summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2016-02-15 17:25:57 -0700
committerJeff Sharkey <jsharkey@android.com>2016-02-15 17:45:42 -0700
commit115d2c189a46f535778d9dd0923f703ff2f888fe (patch)
treef082b998dc2345ccb24b47657c8b2104991225b6 /core/java/android
parentc6ca265902d41a0553d15f660647410db6a3e889 (diff)
Add feature versions for devices and apps.
We're starting to see more instances of device features that will increment separately from the SDK API level, such as camera HAL, GPU capabilities, Bluetooth, and other hardware standards. This change adds the ability for device features to specify a version, which is defined to be backwards compatible. That is, apps requesting an older version of a feature must continue working on devices with a newer version of that same feature. When a version is undefined, we assume the default version "0". Bug: 27162500 Change-Id: If890bf3f3dbb715e8feb80e7059a0d65618482ea
Diffstat (limited to 'core/java/android')
-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
8 files changed, 61 insertions, 16 deletions
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();
}