summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt4
-rw-r--r--api/system-current.txt4
-rw-r--r--api/test-current.txt4
-rw-r--r--cmds/svc/src/com/android/commands/svc/NfcCommand.java2
-rw-r--r--core/java/android/app/ApplicationPackageManager.java7
-rw-r--r--core/java/android/content/pm/FeatureInfo.java40
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl2
-rw-r--r--core/java/android/content/pm/PackageManager.java20
-rw-r--r--core/java/android/content/pm/PackageParser.java2
-rw-r--r--core/java/android/nfc/NfcAdapter.java2
-rw-r--r--core/java/android/nfc/cardemulation/CardEmulation.java2
-rw-r--r--core/java/android/nfc/cardemulation/NfcFCardEmulation.java2
-rw-r--r--core/res/res/values/attrs_manifest.xml18
-rw-r--r--core/res/res/values/public.xml1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java2
-rw-r--r--services/core/java/com/android/server/SystemConfig.java27
-rw-r--r--services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java4
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java30
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerShellCommand.java12
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java2
-rw-r--r--test-runner/src/android/test/mock/MockPackageManager.java5
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java5
22 files changed, 146 insertions, 51 deletions
diff --git a/api/current.txt b/api/current.txt
index 3c0c64df89ba..0337e11a3c79 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1376,6 +1376,7 @@ package android {
field public static final int valueType = 16843488; // 0x10102e0
field public static final int variablePadding = 16843157; // 0x1010195
field public static final int vendor = 16843751; // 0x10103e7
+ field public static final int version = 16844058; // 0x101051a
field public static final int versionCode = 16843291; // 0x101021b
field public static final int versionName = 16843292; // 0x101021c
field public static final int verticalCorrection = 16843322; // 0x101023a
@@ -9400,6 +9401,7 @@ package android.content.pm {
field public int flags;
field public java.lang.String name;
field public int reqGlEsVersion;
+ field public int version;
}
public class InstrumentationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
@@ -9678,6 +9680,7 @@ package android.content.pm {
method public abstract java.lang.CharSequence getUserBadgedLabel(java.lang.CharSequence, android.os.UserHandle);
method public abstract android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo);
method public abstract boolean hasSystemFeature(java.lang.String);
+ method public abstract boolean hasSystemFeature(java.lang.String, int);
method public abstract boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
method public abstract boolean isSafeMode();
method public abstract java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
@@ -37789,6 +37792,7 @@ package android.test.mock {
method public java.lang.CharSequence getUserBadgedLabel(java.lang.CharSequence, android.os.UserHandle);
method public android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo);
method public boolean hasSystemFeature(java.lang.String);
+ method public boolean hasSystemFeature(java.lang.String, int);
method public boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
method public boolean isSafeMode();
method public java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
diff --git a/api/system-current.txt b/api/system-current.txt
index 335557b4baf9..266900f917e9 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1475,6 +1475,7 @@ package android {
field public static final int valueType = 16843488; // 0x10102e0
field public static final int variablePadding = 16843157; // 0x1010195
field public static final int vendor = 16843751; // 0x10103e7
+ field public static final int version = 16844058; // 0x101051a
field public static final int versionCode = 16843291; // 0x101021b
field public static final int versionName = 16843292; // 0x101021c
field public static final int verticalCorrection = 16843322; // 0x101023a
@@ -9745,6 +9746,7 @@ package android.content.pm {
field public int flags;
field public java.lang.String name;
field public int reqGlEsVersion;
+ field public int version;
}
public class InstrumentationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
@@ -10027,6 +10029,7 @@ package android.content.pm {
method public abstract android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo);
method public abstract void grantRuntimePermission(java.lang.String, java.lang.String, android.os.UserHandle);
method public abstract boolean hasSystemFeature(java.lang.String);
+ method public abstract boolean hasSystemFeature(java.lang.String, int);
method public abstract boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
method public abstract boolean isSafeMode();
method public abstract java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
@@ -40538,6 +40541,7 @@ package android.test.mock {
method public android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo);
method public void grantRuntimePermission(java.lang.String, java.lang.String, android.os.UserHandle);
method public boolean hasSystemFeature(java.lang.String);
+ method public boolean hasSystemFeature(java.lang.String, int);
method public boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
method public boolean isSafeMode();
method public java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
diff --git a/api/test-current.txt b/api/test-current.txt
index 6bd4887582ed..15b1e7884cf5 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1376,6 +1376,7 @@ package android {
field public static final int valueType = 16843488; // 0x10102e0
field public static final int variablePadding = 16843157; // 0x1010195
field public static final int vendor = 16843751; // 0x10103e7
+ field public static final int version = 16844058; // 0x101051a
field public static final int versionCode = 16843291; // 0x101021b
field public static final int versionName = 16843292; // 0x101021c
field public static final int verticalCorrection = 16843322; // 0x101023a
@@ -9407,6 +9408,7 @@ package android.content.pm {
field public int flags;
field public java.lang.String name;
field public int reqGlEsVersion;
+ field public int version;
}
public class InstrumentationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
@@ -9686,6 +9688,7 @@ package android.content.pm {
method public abstract java.lang.CharSequence getUserBadgedLabel(java.lang.CharSequence, android.os.UserHandle);
method public abstract android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo);
method public abstract boolean hasSystemFeature(java.lang.String);
+ method public abstract boolean hasSystemFeature(java.lang.String, int);
method public abstract boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
method public abstract boolean isSafeMode();
method public abstract java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
@@ -37806,6 +37809,7 @@ package android.test.mock {
method public java.lang.CharSequence getUserBadgedLabel(java.lang.CharSequence, android.os.UserHandle);
method public android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo);
method public boolean hasSystemFeature(java.lang.String);
+ method public boolean hasSystemFeature(java.lang.String, int);
method public boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
method public boolean isSafeMode();
method public java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
diff --git a/cmds/svc/src/com/android/commands/svc/NfcCommand.java b/cmds/svc/src/com/android/commands/svc/NfcCommand.java
index e0f09ee2c666..8e9791f8b731 100644
--- a/cmds/svc/src/com/android/commands/svc/NfcCommand.java
+++ b/cmds/svc/src/com/android/commands/svc/NfcCommand.java
@@ -58,7 +58,7 @@ public class NfcCommand extends Svc.Command {
IPackageManager pm = IPackageManager.Stub.asInterface(
ServiceManager.getService("package"));
try {
- if (pm.hasSystemFeature(PackageManager.FEATURE_NFC)) {
+ if (pm.hasSystemFeature(PackageManager.FEATURE_NFC, 0)) {
INfcAdapter nfc = INfcAdapter.Stub
.asInterface(ServiceManager.getService(Context.NFC_SERVICE));
try {
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index df4b7d1eb50d..7e50518cb3e1 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -450,8 +450,13 @@ public class ApplicationPackageManager extends PackageManager {
@Override
public boolean hasSystemFeature(String name) {
+ return hasSystemFeature(name, 0);
+ }
+
+ @Override
+ public boolean hasSystemFeature(String name, int version) {
try {
- return mPM.hasSystemFeature(name);
+ return mPM.hasSystemFeature(name, version);
} catch (RemoteException e) {
throw new RuntimeException("Package manager has died", e);
}
diff --git a/core/java/android/content/pm/FeatureInfo.java b/core/java/android/content/pm/FeatureInfo.java
index 79fa32791a31..7671f72cbeac 100644
--- a/core/java/android/content/pm/FeatureInfo.java
+++ b/core/java/android/content/pm/FeatureInfo.java
@@ -20,9 +20,18 @@ import android.os.Parcel;
import android.os.Parcelable;
/**
- * A single feature that can be requested by an application. This corresponds
- * to information collected from the
- * AndroidManifest.xml's {@code <uses-feature>} tag.
+ * Definition of a single optional hardware or software feature of an Android
+ * device.
+ * <p>
+ * This object is used to represent both features supported by a device and
+ * features requested by an app. Apps can request that certain features be
+ * available as a prerequisite to being installed through the
+ * {@code uses-feature} tag in their manifests.
+ * <p>
+ * Starting in {@link android.os.Build.VERSION_CODES#N}, features can have a
+ * version, which must always be backwards compatible. That is, a device
+ * claiming to support version 3 of a specific feature must support apps
+ * requesting version 1 of that feature.
*/
public class FeatureInfo implements Parcelable {
/**
@@ -31,7 +40,17 @@ public class FeatureInfo implements Parcelable {
* in {@link #reqGlEsVersion}.
*/
public String name;
-
+
+ /**
+ * If this object represents a feature supported by a device, this is the
+ * maximum version of this feature supported by the device. The device
+ * implicitly supports all older versions of this feature.
+ * <p>
+ * If this object represents a feature requested by an app, this is the
+ * minimum version of the feature required by the app.
+ */
+ public int version;
+
/**
* Default value for {@link #reqGlEsVersion};
*/
@@ -59,15 +78,17 @@ public class FeatureInfo implements Parcelable {
public FeatureInfo(FeatureInfo orig) {
name = orig.name;
+ version = orig.version;
reqGlEsVersion = orig.reqGlEsVersion;
flags = orig.flags;
}
+ @Override
public String toString() {
if (name != null) {
return "FeatureInfo{"
+ Integer.toHexString(System.identityHashCode(this))
- + " " + name + " fl=0x" + Integer.toHexString(flags) + "}";
+ + " " + name + " v=" + version + " fl=0x" + Integer.toHexString(flags) + "}";
} else {
return "FeatureInfo{"
+ Integer.toHexString(System.identityHashCode(this))
@@ -76,21 +97,25 @@ public class FeatureInfo implements Parcelable {
}
}
+ @Override
public int describeContents() {
return 0;
}
+ @Override
public void writeToParcel(Parcel dest, int parcelableFlags) {
dest.writeString(name);
+ dest.writeInt(version);
dest.writeInt(reqGlEsVersion);
dest.writeInt(flags);
}
- public static final Creator<FeatureInfo> CREATOR =
- new Creator<FeatureInfo>() {
+ public static final Creator<FeatureInfo> CREATOR = new Creator<FeatureInfo>() {
+ @Override
public FeatureInfo createFromParcel(Parcel source) {
return new FeatureInfo(source);
}
+ @Override
public FeatureInfo[] newArray(int size) {
return new FeatureInfo[size];
}
@@ -98,6 +123,7 @@ public class FeatureInfo implements Parcelable {
private FeatureInfo(Parcel source) {
name = source.readString();
+ version = source.readInt();
reqGlEsVersion = source.readInt();
flags = source.readInt();
}
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 386385790e49..c71a60353e1a 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -416,7 +416,7 @@ interface IPackageManager {
*/
FeatureInfo[] getSystemAvailableFeatures();
- boolean hasSystemFeature(String name);
+ boolean hasSystemFeature(String name, int version);
void enterSafeMode();
boolean isSafeMode();
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index bf0d4ded17a9..36b902c3e481 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3405,15 +3405,27 @@ public abstract class PackageManager {
public abstract FeatureInfo[] getSystemAvailableFeatures();
/**
- * Check whether the given feature name is one of the available
- * features as returned by {@link #getSystemAvailableFeatures()}.
+ * Check whether the given feature name is one of the available features as
+ * returned by {@link #getSystemAvailableFeatures()}. This tests for the
+ * presence of <em>any</em> version of the given feature name; use
+ * {@link #hasSystemFeature(String, int)} to check for a minimum version.
*
- * @return Returns true if the devices supports the feature, else
- * false.
+ * @return Returns true if the devices supports the feature, else false.
*/
public abstract boolean hasSystemFeature(String name);
/**
+ * Check whether the given feature name and version is one of the available
+ * features as returned by {@link #getSystemAvailableFeatures()}. Since
+ * features are defined to always be backwards compatible, this returns true
+ * if the available feature version is greater than or equal to the
+ * requested version.
+ *
+ * @return Returns true if the devices supports the feature, else false.
+ */
+ public abstract boolean hasSystemFeature(String name, int version);
+
+ /**
* Determine the best action to perform for a given Intent. This is how
* {@link Intent#resolveActivity} finds an activity if a class has not
* been explicitly specified.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 5ae8d4cf0ce4..1ee19de282ac 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -2127,6 +2127,8 @@ public class PackageParser {
// that may change.
fi.name = sa.getNonResourceString(
com.android.internal.R.styleable.AndroidManifestUsesFeature_name);
+ fi.version = sa.getInt(
+ com.android.internal.R.styleable.AndroidManifestUsesFeature_version, 0);
if (fi.name == null) {
fi.reqGlEsVersion = sa.getInt(
com.android.internal.R.styleable.AndroidManifestUsesFeature_glEsVersion,
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index acd780d9ecad..6f911ceb4bed 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -414,7 +414,7 @@ public final class NfcAdapter {
return false;
}
try {
- return pm.hasSystemFeature(PackageManager.FEATURE_NFC);
+ return pm.hasSystemFeature(PackageManager.FEATURE_NFC, 0);
} catch (RemoteException e) {
Log.e(TAG, "Package manager query failed, assuming no NFC feature", e);
return false;
diff --git a/core/java/android/nfc/cardemulation/CardEmulation.java b/core/java/android/nfc/cardemulation/CardEmulation.java
index 23d05bda3633..b49288e6e59e 100644
--- a/core/java/android/nfc/cardemulation/CardEmulation.java
+++ b/core/java/android/nfc/cardemulation/CardEmulation.java
@@ -156,7 +156,7 @@ public final class CardEmulation {
throw new UnsupportedOperationException();
}
try {
- if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)) {
+ if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION, 0)) {
Log.e(TAG, "This device does not support card emulation");
throw new UnsupportedOperationException();
}
diff --git a/core/java/android/nfc/cardemulation/NfcFCardEmulation.java b/core/java/android/nfc/cardemulation/NfcFCardEmulation.java
index d61ac02eb98e..42ccf20a584a 100644
--- a/core/java/android/nfc/cardemulation/NfcFCardEmulation.java
+++ b/core/java/android/nfc/cardemulation/NfcFCardEmulation.java
@@ -77,7 +77,7 @@ public final class NfcFCardEmulation {
throw new UnsupportedOperationException();
}
try {
- if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF)) {
+ if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF, 0)) {
Log.e(TAG, "This device does not support NFC-F card emulation");
throw new UnsupportedOperationException();
}
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 1496d0926dc6..f91bcd0bdeea 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1425,22 +1425,24 @@
<attr name="reqFiveWayNav" />
</declare-styleable>
- <!-- The <code>uses-feature</code> tag specifies
- a specific feature used by the application.
- For example an application might specify that it requires
- specific version of OpenGL. Multiple such attribute
- values can be specified by the application.
+ <!-- The <code>uses-feature</code> tag specifies a specific device
+ hardware or software feature used by the application. For
+ example an application might specify that it requires
+ a camera. Multiple attribute values can be specified by the
+ application.
<p>This appears as a child tag of the root
{@link #AndroidManifest manifest} tag. -->
<declare-styleable name="AndroidManifestUsesFeature" parent="AndroidManifest">
+ <!-- The name of the feature that is being used. -->
+ <attr name="name" />
+ <!-- The version of the feature that is being used. -->
+ <attr name="version" format="integer" />
<!-- The GLES driver version number needed by an application.
The higher 16 bits represent the major number and the lower 16 bits
represent the minor number. For example for GL 1.2 referring to
0x00000102, the actual value should be set as 0x00010002. -->
- <attr name="glEsVersion" format="integer"/>
- <!-- The name of the feature that is being used. -->
- <attr name="name" />
+ <attr name="glEsVersion" format="integer" />
<!-- Specify whether this feature is required for the application.
The default is true, meaning the application requires the
feature, and does not want to be installed on devices that
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 69d005cb6806..894fd3721112 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2700,6 +2700,7 @@
<public type="attr" name="bitmap" />
<public type="attr" name="hotSpotX" />
<public type="attr" name="hotSpotY" />
+ <public type="attr" name="version" />
<public type="style" name="Theme.Material.Light.DialogWhenLarge.DarkActionBar" />
<public type="style" name="Widget.Material.SeekBar.Discrete" />
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 278dfe6c9314..17e43c406288 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -267,7 +267,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
onlyCoreApps = packageManager.isOnlyCoreApps();
freeformWindowManagement = packageManager.hasSystemFeature(
- PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT);
+ PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT, 0);
} catch (RemoteException e) {
onlyCoreApps = false;
freeformWindowManagement = false;
diff --git a/services/core/java/com/android/server/SystemConfig.java b/services/core/java/com/android/server/SystemConfig.java
index 5aba22d5c4c7..19d7e2e1e8d0 100644
--- a/services/core/java/com/android/server/SystemConfig.java
+++ b/services/core/java/com/android/server/SystemConfig.java
@@ -342,6 +342,7 @@ public class SystemConfig {
} else if ("feature".equals(name) && allowFeatures) {
String fname = parser.getAttributeValue(null, "name");
+ int fversion = XmlUtils.readIntAttribute(null, "version", 0);
boolean allowed;
if (!lowRam) {
allowed = true;
@@ -353,7 +354,7 @@ public class SystemConfig {
Slog.w(TAG, "<feature> without name in " + permFile + " at "
+ parser.getPositionDescription());
} else if (allowed) {
- addFeature(fname);
+ addFeature(fname, fversion);
}
XmlUtils.skipCurrentTag(parser);
continue;
@@ -445,8 +446,8 @@ public class SystemConfig {
// Some devices can be field-converted to FBE, so offer to splice in
// those features if not already defined by the static config
if (StorageManager.isNativeFileBasedEncryptionEnabled()) {
- addFeature(PackageManager.FEATURE_FILE_BASED_ENCRYPTION);
- addFeature(PackageManager.FEATURE_SECURELY_REMOVES_USERS);
+ addFeature(PackageManager.FEATURE_FILE_BASED_ENCRYPTION, 0);
+ addFeature(PackageManager.FEATURE_SECURELY_REMOVES_USERS, 0);
}
for (String featureName : mUnavailableFeatures) {
@@ -454,17 +455,21 @@ public class SystemConfig {
}
}
- private void addFeature(String featureName) {
- if (!mAvailableFeatures.containsKey(featureName)) {
- final FeatureInfo fi = new FeatureInfo();
- fi.name = featureName;
- mAvailableFeatures.put(featureName, fi);
+ private void addFeature(String name, int version) {
+ FeatureInfo fi = mAvailableFeatures.get(name);
+ if (fi == null) {
+ fi = new FeatureInfo();
+ fi.name = name;
+ fi.version = version;
+ mAvailableFeatures.put(name, fi);
+ } else {
+ fi.version = Math.max(fi.version, version);
}
}
- private void removeFeature(String featureName) {
- if (mAvailableFeatures.remove(featureName) != null) {
- Slog.d(TAG, "Removed unavailable feature " + featureName);
+ private void removeFeature(String name) {
+ if (mAvailableFeatures.remove(name) != null) {
+ Slog.d(TAG, "Removed unavailable feature " + name);
}
}
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index 9b5fde00bce0..63c940890a81 100644
--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -577,7 +577,7 @@ final class DefaultPermissionGrantPolicy {
}
// Android Wear Home
- if (mService.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+ if (mService.hasSystemFeature(PackageManager.FEATURE_WATCH, 0)) {
Intent homeIntent = new Intent(Intent.ACTION_MAIN);
homeIntent.addCategory(Intent.CATEGORY_HOME_MAIN);
@@ -612,7 +612,7 @@ final class DefaultPermissionGrantPolicy {
PackageParser.Package dialerPackage, int userId) {
if (doesPackageSupportRuntimePermissions(dialerPackage)) {
boolean isPhonePermFixed =
- mService.hasSystemFeature(PackageManager.FEATURE_WATCH);
+ mService.hasSystemFeature(PackageManager.FEATURE_WATCH, 0);
grantRuntimePermissionsLPw(
dialerPackage, PHONE_PERMISSIONS, isPhonePermFixed, userId);
grantRuntimePermissionsLPw(dialerPackage, CONTACTS_PERMISSIONS, userId);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index caa58d6ed6bd..cc44f709b729 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3503,9 +3503,14 @@ public class PackageManagerService extends IPackageManager.Stub {
}
@Override
- public boolean hasSystemFeature(String name) {
+ public boolean hasSystemFeature(String name, int version) {
synchronized (mPackages) {
- return mAvailableFeatures.containsKey(name);
+ final FeatureInfo feat = mAvailableFeatures.get(name);
+ if (feat == null) {
+ return false;
+ } else {
+ return feat.version >= version;
+ }
}
}
@@ -16909,15 +16914,22 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
if (!checkin) {
pw.println("Features:");
}
- Iterator<String> it = mAvailableFeatures.keySet().iterator();
- while (it.hasNext()) {
- String name = it.next();
- if (!checkin) {
- pw.print(" ");
- } else {
+
+ for (FeatureInfo feat : mAvailableFeatures.values()) {
+ if (checkin) {
pw.print("feat,");
+ pw.print(feat.name);
+ pw.print(",");
+ pw.println(feat.version);
+ } else {
+ pw.print(" ");
+ pw.print(feat.name);
+ if (feat.version > 0) {
+ pw.print(" version=");
+ pw.print(feat.version);
+ }
+ pw.println();
}
- pw.println(name);
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index d8845d816450..d4048ef60b75 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -339,9 +339,17 @@ class PackageManagerShellCommand extends ShellCommand {
for (int p = 0; p < count; p++) {
FeatureInfo fi = list.get(p);
pw.print("feature:");
- if (fi.name != null) pw.println(fi.name);
- else pw.println("reqGlEsVersion=0x"
+ if (fi.name != null) {
+ pw.print(fi.name);
+ if (fi.version > 0) {
+ pw.print("=");
+ pw.print(fi.version);
+ }
+ pw.println();
+ } else {
+ pw.println("reqGlEsVersion=0x"
+ Integer.toHexString(fi.reqGlEsVersion));
+ }
}
return 0;
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index cda60bd3839a..1cd563559820 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -8136,7 +8136,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
private boolean hasFeatureManagedUsers() {
try {
- return mIPackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS);
+ return mIPackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0);
} catch (RemoteException e) {
return false;
}
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index 4e6d638d4739..552ce6d724fd 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -824,6 +824,11 @@ public class MockPackageManager extends PackageManager {
}
@Override
+ public boolean hasSystemFeature(String name, int version) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public boolean isSafeMode() {
throw new UnsupportedOperationException();
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
index 5c20dfa8e627..8da3cbd411b9 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
@@ -323,6 +323,11 @@ public class BridgePackageManager extends PackageManager {
}
@Override
+ public boolean hasSystemFeature(String name, int version) {
+ return false;
+ }
+
+ @Override
public ResolveInfo resolveActivity(Intent intent, int flags) {
return null;
}