1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.wm; 18 19 import static android.provider.DeviceConfig.NAMESPACE_WINDOW_MANAGER; 20 21 import static com.android.server.wm.ActivityStarter.ASM_RESTRICTIONS; 22 23 import android.annotation.NonNull; 24 import android.app.compat.CompatChanges; 25 import android.content.pm.PackageManager; 26 import android.provider.DeviceConfig; 27 28 import com.android.internal.annotations.GuardedBy; 29 30 import java.util.HashSet; 31 import java.util.concurrent.Executor; 32 33 /** 34 * Contains utility methods to query whether or not go/activity-security should be enabled 35 * asm_start_rules_enabled - Enable rule enforcement in ActivityStarter.java 36 * asm_start_rules_toasts_enabled - Show toasts when rules would block from ActivityStarter.java 37 * asm_start_rules_exception_list - Comma separated list of packages to exclude from the above 38 * 2 rules. 39 * TODO(b/258792202) Cleanup once ASM is ready to launch 40 */ 41 class ActivitySecurityModelFeatureFlags { 42 // TODO(b/230590090): Replace with public documentation once ready 43 static final String DOC_LINK = "go/android-asm"; 44 45 /** Used to determine which version of the ASM logic was used in logs while we iterate */ 46 static final int ASM_VERSION = 7; 47 48 private static final String NAMESPACE = NAMESPACE_WINDOW_MANAGER; 49 private static final String KEY_ASM_PREFIX = "ActivitySecurity__"; 50 private static final String KEY_ASM_RESTRICTIONS_ENABLED = KEY_ASM_PREFIX 51 + "asm_restrictions_enabled"; 52 private static final String KEY_ASM_TOASTS_ENABLED = KEY_ASM_PREFIX + "asm_toasts_enabled"; 53 private static final String KEY_ASM_EXEMPTED_PACKAGES = KEY_ASM_PREFIX 54 + "asm_exempted_packages"; 55 private static final int VALUE_DISABLE = 0; 56 private static final int VALUE_ENABLE_FOR_U = 1; 57 private static final int VALUE_ENABLE_FOR_ALL = 2; 58 59 private static final int DEFAULT_VALUE = VALUE_DISABLE; 60 private static final String DEFAULT_EXCEPTION_LIST = ""; 61 62 private static int sAsmToastsEnabled; 63 private static int sAsmRestrictionsEnabled; 64 private static final HashSet<String> sExcludedPackageNames = new HashSet<>(); 65 private static PackageManager sPm; 66 67 @GuardedBy("ActivityTaskManagerService.mGlobalLock") initialize(@onNull Executor executor, @NonNull PackageManager pm)68 static void initialize(@NonNull Executor executor, @NonNull PackageManager pm) { 69 updateFromDeviceConfig(); 70 DeviceConfig.addOnPropertiesChangedListener(NAMESPACE, executor, 71 properties -> updateFromDeviceConfig()); 72 sPm = pm; 73 } 74 75 @GuardedBy("ActivityTaskManagerService.mGlobalLock") shouldShowToast(int uid)76 static boolean shouldShowToast(int uid) { 77 return flagEnabledForUid(sAsmToastsEnabled, uid); 78 } 79 80 @GuardedBy("ActivityTaskManagerService.mGlobalLock") shouldRestrictActivitySwitch(int uid)81 static boolean shouldRestrictActivitySwitch(int uid) { 82 return flagEnabledForUid(sAsmRestrictionsEnabled, uid); 83 } 84 flagEnabledForUid(int flag, int uid)85 private static boolean flagEnabledForUid(int flag, int uid) { 86 boolean flagEnabled = flag == VALUE_ENABLE_FOR_ALL 87 || (flag == VALUE_ENABLE_FOR_U 88 && CompatChanges.isChangeEnabled(ASM_RESTRICTIONS, uid)); 89 90 if (flagEnabled) { 91 String[] packageNames = sPm.getPackagesForUid(uid); 92 if (packageNames == null) { 93 return true; 94 } 95 for (int i = 0; i < packageNames.length; i++) { 96 if (sExcludedPackageNames.contains(packageNames[i])) { 97 return false; 98 } 99 } 100 return true; 101 } 102 103 return false; 104 } 105 updateFromDeviceConfig()106 private static void updateFromDeviceConfig() { 107 sAsmToastsEnabled = DeviceConfig.getInt(NAMESPACE, KEY_ASM_TOASTS_ENABLED, 108 DEFAULT_VALUE); 109 sAsmRestrictionsEnabled = DeviceConfig.getInt(NAMESPACE, KEY_ASM_RESTRICTIONS_ENABLED, 110 DEFAULT_VALUE); 111 112 String rawExceptionList = DeviceConfig.getString(NAMESPACE, 113 KEY_ASM_EXEMPTED_PACKAGES, DEFAULT_EXCEPTION_LIST); 114 sExcludedPackageNames.clear(); 115 String[] packages = rawExceptionList.split(","); 116 for (String packageName : packages) { 117 String packageNameTrimmed = packageName.trim(); 118 if (!packageNameTrimmed.isEmpty()) { 119 sExcludedPackageNames.add(packageNameTrimmed); 120 } 121 } 122 } 123 } 124