1 /* 2 * Copyright (C) 2021 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 android.car.builtin.content.pm; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.RequiresApi; 22 import android.annotation.SystemApi; 23 import android.annotation.UserIdInt; 24 import android.app.ActivityManager; 25 import android.app.ActivityThread; 26 import android.car.builtin.annotation.AddedIn; 27 import android.car.builtin.annotation.PlatformVersion; 28 import android.content.ComponentName; 29 import android.content.Context; 30 import android.content.pm.ApplicationInfo; 31 import android.content.pm.ComponentInfo; 32 import android.content.pm.IPackageManager; 33 import android.content.pm.PackageInfo; 34 import android.content.pm.PackageManager; 35 import android.os.Build; 36 import android.os.RemoteException; 37 import android.text.TextUtils; 38 39 /** 40 * Helper class for {@code PackageManager}. 41 * 42 * @hide 43 */ 44 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 45 public final class PackageManagerHelper { 46 47 /** 48 * Read-only property to define the package name of car service updatable 49 * package. 50 * 51 * <p>This property must be defined and will be set to {@code "com.android.car.updatable"} for 52 * car service created from AOSP build. It can be set to the different package name depending on 53 * who is signing the car framework apex module. 54 */ 55 @AddedIn(PlatformVersion.TIRAMISU_0) 56 public static final String PROPERTY_CAR_SERVICE_PACKAGE_NAME = 57 "ro.android.car.carservice.package"; 58 59 /** 60 * Read only property which contains semicolon (;) separated list of RRO packages. 61 * 62 * <p> 63 * RRO packages would be enabled if they are overlaying {@code CarServiceUpdatable}. 64 * {@code CarServiceUpdatable} can have different package names and this property may include 65 * all RROs to cover different {@code CarServiceUpdatable} package names but only those 66 * overriding the current {@code CarServiceUpdatable} package name will be selected. 67 */ 68 @AddedIn(PlatformVersion.TIRAMISU_0) 69 public static final String PROPERTY_CAR_SERVICE_OVERLAY_PACKAGES = 70 "ro.android.car.carservice.overlay.packages"; 71 PackageManagerHelper()72 private PackageManagerHelper() { 73 throw new UnsupportedOperationException("provides only static methods"); 74 } 75 76 /** 77 * Gets the name of the {@code SystemUI} package. 78 * @param context 79 * @return 80 */ 81 @NonNull 82 @AddedIn(PlatformVersion.TIRAMISU_0) getSystemUiPackageName(@onNull Context context)83 public static String getSystemUiPackageName(@NonNull Context context) { 84 // TODO(157082995): This information can be taken from 85 // PackageManageInternalImpl.getSystemUiServiceComponent() 86 String flattenName = context.getResources() 87 .getString(com.android.internal.R.string.config_systemUIServiceComponent); 88 if (TextUtils.isEmpty(flattenName)) { 89 throw new IllegalStateException("No " 90 + "com.android.internal.R.string.config_systemUIServiceComponent resource"); 91 } 92 try { 93 ComponentName componentName = ComponentName.unflattenFromString(flattenName); 94 return componentName.getPackageName(); 95 } catch (RuntimeException e) { 96 throw new IllegalStateException("Invalid component name defined by " 97 + "com.android.internal.R.string.config_systemUIServiceComponent resource: " 98 + flattenName, e); 99 } 100 } 101 102 /** Check {@link PackageManager#getPackageInfoAsUser(String, int, int)}. */ 103 @AddedIn(PlatformVersion.TIRAMISU_0) getPackageInfoAsUser(@onNull PackageManager pm, @NonNull String packageName, int packageInfoFlags, @UserIdInt int userId)104 public static PackageInfo getPackageInfoAsUser(@NonNull PackageManager pm, 105 @NonNull String packageName, int packageInfoFlags, 106 @UserIdInt int userId) throws PackageManager.NameNotFoundException { 107 return pm.getPackageInfoAsUser(packageName, packageInfoFlags, userId); 108 } 109 110 /** Check {@link PackageManager#getPackageUidAsUser(String, int)}. */ 111 @AddedIn(PlatformVersion.TIRAMISU_0) getPackageUidAsUser(@onNull PackageManager pm, @NonNull String packageName, @UserIdInt int userId)112 public static int getPackageUidAsUser(@NonNull PackageManager pm, @NonNull String packageName, 113 @UserIdInt int userId) throws PackageManager.NameNotFoundException { 114 return pm.getPackageUidAsUser(packageName, userId); 115 } 116 117 /** Check {@link PackageManager#getNamesForUids(int[])}. */ 118 @Nullable 119 @AddedIn(PlatformVersion.TIRAMISU_0) getNamesForUids(@onNull PackageManager pm, int[] uids)120 public static String[] getNamesForUids(@NonNull PackageManager pm, int[] uids) { 121 return pm.getNamesForUids(uids); 122 } 123 124 /** Check {@link PackageManager#getApplicationEnabledSetting(String)}. */ 125 @AddedIn(PlatformVersion.TIRAMISU_0) getApplicationEnabledSettingForUser(@onNull String packageName, @UserIdInt int userId)126 public static int getApplicationEnabledSettingForUser(@NonNull String packageName, 127 @UserIdInt int userId) throws RemoteException { 128 IPackageManager pm = ActivityThread.getPackageManager(); 129 return pm.getApplicationEnabledSetting(packageName, userId); 130 } 131 132 /** Check {@link PackageManager#setApplicationEnabledSetting(String, int, int)}. */ 133 @AddedIn(PlatformVersion.TIRAMISU_0) setApplicationEnabledSettingForUser(@onNull String packageName, @PackageManager.EnabledState int newState, @PackageManager.EnabledFlags int flags, @UserIdInt int userId, @NonNull String callingPackage)134 public static void setApplicationEnabledSettingForUser(@NonNull String packageName, 135 @PackageManager.EnabledState int newState, @PackageManager.EnabledFlags int flags, 136 @UserIdInt int userId, @NonNull String callingPackage) throws RemoteException { 137 IPackageManager pm = ActivityThread.getPackageManager(); 138 pm.setApplicationEnabledSetting(packageName, newState, flags, userId, callingPackage); 139 } 140 141 /** Tells if the passed app is OEM app or not. */ 142 @AddedIn(PlatformVersion.TIRAMISU_0) isOemApp(@onNull ApplicationInfo appInfo)143 public static boolean isOemApp(@NonNull ApplicationInfo appInfo) { 144 return (appInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0; 145 } 146 147 /** Tells if the passed app is ODM app or not. */ 148 @AddedIn(PlatformVersion.TIRAMISU_0) isOdmApp(@onNull ApplicationInfo appInfo)149 public static boolean isOdmApp(@NonNull ApplicationInfo appInfo) { 150 return (appInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_ODM) != 0; 151 } 152 153 /** Tells if the passed app is vendor app or not. */ 154 @AddedIn(PlatformVersion.TIRAMISU_0) isVendorApp(@onNull ApplicationInfo appInfo)155 public static boolean isVendorApp(@NonNull ApplicationInfo appInfo) { 156 return (appInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0; 157 } 158 159 /** Tells if the passed app is system app or not. */ 160 @AddedIn(PlatformVersion.TIRAMISU_0) isSystemApp(@onNull ApplicationInfo appInfo)161 public static boolean isSystemApp(@NonNull ApplicationInfo appInfo) { 162 return (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 163 } 164 165 /** Tells if the passed app is updated system app or not. */ 166 @AddedIn(PlatformVersion.TIRAMISU_0) isUpdatedSystemApp(@onNull ApplicationInfo appInfo)167 public static boolean isUpdatedSystemApp(@NonNull ApplicationInfo appInfo) { 168 return (appInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 169 } 170 171 /** Tells if the passed app is product app or not. */ 172 @AddedIn(PlatformVersion.TIRAMISU_0) isProductApp(@onNull ApplicationInfo appInfo)173 public static boolean isProductApp(@NonNull ApplicationInfo appInfo) { 174 return (appInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0; 175 } 176 177 /** Tells if the passed app is system ext vendor app or not. */ 178 @AddedIn(PlatformVersion.TIRAMISU_0) isSystemExtApp(@onNull ApplicationInfo appInfo)179 public static boolean isSystemExtApp(@NonNull ApplicationInfo appInfo) { 180 return (appInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0; 181 } 182 183 /** Check {@link ComponentInfo#getComponentName()}. */ 184 @AddedIn(PlatformVersion.TIRAMISU_0) getComponentName(ComponentInfo info)185 public static ComponentName getComponentName(ComponentInfo info) { 186 return info.getComponentName(); 187 } 188 189 /** Check PackageManagerInternal#getSystemUiServiceComponent(). */ 190 @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 191 @AddedIn(PlatformVersion.UPSIDE_DOWN_CAKE_0) 192 @NonNull getSystemUiServiceComponent(@onNull Context context)193 public static ComponentName getSystemUiServiceComponent(@NonNull Context context) { 194 String flattenName = context.getResources() 195 .getString(com.android.internal.R.string.config_systemUIServiceComponent); 196 if (TextUtils.isEmpty(flattenName)) { 197 throw new IllegalStateException("No " 198 + "com.android.internal.R.string.config_systemUIServiceComponent resource"); 199 } 200 return ComponentName.unflattenFromString(flattenName); 201 } 202 203 /** Check {@link ActivityManager#forceStopPackageAsUser}. */ 204 @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 205 @AddedIn(PlatformVersion.UPSIDE_DOWN_CAKE_0) forceStopPackageAsUser(@onNull Context context, @NonNull String packageName, @UserIdInt int userId)206 public static void forceStopPackageAsUser(@NonNull Context context, @NonNull String packageName, 207 @UserIdInt int userId) { 208 ActivityManager am = context.getSystemService(ActivityManager.class); 209 am.forceStopPackageAsUser(packageName, userId); 210 } 211 212 /** Check {@link ActivityManager#forceStopPackageAsUserEvenWhenStopping}. */ 213 @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 214 @AddedIn(PlatformVersion.UPSIDE_DOWN_CAKE_0) forceStopPackageAsUserEvenWhenStopping(@onNull Context context, @NonNull String packageName, @UserIdInt int userId)215 public static void forceStopPackageAsUserEvenWhenStopping(@NonNull Context context, 216 @NonNull String packageName, @UserIdInt int userId) { 217 ActivityManager am = context.getSystemService(ActivityManager.class); 218 am.forceStopPackageAsUserEvenWhenStopping(packageName, userId); 219 } 220 } 221