Merge "More flexible API enforcement policy."
This commit is contained in:
@@ -1046,6 +1046,58 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
|
||||
/** @hide */
|
||||
public String[] splitClassLoaderNames;
|
||||
|
||||
/**
|
||||
* Represents the default policy. The actual policy used will depend on other properties of
|
||||
* the application, e.g. the target SDK version.
|
||||
* @hide
|
||||
*/
|
||||
public static final int HIDDEN_API_ENFORCEMENT_DEFAULT = -1;
|
||||
/**
|
||||
* No API enforcement; the app can access the entire internal private API. Only for use by
|
||||
* system apps.
|
||||
* @hide
|
||||
*/
|
||||
public static final int HIDDEN_API_ENFORCEMENT_NONE = 0;
|
||||
/**
|
||||
* Light grey list enforcement, the strictest option. Enforces the light grey, dark grey and
|
||||
* black lists.
|
||||
* @hide
|
||||
* */
|
||||
public static final int HIDDEN_API_ENFORCEMENT_ALL_LISTS = 1;
|
||||
/**
|
||||
* Dark grey list enforcement. Enforces the dark grey and black lists
|
||||
* @hide
|
||||
*/
|
||||
public static final int HIDDEN_API_ENFORCEMENT_DARK_GREY_AND_BLACK = 2;
|
||||
/**
|
||||
* Blacklist enforcement only.
|
||||
* @hide
|
||||
*/
|
||||
public static final int HIDDEN_API_ENFORCEMENT_BLACK = 3;
|
||||
|
||||
private static final int HIDDEN_API_ENFORCEMENT_MAX = HIDDEN_API_ENFORCEMENT_BLACK;
|
||||
|
||||
/**
|
||||
* Values in this IntDef MUST be kept in sync with enum hiddenapi::EnforcementPolicy in
|
||||
* art/runtime/hidden_api.h
|
||||
* @hide
|
||||
*/
|
||||
@IntDef(prefix = { "HIDDEN_API_ENFORCEMENT_" }, value = {
|
||||
HIDDEN_API_ENFORCEMENT_DEFAULT,
|
||||
HIDDEN_API_ENFORCEMENT_NONE,
|
||||
HIDDEN_API_ENFORCEMENT_ALL_LISTS,
|
||||
HIDDEN_API_ENFORCEMENT_DARK_GREY_AND_BLACK,
|
||||
HIDDEN_API_ENFORCEMENT_BLACK,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface HiddenApiEnforcementPolicy {}
|
||||
|
||||
private boolean isValidHiddenApiEnforcementPolicy(int policy) {
|
||||
return policy >= HIDDEN_API_ENFORCEMENT_DEFAULT && policy <= HIDDEN_API_ENFORCEMENT_MAX;
|
||||
}
|
||||
|
||||
private int mHiddenApiPolicy = HIDDEN_API_ENFORCEMENT_DEFAULT;
|
||||
|
||||
public void dump(Printer pw, String prefix) {
|
||||
dump(pw, prefix, DUMP_FLAG_ALL);
|
||||
}
|
||||
@@ -1133,6 +1185,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
|
||||
if (category != CATEGORY_UNDEFINED) {
|
||||
pw.println(prefix + "category=" + category);
|
||||
}
|
||||
pw.println(prefix + "HiddenApiEnforcementPolicy=" + getHiddenApiEnforcementPolicy());
|
||||
}
|
||||
super.dumpBack(pw, prefix);
|
||||
}
|
||||
@@ -1228,6 +1281,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
|
||||
targetSandboxVersion = orig.targetSandboxVersion;
|
||||
classLoaderName = orig.classLoaderName;
|
||||
splitClassLoaderNames = orig.splitClassLoaderNames;
|
||||
mHiddenApiPolicy = orig.mHiddenApiPolicy;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
@@ -1298,6 +1352,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
|
||||
dest.writeInt(targetSandboxVersion);
|
||||
dest.writeString(classLoaderName);
|
||||
dest.writeStringArray(splitClassLoaderNames);
|
||||
dest.writeInt(mHiddenApiPolicy);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<ApplicationInfo> CREATOR
|
||||
@@ -1365,6 +1420,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
|
||||
targetSandboxVersion = source.readInt();
|
||||
classLoaderName = source.readString();
|
||||
splitClassLoaderNames = source.readStringArray();
|
||||
mHiddenApiPolicy = source.readInt();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1456,14 +1512,31 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPackageWhitelistedForHiddenApis() {
|
||||
return SystemConfig.getInstance().getHiddenApiWhitelistedApps().contains(packageName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public boolean isAllowedToUseHiddenApi() {
|
||||
boolean whitelisted =
|
||||
SystemConfig.getInstance().getHiddenApiWhitelistedApps().contains(packageName);
|
||||
return isSystemApp() || // TODO get rid of this once the whitelist has been populated
|
||||
(whitelisted && (isSystemApp() || isUpdatedSystemApp()));
|
||||
public @HiddenApiEnforcementPolicy int getHiddenApiEnforcementPolicy() {
|
||||
if (mHiddenApiPolicy != HIDDEN_API_ENFORCEMENT_DEFAULT) {
|
||||
return mHiddenApiPolicy;
|
||||
}
|
||||
if (isPackageWhitelistedForHiddenApis() && (isSystemApp() || isUpdatedSystemApp())) {
|
||||
return HIDDEN_API_ENFORCEMENT_NONE;
|
||||
}
|
||||
return HIDDEN_API_ENFORCEMENT_BLACK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void setHiddenApiEnforcementPolicy(@HiddenApiEnforcementPolicy int policy) {
|
||||
if (!isValidHiddenApiEnforcementPolicy(policy)) {
|
||||
throw new IllegalArgumentException("Invalid API enforcement policy: " + policy);
|
||||
}
|
||||
mHiddenApiPolicy = policy;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -55,10 +55,21 @@ public final class Zygote {
|
||||
public static final int DISABLE_VERIFIER = 1 << 9;
|
||||
/** Only use oat files located in /system. Otherwise use dex/jar/apk . */
|
||||
public static final int ONLY_USE_SYSTEM_OAT_FILES = 1 << 10;
|
||||
/** Do enfore hidden API access restrictions. */
|
||||
public static final int ENABLE_HIDDEN_API_CHECKS = 1 << 11;
|
||||
/** Force generation of native debugging information for backtraces. */
|
||||
public static final int DEBUG_GENERATE_MINI_DEBUG_INFO = 1 << 12;
|
||||
public static final int DEBUG_GENERATE_MINI_DEBUG_INFO = 1 << 11;
|
||||
/**
|
||||
* Hidden API access restrictions. This is a mask for bits representing the API enforcement
|
||||
* policy, defined by {@code @ApplicationInfo.HiddenApiEnforcementPolicy}.
|
||||
*/
|
||||
public static final int API_ENFORCEMENT_POLICY_MASK = (1 << 12) | (1 << 13);
|
||||
/**
|
||||
* Bit shift for use with {@link #API_ENFORCEMENT_POLICY_MASK}.
|
||||
*
|
||||
* (flags & API_ENFORCEMENT_POLICY_MASK) >> API_ENFORCEMENT_POLICY_SHIFT gives
|
||||
* @ApplicationInfo.ApiEnforcementPolicy values.
|
||||
*/
|
||||
public static final int API_ENFORCEMENT_POLICY_SHIFT =
|
||||
Integer.numberOfTrailingZeros(API_ENFORCEMENT_POLICY_MASK);
|
||||
|
||||
/** No external storage should be mounted. */
|
||||
public static final int MOUNT_EXTERNAL_NONE = 0;
|
||||
|
||||
@@ -257,6 +257,7 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.ApplicationInfo.HiddenApiEnforcementPolicy;
|
||||
import android.content.pm.ConfigurationInfo;
|
||||
import android.content.pm.IPackageDataObserver;
|
||||
import android.content.pm.IPackageManager;
|
||||
@@ -3944,12 +3945,14 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
|
||||
}
|
||||
|
||||
if (!app.info.isAllowedToUseHiddenApi() &&
|
||||
!disableHiddenApiChecks &&
|
||||
!mHiddenApiBlacklist.isDisabled()) {
|
||||
// This app is not allowed to use undocumented and private APIs, or blacklisting is
|
||||
// enabled. Set up its runtime with the appropriate flag.
|
||||
runtimeFlags |= Zygote.ENABLE_HIDDEN_API_CHECKS;
|
||||
if (!disableHiddenApiChecks && !mHiddenApiBlacklist.isDisabled()) {
|
||||
@HiddenApiEnforcementPolicy int policy =
|
||||
app.info.getHiddenApiEnforcementPolicy();
|
||||
int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT);
|
||||
if ((policyBits & Zygote.API_ENFORCEMENT_POLICY_MASK) != policyBits) {
|
||||
throw new IllegalStateException("Invalid API policy: " + policy);
|
||||
}
|
||||
runtimeFlags |= policyBits;
|
||||
}
|
||||
|
||||
String invokeWith = null;
|
||||
|
||||
@@ -47,6 +47,8 @@ import java.util.Map;
|
||||
|
||||
import dalvik.system.DexFile;
|
||||
|
||||
import static android.content.pm.ApplicationInfo.HIDDEN_API_ENFORCEMENT_NONE;
|
||||
|
||||
import static com.android.server.pm.Installer.DEXOPT_BOOTCOMPLETE;
|
||||
import static com.android.server.pm.Installer.DEXOPT_DEBUGGABLE;
|
||||
import static com.android.server.pm.Installer.DEXOPT_PROFILE_GUIDED;
|
||||
@@ -532,7 +534,10 @@ public class PackageDexOptimizer {
|
||||
int profileFlag = isProfileGuidedFilter ? DEXOPT_PROFILE_GUIDED : 0;
|
||||
// Some apps are executed with restrictions on hidden API usage. If this app is one
|
||||
// of them, pass a flag to dexopt to enable the same restrictions during compilation.
|
||||
int hiddenApiFlag = info.isAllowedToUseHiddenApi() ? 0 : DEXOPT_ENABLE_HIDDEN_API_CHECKS;
|
||||
// TODO we should pass the actual flag value to dexopt, rather than assuming blacklist
|
||||
int hiddenApiFlag = info.getHiddenApiEnforcementPolicy() == HIDDEN_API_ENFORCEMENT_NONE
|
||||
? 0
|
||||
: DEXOPT_ENABLE_HIDDEN_API_CHECKS;
|
||||
// Avoid generating CompactDex for modes that are latency critical.
|
||||
final int compilationReason = options.getCompilationReason();
|
||||
boolean generateCompactDex = true;
|
||||
|
||||
Reference in New Issue
Block a user