From ca955a4c3ab3d4b83c6e9d5278bcd8d2258d44ad Mon Sep 17 00:00:00 2001
From: Adam Lesinski
Date: Mon, 1 Aug 2016 16:44:29 -0700
Subject: [PATCH] AAPT: faketouch feature implied if no touchscreen feature
requested.
This changes the default implied feature of 'android.hardware.touchscreen'
to 'android.hardware.faketouch' if no 'android.hardware.touchscreen'
feature is requested, required or otherwise.
Bug:30571641
Change-Id: I1e41242d4b1dc549cf69741d2a309baf476d084e
---
.../guide/topics/manifest/uses-feature-element.jd | 29 ++++------------------
tools/aapt/Command.cpp | 27 +++++++++++++++++---
2 files changed, 29 insertions(+), 27 deletions(-)
diff --git a/docs/html/guide/topics/manifest/uses-feature-element.jd b/docs/html/guide/topics/manifest/uses-feature-element.jd
index 10841d675834..9b32244b736f 100755
--- a/docs/html/guide/topics/manifest/uses-feature-element.jd
+++ b/docs/html/guide/topics/manifest/uses-feature-element.jd
@@ -1230,7 +1230,7 @@ densities: '160'
- When declared as required, this feature indicates that the app is
+ By default, your app requires this feature. This feature indicates that the app is
compatible with a device only if that device emulates a touchscreen
("fake touch" interface) or has an actual touchscreen.
@@ -1240,19 +1240,12 @@ densities: '160'
that emulates a subset of a touchscreen's capabilities. For example, a
mouse or remote control could drive an on-screen cursor. If your app
requires basic point and click interaction (in other words, it won't work
- with only a d-pad controller), you should declare this feature. Because
+ with only a d-pad controller), you should declare this feature or simply
+ avoid declaring any {@code android.hardware.touchscreen.*} features. Because
this is the minimum level of touch interaction, you can also use an app
that declares this feature on devices that offer more complex touch
interfaces.
-
-
- Note: Apps require the {@code android.hardware.touchscreen}
- feature by default. If you want your app to be available to devices that
- provide a fake touch interface, you must also explicitly declare that a
- touchscreen is not required as follows:
-
- <uses-feature android:name="android.hardware.touchscreen" android:required="false" />
@@ -1327,21 +1320,9 @@ densities: '160'
- By default, your app requires this feature. As such, your app is not
- available to devices that provide only an emulated touch interface ("fake
- touch") by default. If you want to make your app available on devices
- that provide a fake touch interface (or even on devices that provide only
- a d-pad controller), you must explicitly declare that a touchscreen is
- not required by declaring {@code android.hardware.touchscreen} with
- {@code android:required="false"}. You should add this declaration if your
- app usesâbut does not requireâa real touchscreen interface.
-
-
-
If your app in fact requires a touch interface (to perform more advanced
- touch gestures such as fling), then you don't need to declare any touch
- interface features because they're required by default. However, it's
- best if you explicitly declare all features that your app uses.
+ touch gestures such as fling), then you must explicitly declare this feature
+ or any advanced touchscreen features.
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 9976d00fa872..59da467a1cc3 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -529,6 +529,16 @@ struct FeatureGroup {
int openGLESVersion;
};
+static bool hasFeature(const char* name, const FeatureGroup& grp,
+ const KeyedVector& implied) {
+ String8 name8(name);
+ ssize_t idx = grp.features.indexOfKey(name8);
+ if (idx < 0) {
+ idx = implied.indexOfKey(name8);
+ }
+ return idx >= 0;
+}
+
static void addImpliedFeature(KeyedVector* impliedFeatures,
const char* name, const char* reason, bool sdk23) {
String8 name8(name);
@@ -616,9 +626,16 @@ static void addParentFeatures(FeatureGroup* grp, const String8& name) {
} else if (name == "android.hardware.location.gps" ||
name == "android.hardware.location.network") {
grp->features.add(String8("android.hardware.location"), Feature(true));
+ } else if (name == "android.hardware.faketouch.multitouch") {
+ grp->features.add(String8("android.hardware.faketouch"), Feature(true));
+ } else if (name == "android.hardware.faketouch.multitouch.distinct" ||
+ name == "android.hardware.faketouch.multitouch.jazzhands") {
+ grp->features.add(String8("android.hardware.faketouch.multitouch"), Feature(true));
+ grp->features.add(String8("android.hardware.faketouch"), Feature(true));
} else if (name == "android.hardware.touchscreen.multitouch") {
grp->features.add(String8("android.hardware.touchscreen"), Feature(true));
- } else if (name == "android.hardware.touchscreen.multitouch.distinct") {
+ } else if (name == "android.hardware.touchscreen.multitouch.distinct" ||
+ name == "android.hardware.touchscreen.multitouch.jazzhands") {
grp->features.add(String8("android.hardware.touchscreen.multitouch"), Feature(true));
grp->features.add(String8("android.hardware.touchscreen"), Feature(true));
} else if (name == "android.hardware.opengles.aep") {
@@ -2005,8 +2022,12 @@ int doDump(Bundle* bundle)
}
}
- addImpliedFeature(&impliedFeatures, "android.hardware.touchscreen",
- "default feature for all apps", false);
+ // If the app hasn't declared the touchscreen as a feature requirement (either
+ // directly or implied, required or not), then the faketouch feature is implied.
+ if (!hasFeature("android.hardware.touchscreen", commonFeatures, impliedFeatures)) {
+ addImpliedFeature(&impliedFeatures, "android.hardware.faketouch",
+ "default feature for all apps", false);
+ }
const size_t numFeatureGroups = featureGroups.size();
if (numFeatureGroups == 0) {
--
2.11.0