From 1ab3025cc761862392db757ed8c12de0574443f5 Mon Sep 17 00:00:00 2001 From: Mathew Inwood Date: Tue, 3 Apr 2018 14:47:26 +0100 Subject: [PATCH] Different hidden API enforcement policy for P & pre-P. Also make these configurable so we have the flexibility to change it if necessary. Setting the policy inside ActivityManagerService is not ideal, as that means that AMS is the only place where the policy in ApplicationInfo is correct. It should really be set inside PackageManagerService. However, if it's set there, it would get out of date when the settings change, and we'd have to update inside AMS anyway. So putting it only here seems ok for now. Test: $ adb shell settings put global hidden_api_policy_pre_p_apps 2 Test: $ adb shell settings put global hidden_api_policy_p_apps 2 Bug: 64382372 Change-Id: Ic4cbbb1e6464623e90c17ae08c0b6cbbe0dfa125 --- .../android/content/pm/ApplicationInfo.java | 41 ++++++++++++++--- core/java/android/provider/Settings.java | 23 ++++++++++ .../android/provider/SettingsBackupTest.java | 2 + .../server/am/ActivityManagerService.java | 45 ++++++++++++++++--- 4 files changed, 100 insertions(+), 11 deletions(-) diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 49b1efd08c914..c5a39f4c45027 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -26,6 +26,7 @@ import android.content.Context; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Environment; import android.os.Parcel; import android.os.Parcelable; @@ -1166,7 +1167,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { @Retention(RetentionPolicy.SOURCE) public @interface HiddenApiEnforcementPolicy {} - private boolean isValidHiddenApiEnforcementPolicy(int policy) { + /** @hide */ + public static boolean isValidHiddenApiEnforcementPolicy(int policy) { return policy >= HIDDEN_API_ENFORCEMENT_DEFAULT && policy <= HIDDEN_API_ENFORCEMENT_MAX; } @@ -1686,13 +1688,17 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { * @hide */ public @HiddenApiEnforcementPolicy int getHiddenApiEnforcementPolicy() { - if (mHiddenApiPolicy != HIDDEN_API_ENFORCEMENT_DEFAULT) { - return mHiddenApiPolicy; - } if (isAllowedToUseHiddenApis()) { return HIDDEN_API_ENFORCEMENT_NONE; } - return HIDDEN_API_ENFORCEMENT_BLACK; + if (mHiddenApiPolicy != HIDDEN_API_ENFORCEMENT_DEFAULT) { + return mHiddenApiPolicy; + } + if (targetSdkVersion <= Build.VERSION_CODES.O_MR1) { + return HIDDEN_API_ENFORCEMENT_BLACK; + } else { + return HIDDEN_API_ENFORCEMENT_DARK_GREY_AND_BLACK; + } } /** @@ -1705,6 +1711,31 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { mHiddenApiPolicy = policy; } + /** + * Updates the hidden API enforcement policy for this app from the given values, if appropriate. + * + * This will have no effect if this app is not subject to hidden API enforcement, i.e. if it + * is on the package whitelist. + * + * @param policyPreP configured policy for pre-P apps, or {@link + * #HIDDEN_API_ENFORCEMENT_DEFAULT} if nothing configured. + * @param policyP configured policy for apps targeting P or later, or {@link + * #HIDDEN_API_ENFORCEMENT_DEFAULT} if nothing configured. + * @hide + */ + public void maybeUpdateHiddenApiEnforcementPolicy( + @HiddenApiEnforcementPolicy int policyPreP, @HiddenApiEnforcementPolicy int policyP) { + if (isPackageWhitelistedForHiddenApis()) { + return; + } + if (targetSdkVersion <= Build.VERSION_CODES.O_MR1) { + setHiddenApiEnforcementPolicy(policyPreP); + } else if (targetSdkVersion > Build.VERSION_CODES.O_MR1) { + setHiddenApiEnforcementPolicy(policyP); + } + + } + /** * @hide */ diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index c361137e1fdce..60bbb10de0141 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -11748,6 +11748,29 @@ public final class Settings { public static final String HIDDEN_API_BLACKLIST_EXEMPTIONS = "hidden_api_blacklist_exemptions"; + /** + * Hidden API enforcement policy for apps targeting SDK versions prior to the latest + * version. + * + * Values correspond to @{@link + * android.content.pm.ApplicationInfo.HiddenApiEnforcementPolicy} + * + * @hide + */ + public static final String HIDDEN_API_POLICY_PRE_P_APPS = + "hidden_api_policy_pre_p_apps"; + + /** + * Hidden API enforcement policy for apps targeting the current SDK version. + * + * Values correspond to @{@link + * android.content.pm.ApplicationInfo.HiddenApiEnforcementPolicy} + * + * @hide + */ + public static final String HIDDEN_API_POLICY_P_APPS = + "hidden_api_policy_p_apps"; + /** * Timeout for a single {@link android.media.soundtrigger.SoundTriggerDetectionService} * operation (in ms). diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index f13b575341b7e..a5941b26b9d3e 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -246,6 +246,8 @@ public class SettingsBackupTest { Settings.Global.HDMI_CONTROL_ENABLED, Settings.Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED, Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED, + Settings.Global.HIDDEN_API_POLICY_P_APPS, + Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS, Settings.Global.HIDE_ERROR_DIALOGS, Settings.Global.HTTP_PROXY, HYBRID_SYSUI_BATTERY_WARNING_FLAGS, diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 26866b3a324b4..04d54e1dcb8dd 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -52,6 +52,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME; +import static android.content.pm.ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT; import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS; import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT; import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY; @@ -1957,7 +1958,7 @@ public class ActivityManagerService extends IActivityManager.Stub final ActivityManagerConstants mConstants; // Encapsulates the global setting "hidden_api_blacklist_exemptions" - final HiddenApiBlacklist mHiddenApiBlacklist; + final HiddenApiSettings mHiddenApiBlacklist; PackageManagerInternal mPackageManagerInt; @@ -2892,17 +2893,19 @@ public class ActivityManagerService extends IActivityManager.Stub } /** - * Encapsulates the global setting "hidden_api_blacklist_exemptions", including tracking the - * latest value via a content observer. + * Encapsulates global settings related to hidden API enforcement behaviour, including tracking + * the latest value via a content observer. */ - static class HiddenApiBlacklist extends ContentObserver { + static class HiddenApiSettings extends ContentObserver { private final Context mContext; private boolean mBlacklistDisabled; private String mExemptionsStr; private List mExemptions = Collections.emptyList(); + @HiddenApiEnforcementPolicy private int mPolicyPreP = HIDDEN_API_ENFORCEMENT_DEFAULT; + @HiddenApiEnforcementPolicy private int mPolicyP = HIDDEN_API_ENFORCEMENT_DEFAULT; - public HiddenApiBlacklist(Handler handler, Context context) { + public HiddenApiSettings(Handler handler, Context context) { super(handler); mContext = context; } @@ -2912,6 +2915,14 @@ public class ActivityManagerService extends IActivityManager.Stub Settings.Global.getUriFor(Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS), false, this); + mContext.getContentResolver().registerContentObserver( + Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS), + false, + this); + mContext.getContentResolver().registerContentObserver( + Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY_P_APPS), + false, + this); update(); } @@ -2931,13 +2942,32 @@ public class ActivityManagerService extends IActivityManager.Stub } zygoteProcess.setApiBlacklistExemptions(mExemptions); } + mPolicyPreP = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS); + mPolicyP = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY_P_APPS); + } + private @HiddenApiEnforcementPolicy int getValidEnforcementPolicy(String settingsKey) { + int policy = Settings.Global.getInt(mContext.getContentResolver(), settingsKey, + ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT); + if (ApplicationInfo.isValidHiddenApiEnforcementPolicy(policy)) { + return policy; + } else { + return ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT; + } } boolean isDisabled() { return mBlacklistDisabled; } + @HiddenApiEnforcementPolicy int getPolicyForPrePApps() { + return mPolicyPreP; + } + + @HiddenApiEnforcementPolicy int getPolicyForPApps() { + return mPolicyP; + } + public void onChange(boolean selfChange) { update(); } @@ -3110,7 +3140,7 @@ public class ActivityManagerService extends IActivityManager.Stub } }; - mHiddenApiBlacklist = new HiddenApiBlacklist(mHandler, mContext); + mHiddenApiBlacklist = new HiddenApiSettings(mHandler, mContext); Watchdog.getInstance().addMonitor(this); Watchdog.getInstance().addThread(mHandler); @@ -4226,6 +4256,9 @@ public class ActivityManagerService extends IActivityManager.Stub } if (!disableHiddenApiChecks && !mHiddenApiBlacklist.isDisabled()) { + app.info.maybeUpdateHiddenApiEnforcementPolicy( + mHiddenApiBlacklist.getPolicyForPrePApps(), + mHiddenApiBlacklist.getPolicyForPApps()); @HiddenApiEnforcementPolicy int policy = app.info.getHiddenApiEnforcementPolicy(); int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT);