am c5193c62: Merge "Add new landscape and portrait orientation features." into honeycomb-mr2
* commit 'c5193c6285d7094fb86dcb5cd56f44a3788af7c2':
Add new landscape and portrait orientation features.
diff --git a/api/current.xml b/api/current.xml
index a9f3e85..f49098e 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -61821,6 +61821,28 @@
visibility="public"
>
</field>
+<field name="FEATURE_SCREEN_LANDSCAPE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""android.hardware.screen.landscape""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FEATURE_SCREEN_PORTRAIT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""android.hardware.screen.portrait""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="FEATURE_SENSOR_ACCELEROMETER"
type="java.lang.String"
transient="false"
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index bb4a5ce..64dea4c 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -920,6 +920,26 @@
/**
* Feature for {@link #getSystemAvailableFeatures} and
+ * {@link #hasSystemFeature}: The device supports portrait orientation
+ * screens. For backwards compatibility, you can assume that if neither
+ * this nor {@link #FEATURE_SCREEN_LANDSCAPE} is set then the device supports
+ * both portrait and landscape.
+ */
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_SCREEN_PORTRAIT = "android.hardware.screen.portrait";
+
+ /**
+ * Feature for {@link #getSystemAvailableFeatures} and
+ * {@link #hasSystemFeature}: The device supports landscape orientation
+ * screens. For backwards compatibility, you can assume that if neither
+ * this nor {@link #FEATURE_SCREEN_PORTRAIT} is set then the device supports
+ * both portrait and landscape.
+ */
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_SCREEN_LANDSCAPE = "android.hardware.screen.landscape";
+
+ /**
+ * Feature for {@link #getSystemAvailableFeatures} and
* {@link #hasSystemFeature}: The device supports live wallpapers.
*/
@SdkConstant(SdkConstantType.FEATURE)
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 6257e95..93c8715 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -243,6 +243,26 @@
* later. Applications that don't support a screen size at least as
* large as the current screen will provide the user with a UI to
* switch them in to screen size compatibility mode.</p>
+ *
+ * <p>This version introduces new screen size resource qualifiers
+ * based on the screen size in dp: see
+ * {@link android.content.res.Configuration#screenWidthDp},
+ * {@link android.content.res.Configuration#screenHeightDp}, and
+ * {@link android.content.res.Configuration#smallestScreenWidthDp}.
+ * Supplying these in <supports-screens> as per
+ * {@link android.content.pm.ApplicationInfo#requiresSmallestWidthDp},
+ * {@link android.content.pm.ApplicationInfo#compatibleWidthLimitDp}, and
+ * {@link android.content.pm.ApplicationInfo#largestWidthLimitDp} is
+ * preferred over the older screen size buckets and for older devices
+ * the appropriate buckets will be inferred from them.</p>
+ *
+ * <p>New {@link android.content.pm.PackageManager#FEATURE_SCREEN_PORTRAIT}
+ * and {@link android.content.pm.PackageManager#FEATURE_SCREEN_LANDSCAPE}
+ * features are introduced in this release. Applications that target
+ * previous platform versions are assumed to require both portrait and
+ * landscape support in the device; when targeting Honeycomb MR1 or
+ * greater the application is responsible for specifying any specific
+ * orientation it requires.</p>
*/
public static final int HONEYCOMB_MR2 = 13;
}
diff --git a/data/etc/handheld_core_hardware.xml b/data/etc/handheld_core_hardware.xml
index 7f87b79..9d2a0cb 100644
--- a/data/etc/handheld_core_hardware.xml
+++ b/data/etc/handheld_core_hardware.xml
@@ -31,6 +31,8 @@
<feature name="android.hardware.bluetooth" />
<feature name="android.hardware.touchscreen" />
<feature name="android.hardware.microphone" />
+ <feature name="android.hardware.screen.portrait" />
+ <feature name="android.hardware.screen.landscape" />
<!-- devices with GPS must include android.hardware.location.gps.xml -->
<!-- devices with an autofocus camera and/or flash must include either
android.hardware.camera.autofocus.xml or
diff --git a/data/etc/tablet_core_hardware.xml b/data/etc/tablet_core_hardware.xml
index 952d0782..bf29fe4 100644
--- a/data/etc/tablet_core_hardware.xml
+++ b/data/etc/tablet_core_hardware.xml
@@ -32,6 +32,8 @@
<feature name="android.hardware.touchscreen.multitouch" />
<feature name="android.hardware.touchscreen.multitouch.distinct" />
<feature name="android.hardware.microphone" />
+ <feature name="android.hardware.screen.portrait" />
+ <feature name="android.hardware.screen.landscape" />
<!-- devices with GPS must include android.hardware.location.gps.xml -->
<!-- devices with a rear-facing camera must include one of these as appropriate:
android.hardware.camera.xml or
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 8ac7590..223b1fa 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -343,6 +343,9 @@
REQUIRED_ATTR = 0x0101028e,
SCREEN_SIZE_ATTR = 0x010102ca,
SCREEN_DENSITY_ATTR = 0x010102cb,
+ REQUIRES_SMALLEST_WIDTH_DP_ATTR = 0x01010364,
+ COMPATIBLE_WIDTH_LIMIT_DP_ATTR = 0x01010365,
+ LARGEST_WIDTH_LIMIT_DP_ATTR = 0x01010366,
};
const char *getComponentName(String8 &pkgName, String8 &componentName) {
@@ -423,6 +426,24 @@
return 1;
}
+ // Make a dummy config for retrieving resources... we need to supply
+ // non-default values for some configs so that we can retrieve resources
+ // in the app that don't have a default. The most important of these is
+ // the API version because key resources like icons will have an implicit
+ // version if they are using newer config types like density.
+ ResTable_config config;
+ config.language[0] = 'e';
+ config.language[1] = 'n';
+ config.country[0] = 'U';
+ config.country[1] = 'S';
+ config.orientation = ResTable_config::ORIENTATION_PORT;
+ config.density = ResTable_config::DENSITY_MEDIUM;
+ config.sdkVersion = 10000; // Very high.
+ config.screenWidthDp = 320;
+ config.screenHeightDp = 480;
+ config.smallestScreenWidthDp = 320;
+ assets.setConfiguration(config);
+
const ResTable& res = assets.getResources(false);
if (&res == NULL) {
fprintf(stderr, "ERROR: dump failed because no resource table was found\n");
@@ -542,6 +563,19 @@
}
}
} else if (strcmp("badging", option) == 0) {
+ Vector<String8> locales;
+ res.getLocales(&locales);
+
+ Vector<ResTable_config> configs;
+ res.getConfigurations(&configs);
+ SortedVector<int> densities;
+ const size_t NC = configs.size();
+ for (size_t i=0; i<NC; i++) {
+ int dens = configs[i].density;
+ if (dens == 0) dens = 160;
+ densities.add(dens);
+ }
+
size_t len;
ResXMLTree::event_code_t code;
int depth = 0;
@@ -598,6 +632,8 @@
bool specTouchscreenFeature = false; // touchscreen-related
bool specMultitouchFeature = false;
bool reqDistinctMultitouchFeature = false;
+ bool specScreenPortraitFeature = false;
+ bool specScreenLandscapeFeature = false;
// 2.2 also added some other features that apps can request, but that
// have no corresponding permission, so we cannot implement any
// back-compatibility heuristic for them. The below are thus unnecessary
@@ -614,6 +650,9 @@
int largeScreen = 1;
int xlargeScreen = 1;
int anyDensity = 1;
+ int requiresSmallestWidthDp = 0;
+ int compatibleWidthLimitDp = 0;
+ int largestWidthLimitDp = 0;
String8 pkg;
String8 activityName;
String8 activityLabel;
@@ -628,10 +667,11 @@
} else if (depth < 3) {
if (withinActivity && isMainActivity && isLauncherActivity) {
const char *aName = getComponentName(pkg, activityName);
+ printf("launchable-activity:");
if (aName != NULL) {
- printf("launchable activity name='%s'", aName);
+ printf(" name='%s' ", aName);
}
- printf("label='%s' icon='%s'\n",
+ printf(" label='%s' icon='%s'\n",
activityLabel.string(),
activityIcon.string());
}
@@ -696,23 +736,51 @@
withinApplication = false;
if (tag == "application") {
withinApplication = true;
- String8 label = getResolvedAttribute(&res, tree, LABEL_ATTR, &error);
- if (error != "") {
- fprintf(stderr, "ERROR getting 'android:label' attribute: %s\n", error.string());
- goto bail;
+
+ String8 label;
+ const size_t NL = locales.size();
+ for (size_t i=0; i<NL; i++) {
+ const char* localeStr = locales[i].string();
+ assets.setLocale(localeStr != NULL ? localeStr : "");
+ String8 llabel = getResolvedAttribute(&res, tree, LABEL_ATTR, &error);
+ if (llabel != "") {
+ if (localeStr == NULL || strlen(localeStr) == 0) {
+ label = llabel;
+ printf("application-label:'%s'\n", llabel.string());
+ } else {
+ if (label == "") {
+ label = llabel;
+ }
+ printf("application-label-%s:'%s'\n", localeStr,
+ llabel.string());
+ }
+ }
}
- printf("application: label='%s' ", label.string());
+
+ ResTable_config tmpConfig = config;
+ const size_t ND = densities.size();
+ for (size_t i=0; i<ND; i++) {
+ tmpConfig.density = densities[i];
+ assets.setConfiguration(tmpConfig);
+ String8 icon = getResolvedAttribute(&res, tree, ICON_ATTR, &error);
+ if (icon != "") {
+ printf("application-icon-%d:'%s'\n", densities[i], icon.string());
+ }
+ }
+ assets.setConfiguration(config);
+
String8 icon = getResolvedAttribute(&res, tree, ICON_ATTR, &error);
if (error != "") {
fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", error.string());
goto bail;
}
- printf("icon='%s'\n", icon.string());
int32_t testOnly = getIntegerAttribute(tree, TEST_ONLY_ATTR, &error, 0);
if (error != "") {
fprintf(stderr, "ERROR getting 'android:testOnly' attribute: %s\n", error.string());
goto bail;
}
+ printf("application: label='%s' ", label.string());
+ printf("icon='%s'\n", icon.string());
if (testOnly != 0) {
printf("testOnly='%d'\n", testOnly);
}
@@ -792,6 +860,12 @@
XLARGE_SCREEN_ATTR, NULL, 1);
anyDensity = getIntegerAttribute(tree,
ANY_DENSITY_ATTR, NULL, 1);
+ requiresSmallestWidthDp = getIntegerAttribute(tree,
+ REQUIRES_SMALLEST_WIDTH_DP_ATTR, NULL, 0);
+ compatibleWidthLimitDp = getIntegerAttribute(tree,
+ COMPATIBLE_WIDTH_LIMIT_DP_ATTR, NULL, 0);
+ largestWidthLimitDp = getIntegerAttribute(tree,
+ LARGEST_WIDTH_LIMIT_DP_ATTR, NULL, 0);
} else if (tag == "uses-feature") {
String8 name = getAttribute(tree, NAME_ATTR, &error);
@@ -837,6 +911,10 @@
// these have no corresponding permission to check for,
// but should imply the foundational telephony permission
reqTelephonySubFeature = true;
+ } else if (name == "android.hardware.screen.portrait") {
+ specScreenPortraitFeature = true;
+ } else if (name == "android.hardware.screen.landscape") {
+ specScreenLandscapeFeature = true;
}
printf("uses-feature%s:'%s'\n",
req ? "" : "-not-required", name.string());
@@ -1103,6 +1181,15 @@
printf("uses-feature:'android.hardware.touchscreen.multitouch'\n");
}
+ // Landscape/portrait-related compatibility logic
+ if (!specScreenLandscapeFeature && !specScreenPortraitFeature && (targetSdk < 13)) {
+ // If app has not specified whether it requires portrait or landscape
+ // and is targeting an API before Honeycomb MR2, then assume it requires
+ // both.
+ printf("uses-feature:'android.hardware.screen.portrait'\n");
+ printf("uses-feature:'android.hardware.screen.landscape'\n");
+ }
+
if (hasMainActivity) {
printf("main\n");
}
@@ -1128,6 +1215,34 @@
printf("other-services\n");
}
+ // For modern apps, if screen size buckets haven't been specified
+ // but the new width ranges have, then infer the buckets from them.
+ if (smallScreen > 0 && normalScreen > 0 && largeScreen > 0 && xlargeScreen > 0
+ && requiresSmallestWidthDp > 0) {
+ int compatWidth = compatibleWidthLimitDp;
+ if (compatWidth <= 0) compatWidth = requiresSmallestWidthDp;
+ if (requiresSmallestWidthDp <= 240 && compatWidth >= 240) {
+ smallScreen = -1;
+ } else {
+ smallScreen = 0;
+ }
+ if (requiresSmallestWidthDp <= 320 && compatWidth >= 320) {
+ normalScreen = -1;
+ } else {
+ normalScreen = 0;
+ }
+ if (requiresSmallestWidthDp <= 480 && compatWidth >= 480) {
+ largeScreen = -1;
+ } else {
+ largeScreen = 0;
+ }
+ if (requiresSmallestWidthDp <= 720 && compatWidth >= 720) {
+ xlargeScreen = -1;
+ } else {
+ xlargeScreen = 0;
+ }
+ }
+
// Determine default values for any unspecified screen sizes,
// based on the target SDK of the package. As of 4 (donut)
// the screen size support was introduced, so all default to
@@ -1146,7 +1261,8 @@
xlargeScreen = targetSdk >= 9 ? -1 : 0;
}
if (anyDensity > 0) {
- anyDensity = targetSdk >= 4 ? -1 : 0;
+ anyDensity = (targetSdk >= 4 || requiresSmallestWidthDp > 0
+ || compatibleWidthLimitDp > 0) ? -1 : 0;
}
printf("supports-screens:");
if (smallScreen != 0) printf(" 'small'");
@@ -1154,12 +1270,18 @@
if (largeScreen != 0) printf(" 'large'");
if (xlargeScreen != 0) printf(" 'xlarge'");
printf("\n");
-
printf("supports-any-density: '%s'\n", anyDensity ? "true" : "false");
+ if (requiresSmallestWidthDp > 0) {
+ printf("requires-smallest-width:'%d'\n", requiresSmallestWidthDp);
+ }
+ if (compatibleWidthLimitDp > 0) {
+ printf("compatible-width-limit:'%d'\n", compatibleWidthLimitDp);
+ }
+ if (largestWidthLimitDp > 0) {
+ printf("largest-width-limit:'%d'\n", largestWidthLimitDp);
+ }
printf("locales:");
- Vector<String8> locales;
- res.getLocales(&locales);
const size_t NL = locales.size();
for (size_t i=0; i<NL; i++) {
const char* localeStr = locales[i].string();
@@ -1170,16 +1292,6 @@
}
printf("\n");
- Vector<ResTable_config> configs;
- res.getConfigurations(&configs);
- SortedVector<int> densities;
- const size_t NC = configs.size();
- for (size_t i=0; i<NC; i++) {
- int dens = configs[i].density;
- if (dens == 0) dens = 160;
- densities.add(dens);
- }
-
printf("densities:");
const size_t ND = densities.size();
for (size_t i=0; i<ND; i++) {