Bescottee苦しいときは伸びてるとき、楽なときは伸びていないとき

2 au isai FL は XXX High DPI 端末!4.4ソースコード調査


Isai FL

「au 発表会 2014 Summer」で発表された isai FL という端末が発表されました。この端末は以下の資料のように640(XXX High DPI)のDensityを持つもので、国内では初めてのXXX High DPI の端末です。

その発売を記念して、該当するAndroid 4.4 のソースコードを調査してみたいと思います。
Android 公式ドキュメントでは、Metrics and Gridsで紹介されています。

4.4ソースコード調査

XXX High DPI が定義、利用されているソースコードは以下のもののようです。

http://tools.oesf.biz/android-4.4.2_r1.0/xref/frameworks/base/core/java/android/util/DisplayMetrics.java

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
public class DisplayMetrics {
    /**
     * Standard quantized DPI for low-density screens.
     */
    public static final int DENSITY_LOW = 120;
 
    /**
     * Standard quantized DPI for medium-density screens.
     */
    public static final int DENSITY_MEDIUM = 160;
 
    /**
     * This is a secondary density, added for some common screen configurations.
     * It is recommended that applications not generally target this as a first
     * class density -- that is, don't supply specific graphics for this
     * density, instead allow the platform to scale from other densities
     * (typically {@link #DENSITY_HIGH}) as
     * appropriate.  In most cases (such as using bitmaps in
     * {@link android.graphics.drawable.Drawable}) the platform
     * can perform this scaling at load time, so the only cost is some slight
     * startup runtime overhead.
     *
     *
 
This density was original introduced to correspond with a
     * 720p TV screen: the density for 1080p televisions is
     * {@link #DENSITY_XHIGH}, and the value here provides the same UI
     * size for a TV running at 720p.  It has also found use in 7" tablets,
     * when these devices have 1280x720 displays.
     */
    public static final int DENSITY_TV = 213;
 
    /**
     * Standard quantized DPI for high-density screens.
     */
    public static final int DENSITY_HIGH = 240;
 
    /**
     * Standard quantized DPI for extra-high-density screens.
     */
    public static final int DENSITY_XHIGH = 320;
 
    /**
     * Intermediate density for screens that sit somewhere between
     * {@link #DENSITY_XHIGH} (320dpi) and {@link #DENSITY_XXHIGH} (480 dpi).
     * This is not a density that applications should target, instead relying
     * on the system to scale their {@link #DENSITY_XXHIGH} assets for them.
     */
    public static final int DENSITY_400 = 400;
 
    /**
     * Standard quantized DPI for extra-extra-high-density screens.  Applications
     * should not generally worry about this density; relying on XHIGH graphics
     * being scaled up to it should be sufficient for almost all cases.
     */
    public static final int DENSITY_XXHIGH = 480;
 
    /**
     * Standard quantized DPI for extra-extra-extra-high-density screens.  Applications
     * should not generally worry about this density; relying on XHIGH graphics
     * being scaled up to it should be sufficient for almost all cases.  A typical
     * use of this density would be 4K television screens -- 3840x2160, which
     * is 2x a traditional HD 1920x1080 screen which runs at DENSITY_XHIGH.
     */
    public static final int DENSITY_XXXHIGH = 640;

http://tools.oesf.biz/android-4.4.2_r1.0/xref/frameworks/base/include/androidfw/ResourceTypes.h

854
855
856
857
858
859
860
861
862
863
864
enum {
    DENSITY_DEFAULT = ACONFIGURATION_DENSITY_DEFAULT,
    DENSITY_LOW = ACONFIGURATION_DENSITY_LOW,
    DENSITY_MEDIUM = ACONFIGURATION_DENSITY_MEDIUM,
    DENSITY_TV = ACONFIGURATION_DENSITY_TV,
    DENSITY_HIGH = ACONFIGURATION_DENSITY_HIGH,
    DENSITY_XHIGH = ACONFIGURATION_DENSITY_XHIGH,
    DENSITY_XXHIGH = ACONFIGURATION_DENSITY_XXHIGH,
    DENSITY_XXXHIGH = ACONFIGURATION_DENSITY_XXXHIGH,
    DENSITY_NONE = ACONFIGURATION_DENSITY_NONE
};

http://tools.oesf.biz/android-4.4.2_r1.0/xref/frameworks/native/include/android/configuration.h

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
struct AConfiguration;
typedef struct AConfiguration AConfiguration;
 
enum {
    ACONFIGURATION_ORIENTATION_ANY  = 0x0000,
    ACONFIGURATION_ORIENTATION_PORT = 0x0001,
    ACONFIGURATION_ORIENTATION_LAND = 0x0002,
    ACONFIGURATION_ORIENTATION_SQUARE = 0x0003,
 
    ACONFIGURATION_TOUCHSCREEN_ANY  = 0x0000,
    ACONFIGURATION_TOUCHSCREEN_NOTOUCH  = 0x0001,
    ACONFIGURATION_TOUCHSCREEN_STYLUS  = 0x0002,
    ACONFIGURATION_TOUCHSCREEN_FINGER  = 0x0003,
 
    ACONFIGURATION_DENSITY_DEFAULT = 0,
    ACONFIGURATION_DENSITY_LOW = 120,
    ACONFIGURATION_DENSITY_MEDIUM = 160,
    ACONFIGURATION_DENSITY_TV = 213,
    ACONFIGURATION_DENSITY_HIGH = 240,
    ACONFIGURATION_DENSITY_XHIGH = 320,
    ACONFIGURATION_DENSITY_XXHIGH = 480,
    ACONFIGURATION_DENSITY_XXXHIGH = 640,

おまけとしてツールやテストコードも調査

aaptツールのコード

http://tools.oesf.biz/android-4.4.2_r1.0/xref/frameworks/base/tools/aapt/AaptAssets.cpp

1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
bool AaptGroupEntry::getDensityName(const char* name,
                                    ResTable_config* out)
{
    if (strcmp(name, kWildcardName) == 0) {
        if (out) out->density = ResTable_config::DENSITY_DEFAULT;
        return true;
    }
 
    if (strcmp(name, "nodpi") == 0) {
        if (out) out->density = ResTable_config::DENSITY_NONE;
        return true;
    }
 
    if (strcmp(name, "ldpi") == 0) {
        if (out) out->density = ResTable_config::DENSITY_LOW;
        return true;
    }
 
    if (strcmp(name, "mdpi") == 0) {
        if (out) out->density = ResTable_config::DENSITY_MEDIUM;
        return true;
    }
 
    if (strcmp(name, "tvdpi") == 0) {
        if (out) out->density = ResTable_config::DENSITY_TV;
        return true;
    }
 
    if (strcmp(name, "hdpi") == 0) {
        if (out) out->density = ResTable_config::DENSITY_HIGH;
        return true;
    }
 
    if (strcmp(name, "xhdpi") == 0) {
        if (out) out->density = ResTable_config::DENSITY_XHIGH;
        return true;
    }
 
    if (strcmp(name, "xxhdpi") == 0) {
        if (out) out->density = ResTable_config::DENSITY_XXHIGH;
        return true;
    }
 
    if (strcmp(name, "xxxhdpi") == 0) {
        if (out) out->density = ResTable_config::DENSITY_XXXHIGH;
        return true;
    }
 
    char* c = (char*)name;
    while (*c >= '0' && *c <= '9') {
        c++;
    }
 
    // check that we have 'dpi' after the last digit.
    if (toupper(c[0]) != 'D' ||
            toupper(c[1]) != 'P' ||
            toupper(c[2]) != 'I' ||
            c[3] != 0) {
        return false;
    }
 
    // temporarily replace the first letter with \0 to
    // use atoi.
    char tmp = c[0];
    c[0] = '\0';
 
    int d = atoi(name);
    c[0] = tmp;
 
    if (d != 0) {
        if (out) out->density = d;
        return true;
    }
 
    return false;
}
holo向けCTS(Compatibility Test Suite)のテストコード

http://tools.oesf.biz/android-4.4.2_r1.0/xref/cts/tests/tests/holo/src/android/holo/cts/DisplayInfoActivity.java

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
public class DisplayInfoActivity extends Activity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.display_info);
 
        WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        Display display = windowManager.getDefaultDisplay();
        DisplayMetrics metrics = new DisplayMetrics();
        display.getMetrics(metrics);
 
        DisplayMetrics dm = getResources().getDisplayMetrics();
        int width = Math.round(dm.widthPixels / dm.density);
        int height = Math.round(dm.heightPixels / dm.density);
 
        TextView text = (TextView) findViewById(R.id.text);
        text.setText(getString(R.string.display_info_text, metrics.densityDpi,
                getScreenDensityBucket(metrics), width, height));
    }
 
    private String getScreenDensityBucket(DisplayMetrics metrics) {
        switch (metrics.densityDpi) {
            case DisplayMetrics.DENSITY_LOW:
                return "ldpi";
 
            case DisplayMetrics.DENSITY_MEDIUM:
                return "mdpi";
 
            case DisplayMetrics.DENSITY_HIGH:
                return "hdpi";
 
            case DisplayMetrics.DENSITY_XHIGH:
                return "xdpi";
 
            case DisplayMetrics.DENSITY_XXHIGH:
                return "xxdpi";
 
            case DisplayMetrics.DENSITY_XXXHIGH:
                return "xxxdpi";
 
            case DisplayMetrics.DENSITY_TV:
                return "tvdpi";
 
            default:
                return "" + metrics.densityDpi;
        }
    }
}

au Isai FL向けのアプリアイコン


アプリアイコンは、通常の4倍の大きさの192×192 px の必要だそうです。ただ、以下のようにGoogle Play向けに512×512 px のアイコンを作っておいて、そこから各DPIごとのアイコンを生成していると思いますので問題ないかとは思います。アプリの機能を変更しないのに、versionCodeをあげて、google play に apkをアップしなおさないといけないのは少し手間ですね。Google Playにアップした512×512 px アイコンから自動的に各DPIごとのアイコンを生成して、配布するapkにいれてくれればいいのになぁと思ってしまいました。

コメントをどうぞ