Loading services/core/java/com/android/server/wm/ActivitySecurityModelFeatureFlags.java 0 → 100644 +114 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.wm; import static android.provider.DeviceConfig.NAMESPACE_WINDOW_MANAGER; import static com.android.server.wm.ActivityStarter.ASM_RESTRICTIONS; import android.annotation.NonNull; import android.app.compat.CompatChanges; import android.content.pm.PackageManager; import android.provider.DeviceConfig; import com.android.internal.annotations.GuardedBy; import java.util.HashSet; import java.util.concurrent.Executor; /** * Contains utility methods to query whether or not go/activity-security should be enabled * asm_start_rules_enabled - Enable rule enforcement in ActivityStarter.java * asm_start_rules_toasts_enabled - Show toasts when rules would block from ActivityStarter.java * asm_start_rules_exception_list - Comma separated list of packages to exclude from the above * 2 rules. * TODO(b/258792202) Cleanup once ASM is ready to launch */ class ActivitySecurityModelFeatureFlags { // TODO(b/230590090): Replace with public documentation once ready static final String DOC_LINK = "go/android-asm"; private static final String NAMESPACE = NAMESPACE_WINDOW_MANAGER; private static final String KEY_ASM_RESTRICTIONS_ENABLED = "asm_restrictions_enabled"; private static final String KEY_ASM_TOASTS_ENABLED = "asm_toasts_enabled"; private static final String KEY_ASM_EXEMPTED_PACKAGES = "asm_exempted_packages"; private static final int VALUE_DISABLE = 0; private static final int VALUE_ENABLE_FOR_U = 1; private static final int VALUE_ENABLE_FOR_ALL = 2; private static final int DEFAULT_VALUE = VALUE_DISABLE; private static final String DEFAULT_EXCEPTION_LIST = ""; private static int sAsmToastsEnabled; private static int sAsmRestrictionsEnabled; private static final HashSet<String> sExcludedPackageNames = new HashSet<>(); private static PackageManager sPm; @GuardedBy("ActivityTaskManagerService.mGlobalLock") static void initialize(@NonNull Executor executor, @NonNull PackageManager pm) { updateFromDeviceConfig(); DeviceConfig.addOnPropertiesChangedListener(NAMESPACE, executor, properties -> updateFromDeviceConfig()); sPm = pm; } @GuardedBy("ActivityTaskManagerService.mGlobalLock") static boolean shouldShowToast(int uid) { return flagEnabledForUid(sAsmToastsEnabled, uid); } @GuardedBy("ActivityTaskManagerService.mGlobalLock") static boolean shouldBlockActivityStart(int uid) { return flagEnabledForUid(sAsmRestrictionsEnabled, uid); } private static boolean flagEnabledForUid(int flag, int uid) { boolean flagEnabled = flag == VALUE_ENABLE_FOR_ALL || (flag == VALUE_ENABLE_FOR_U && CompatChanges.isChangeEnabled(ASM_RESTRICTIONS, uid)); if (flagEnabled) { String[] packageNames = sPm.getPackagesForUid(uid); for (int i = 0; i < packageNames.length; i++) { if (sExcludedPackageNames.contains(packageNames[i])) { return false; } } return true; } return false; } private static void updateFromDeviceConfig() { sAsmToastsEnabled = DeviceConfig.getInt(NAMESPACE, KEY_ASM_TOASTS_ENABLED, DEFAULT_VALUE); sAsmRestrictionsEnabled = DeviceConfig.getInt(NAMESPACE, KEY_ASM_RESTRICTIONS_ENABLED, DEFAULT_VALUE); String rawExceptionList = DeviceConfig.getString(NAMESPACE, KEY_ASM_EXEMPTED_PACKAGES, DEFAULT_EXCEPTION_LIST); sExcludedPackageNames.clear(); String[] packages = rawExceptionList.split(","); for (String packageName : packages) { String packageNameTrimmed = packageName.trim(); if (!packageNameTrimmed.isEmpty()) { sExcludedPackageNames.add(packageNameTrimmed); } } } } services/core/java/com/android/server/wm/ActivityStarter.java +33 −7 Original line number Diff line number Diff line Loading @@ -125,6 +125,7 @@ import android.service.voice.IVoiceInteractionSession; import android.text.TextUtils; import android.util.Pools.SynchronizedPool; import android.util.Slog; import android.widget.Toast; import android.window.RemoteTransition; import com.android.internal.annotations.VisibleForTesting; Loading @@ -132,6 +133,7 @@ import com.android.internal.app.HeavyWeightSwitcherActivity; import com.android.internal.app.IVoiceInteractor; import com.android.internal.protolog.common.ProtoLog; import com.android.internal.util.FrameworkStatsLog; import com.android.server.UiThread; import com.android.server.am.PendingIntentRecord; import com.android.server.pm.InstantAppResolver; import com.android.server.power.ShutdownCheckPoints; Loading Loading @@ -168,6 +170,13 @@ class ActivityStarter { @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU) static final long ENABLE_PENDING_INTENT_BAL_OPTION = 192341120L; /** * Feature flag for go/activity-security rules */ @ChangeId @EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) static final long ASM_RESTRICTIONS = 230590090L; private final ActivityTaskManagerService mService; private final RootWindowContainer mRootWindowContainer; private final ActivityTaskSupervisor mSupervisor; Loading Loading @@ -1859,7 +1868,7 @@ class ActivityStarter { } if (!checkActivitySecurityModel(r, newTask, targetTask)) { return START_SUCCESS; return START_ABORTED; } return START_SUCCESS; Loading Loading @@ -1925,11 +1934,6 @@ class ActivityStarter { : targetTask.getActivity(ar -> !ar.isState(FINISHING) && !ar.isAlwaysOnTop()); Slog.i(TAG, "Launching r: " + r + " from background: " + mSourceRecord + ". New task: " + newTask + ". Top activity: " + targetTopActivity); int action = newTask || mSourceRecord == null ? FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED__ACTION__ACTIVITY_START_NEW_TASK : (mSourceRecord.getTask().equals(targetTask) Loading Loading @@ -1965,9 +1969,31 @@ class ActivityStarter { && !targetTask.equals(mSourceRecord.getTask()) && targetTask.isVisible() ); boolean shouldBlockActivityStart = ActivitySecurityModelFeatureFlags.shouldBlockActivityStart(mCallingUid); if (ActivitySecurityModelFeatureFlags.shouldShowToast(mCallingUid)) { UiThread.getHandler().post(() -> Toast.makeText(mService.mContext, (shouldBlockActivityStart ? "Activity start blocked by " : "Activity start would be blocked by ") + ActivitySecurityModelFeatureFlags.DOC_LINK, Toast.LENGTH_SHORT).show()); } if (shouldBlockActivityStart) { Slog.e(TAG, "Abort Launching r: " + r + " as source: " + mSourceRecord + "is in background. New task: " + newTask + ". Top activity: " + targetTopActivity); return false; } return true; } /** * Returns whether embedding of {@code starting} is allowed. * Loading services/core/java/com/android/server/wm/ActivityTaskManagerService.java +2 −0 Original line number Diff line number Diff line Loading @@ -859,6 +859,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mRecentTasks.onSystemReadyLocked(); mTaskSupervisor.onSystemReady(); mActivityClientController.onSystemReady(); // TODO(b/258792202) Cleanup once ASM is ready to launch ActivitySecurityModelFeatureFlags.initialize(mContext.getMainExecutor(), pm); } } Loading Loading
services/core/java/com/android/server/wm/ActivitySecurityModelFeatureFlags.java 0 → 100644 +114 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.wm; import static android.provider.DeviceConfig.NAMESPACE_WINDOW_MANAGER; import static com.android.server.wm.ActivityStarter.ASM_RESTRICTIONS; import android.annotation.NonNull; import android.app.compat.CompatChanges; import android.content.pm.PackageManager; import android.provider.DeviceConfig; import com.android.internal.annotations.GuardedBy; import java.util.HashSet; import java.util.concurrent.Executor; /** * Contains utility methods to query whether or not go/activity-security should be enabled * asm_start_rules_enabled - Enable rule enforcement in ActivityStarter.java * asm_start_rules_toasts_enabled - Show toasts when rules would block from ActivityStarter.java * asm_start_rules_exception_list - Comma separated list of packages to exclude from the above * 2 rules. * TODO(b/258792202) Cleanup once ASM is ready to launch */ class ActivitySecurityModelFeatureFlags { // TODO(b/230590090): Replace with public documentation once ready static final String DOC_LINK = "go/android-asm"; private static final String NAMESPACE = NAMESPACE_WINDOW_MANAGER; private static final String KEY_ASM_RESTRICTIONS_ENABLED = "asm_restrictions_enabled"; private static final String KEY_ASM_TOASTS_ENABLED = "asm_toasts_enabled"; private static final String KEY_ASM_EXEMPTED_PACKAGES = "asm_exempted_packages"; private static final int VALUE_DISABLE = 0; private static final int VALUE_ENABLE_FOR_U = 1; private static final int VALUE_ENABLE_FOR_ALL = 2; private static final int DEFAULT_VALUE = VALUE_DISABLE; private static final String DEFAULT_EXCEPTION_LIST = ""; private static int sAsmToastsEnabled; private static int sAsmRestrictionsEnabled; private static final HashSet<String> sExcludedPackageNames = new HashSet<>(); private static PackageManager sPm; @GuardedBy("ActivityTaskManagerService.mGlobalLock") static void initialize(@NonNull Executor executor, @NonNull PackageManager pm) { updateFromDeviceConfig(); DeviceConfig.addOnPropertiesChangedListener(NAMESPACE, executor, properties -> updateFromDeviceConfig()); sPm = pm; } @GuardedBy("ActivityTaskManagerService.mGlobalLock") static boolean shouldShowToast(int uid) { return flagEnabledForUid(sAsmToastsEnabled, uid); } @GuardedBy("ActivityTaskManagerService.mGlobalLock") static boolean shouldBlockActivityStart(int uid) { return flagEnabledForUid(sAsmRestrictionsEnabled, uid); } private static boolean flagEnabledForUid(int flag, int uid) { boolean flagEnabled = flag == VALUE_ENABLE_FOR_ALL || (flag == VALUE_ENABLE_FOR_U && CompatChanges.isChangeEnabled(ASM_RESTRICTIONS, uid)); if (flagEnabled) { String[] packageNames = sPm.getPackagesForUid(uid); for (int i = 0; i < packageNames.length; i++) { if (sExcludedPackageNames.contains(packageNames[i])) { return false; } } return true; } return false; } private static void updateFromDeviceConfig() { sAsmToastsEnabled = DeviceConfig.getInt(NAMESPACE, KEY_ASM_TOASTS_ENABLED, DEFAULT_VALUE); sAsmRestrictionsEnabled = DeviceConfig.getInt(NAMESPACE, KEY_ASM_RESTRICTIONS_ENABLED, DEFAULT_VALUE); String rawExceptionList = DeviceConfig.getString(NAMESPACE, KEY_ASM_EXEMPTED_PACKAGES, DEFAULT_EXCEPTION_LIST); sExcludedPackageNames.clear(); String[] packages = rawExceptionList.split(","); for (String packageName : packages) { String packageNameTrimmed = packageName.trim(); if (!packageNameTrimmed.isEmpty()) { sExcludedPackageNames.add(packageNameTrimmed); } } } }
services/core/java/com/android/server/wm/ActivityStarter.java +33 −7 Original line number Diff line number Diff line Loading @@ -125,6 +125,7 @@ import android.service.voice.IVoiceInteractionSession; import android.text.TextUtils; import android.util.Pools.SynchronizedPool; import android.util.Slog; import android.widget.Toast; import android.window.RemoteTransition; import com.android.internal.annotations.VisibleForTesting; Loading @@ -132,6 +133,7 @@ import com.android.internal.app.HeavyWeightSwitcherActivity; import com.android.internal.app.IVoiceInteractor; import com.android.internal.protolog.common.ProtoLog; import com.android.internal.util.FrameworkStatsLog; import com.android.server.UiThread; import com.android.server.am.PendingIntentRecord; import com.android.server.pm.InstantAppResolver; import com.android.server.power.ShutdownCheckPoints; Loading Loading @@ -168,6 +170,13 @@ class ActivityStarter { @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU) static final long ENABLE_PENDING_INTENT_BAL_OPTION = 192341120L; /** * Feature flag for go/activity-security rules */ @ChangeId @EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) static final long ASM_RESTRICTIONS = 230590090L; private final ActivityTaskManagerService mService; private final RootWindowContainer mRootWindowContainer; private final ActivityTaskSupervisor mSupervisor; Loading Loading @@ -1859,7 +1868,7 @@ class ActivityStarter { } if (!checkActivitySecurityModel(r, newTask, targetTask)) { return START_SUCCESS; return START_ABORTED; } return START_SUCCESS; Loading Loading @@ -1925,11 +1934,6 @@ class ActivityStarter { : targetTask.getActivity(ar -> !ar.isState(FINISHING) && !ar.isAlwaysOnTop()); Slog.i(TAG, "Launching r: " + r + " from background: " + mSourceRecord + ". New task: " + newTask + ". Top activity: " + targetTopActivity); int action = newTask || mSourceRecord == null ? FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED__ACTION__ACTIVITY_START_NEW_TASK : (mSourceRecord.getTask().equals(targetTask) Loading Loading @@ -1965,9 +1969,31 @@ class ActivityStarter { && !targetTask.equals(mSourceRecord.getTask()) && targetTask.isVisible() ); boolean shouldBlockActivityStart = ActivitySecurityModelFeatureFlags.shouldBlockActivityStart(mCallingUid); if (ActivitySecurityModelFeatureFlags.shouldShowToast(mCallingUid)) { UiThread.getHandler().post(() -> Toast.makeText(mService.mContext, (shouldBlockActivityStart ? "Activity start blocked by " : "Activity start would be blocked by ") + ActivitySecurityModelFeatureFlags.DOC_LINK, Toast.LENGTH_SHORT).show()); } if (shouldBlockActivityStart) { Slog.e(TAG, "Abort Launching r: " + r + " as source: " + mSourceRecord + "is in background. New task: " + newTask + ". Top activity: " + targetTopActivity); return false; } return true; } /** * Returns whether embedding of {@code starting} is allowed. * Loading
services/core/java/com/android/server/wm/ActivityTaskManagerService.java +2 −0 Original line number Diff line number Diff line Loading @@ -859,6 +859,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mRecentTasks.onSystemReadyLocked(); mTaskSupervisor.onSystemReady(); mActivityClientController.onSystemReady(); // TODO(b/258792202) Cleanup once ASM is ready to launch ActivitySecurityModelFeatureFlags.initialize(mContext.getMainExecutor(), pm); } } Loading