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
This commit is contained in:
Adam Lesinski
2016-08-01 16:44:29 -07:00
parent 76af60554c
commit ca955a4c3a
2 changed files with 29 additions and 27 deletions

View File

@@ -1230,7 +1230,7 @@ densities: '160'
</p>
<p>
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.
</p>
@@ -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.
</p>
<p class="note">
<strong>Note:</strong> 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:
</p>
<pre>&lt;uses-feature android:name="android.hardware.touchscreen" <strong>android:required="false"</strong> /&gt;</pre>
</dd>
<dt>
@@ -1326,22 +1319,10 @@ densities: '160'
superset of the <code>android.hardware.faketouch</code> feature.
</p>
<p>
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.
</p>
<p>
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.
</p>
<p>

View File

@@ -529,6 +529,16 @@ struct FeatureGroup {
int openGLESVersion;
};
static bool hasFeature(const char* name, const FeatureGroup& grp,
const KeyedVector<String8, ImpliedFeature>& 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<String8, ImpliedFeature>* 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) {