1 /* 2 * Copyright (C) 2011 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.pm; 18 19 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 20 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; 21 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 22 23 import android.content.pm.PackageUserState; 24 import android.util.ArraySet; 25 import android.util.SparseArray; 26 27 import java.io.File; 28 29 /** 30 * Settings base class for pending and resolved classes. 31 */ 32 class PackageSettingBase extends GrantedPermissions { 33 /** 34 * Indicates the state of installation. Used by PackageManager to figure out 35 * incomplete installations. Say a package is being installed (the state is 36 * set to PKG_INSTALL_INCOMPLETE) and remains so till the package 37 * installation is successful or unsuccessful in which case the 38 * PackageManager will no longer maintain state information associated with 39 * the package. If some exception(like device freeze or battery being pulled 40 * out) occurs during installation of a package, the PackageManager needs 41 * this information to clean up the previously failed installation. 42 */ 43 static final int PKG_INSTALL_COMPLETE = 1; 44 static final int PKG_INSTALL_INCOMPLETE = 0; 45 46 final String name; 47 final String realName; 48 49 /** 50 * Path where this package was found on disk. For monolithic packages 51 * this is path to single base APK file; for cluster packages this is 52 * path to the cluster directory. 53 */ 54 File codePath; 55 String codePathString; 56 File resourcePath; 57 String resourcePathString; 58 59 /** 60 * The path under which native libraries have been unpacked. This path is 61 * always derived at runtime, and is only stored here for cleanup when a 62 * package is uninstalled. 63 */ 64 @Deprecated 65 String legacyNativeLibraryPathString; 66 67 /** 68 * The primary CPU abi for this package. This value is regenerated at every 69 * boot scan. 70 */ 71 String primaryCpuAbiString; 72 73 /** 74 * The secondary CPU abi for this package. This value is regenerated at every 75 * boot scan. 76 */ 77 String secondaryCpuAbiString; 78 79 /** 80 * The install time CPU override, if any. This value is written at install time 81 * and doesn't change during the life of an install. If non-null, 82 * {@code primaryCpuAbiString} will contain the same value. 83 */ 84 String cpuAbiOverrideString; 85 86 long timeStamp; 87 long firstInstallTime; 88 long lastUpdateTime; 89 int versionCode; 90 91 boolean uidError; 92 93 PackageSignatures signatures = new PackageSignatures(); 94 95 boolean permissionsFixed; 96 boolean haveGids; 97 98 PackageKeySetData keySetData = new PackageKeySetData(); 99 100 private static final PackageUserState DEFAULT_USER_STATE = new PackageUserState(); 101 102 // Whether this package is currently stopped, thus can not be 103 // started until explicitly launched by the user. 104 private final SparseArray<PackageUserState> userState = new SparseArray<PackageUserState>(); 105 106 int installStatus = PKG_INSTALL_COMPLETE; 107 108 PackageSettingBase origPackage; 109 110 /* package name of the app that installed this package */ 111 String installerPackageName; PackageSettingBase(String name, String realName, File codePath, File resourcePath, String legacyNativeLibraryPathString, String primaryCpuAbiString, String secondaryCpuAbiString, String cpuAbiOverrideString, int pVersionCode, int pkgFlags)112 PackageSettingBase(String name, String realName, File codePath, File resourcePath, 113 String legacyNativeLibraryPathString, String primaryCpuAbiString, 114 String secondaryCpuAbiString, String cpuAbiOverrideString, 115 int pVersionCode, int pkgFlags) { 116 super(pkgFlags); 117 this.name = name; 118 this.realName = realName; 119 init(codePath, resourcePath, legacyNativeLibraryPathString, primaryCpuAbiString, 120 secondaryCpuAbiString, cpuAbiOverrideString, pVersionCode); 121 } 122 123 /** 124 * New instance of PackageSetting with one-level-deep cloning. 125 */ 126 @SuppressWarnings("unchecked") PackageSettingBase(PackageSettingBase base)127 PackageSettingBase(PackageSettingBase base) { 128 super(base); 129 130 name = base.name; 131 realName = base.realName; 132 codePath = base.codePath; 133 codePathString = base.codePathString; 134 resourcePath = base.resourcePath; 135 resourcePathString = base.resourcePathString; 136 legacyNativeLibraryPathString = base.legacyNativeLibraryPathString; 137 primaryCpuAbiString = base.primaryCpuAbiString; 138 secondaryCpuAbiString = base.secondaryCpuAbiString; 139 cpuAbiOverrideString = base.cpuAbiOverrideString; 140 timeStamp = base.timeStamp; 141 firstInstallTime = base.firstInstallTime; 142 lastUpdateTime = base.lastUpdateTime; 143 versionCode = base.versionCode; 144 145 uidError = base.uidError; 146 147 signatures = new PackageSignatures(base.signatures); 148 149 permissionsFixed = base.permissionsFixed; 150 haveGids = base.haveGids; 151 userState.clear(); 152 for (int i=0; i<base.userState.size(); i++) { 153 userState.put(base.userState.keyAt(i), 154 new PackageUserState(base.userState.valueAt(i))); 155 } 156 installStatus = base.installStatus; 157 158 origPackage = base.origPackage; 159 160 installerPackageName = base.installerPackageName; 161 162 keySetData = new PackageKeySetData(base.keySetData); 163 164 } 165 init(File codePath, File resourcePath, String legacyNativeLibraryPathString, String primaryCpuAbiString, String secondaryCpuAbiString, String cpuAbiOverrideString, int pVersionCode)166 void init(File codePath, File resourcePath, String legacyNativeLibraryPathString, 167 String primaryCpuAbiString, String secondaryCpuAbiString, 168 String cpuAbiOverrideString, int pVersionCode) { 169 this.codePath = codePath; 170 this.codePathString = codePath.toString(); 171 this.resourcePath = resourcePath; 172 this.resourcePathString = resourcePath.toString(); 173 this.legacyNativeLibraryPathString = legacyNativeLibraryPathString; 174 this.primaryCpuAbiString = primaryCpuAbiString; 175 this.secondaryCpuAbiString = secondaryCpuAbiString; 176 this.cpuAbiOverrideString = cpuAbiOverrideString; 177 this.versionCode = pVersionCode; 178 } 179 setInstallerPackageName(String packageName)180 public void setInstallerPackageName(String packageName) { 181 installerPackageName = packageName; 182 } 183 getInstallerPackageName()184 String getInstallerPackageName() { 185 return installerPackageName; 186 } 187 setInstallStatus(int newStatus)188 public void setInstallStatus(int newStatus) { 189 installStatus = newStatus; 190 } 191 getInstallStatus()192 public int getInstallStatus() { 193 return installStatus; 194 } 195 setTimeStamp(long newStamp)196 public void setTimeStamp(long newStamp) { 197 timeStamp = newStamp; 198 } 199 200 /** 201 * Make a shallow copy of this package settings. 202 */ copyFrom(PackageSettingBase base)203 public void copyFrom(PackageSettingBase base) { 204 grantedPermissions = base.grantedPermissions; 205 gids = base.gids; 206 207 primaryCpuAbiString = base.primaryCpuAbiString; 208 secondaryCpuAbiString = base.secondaryCpuAbiString; 209 cpuAbiOverrideString = base.cpuAbiOverrideString; 210 timeStamp = base.timeStamp; 211 firstInstallTime = base.firstInstallTime; 212 lastUpdateTime = base.lastUpdateTime; 213 signatures = base.signatures; 214 permissionsFixed = base.permissionsFixed; 215 haveGids = base.haveGids; 216 userState.clear(); 217 for (int i=0; i<base.userState.size(); i++) { 218 userState.put(base.userState.keyAt(i), base.userState.valueAt(i)); 219 } 220 installStatus = base.installStatus; 221 keySetData = base.keySetData; 222 } 223 modifyUserState(int userId)224 private PackageUserState modifyUserState(int userId) { 225 PackageUserState state = userState.get(userId); 226 if (state == null) { 227 state = new PackageUserState(); 228 userState.put(userId, state); 229 } 230 return state; 231 } 232 readUserState(int userId)233 public PackageUserState readUserState(int userId) { 234 PackageUserState state = userState.get(userId); 235 if (state != null) { 236 return state; 237 } 238 return DEFAULT_USER_STATE; 239 } 240 setEnabled(int state, int userId, String callingPackage)241 void setEnabled(int state, int userId, String callingPackage) { 242 PackageUserState st = modifyUserState(userId); 243 st.enabled = state; 244 st.lastDisableAppCaller = callingPackage; 245 } 246 getEnabled(int userId)247 int getEnabled(int userId) { 248 return readUserState(userId).enabled; 249 } 250 getLastDisabledAppCaller(int userId)251 String getLastDisabledAppCaller(int userId) { 252 return readUserState(userId).lastDisableAppCaller; 253 } 254 setInstalled(boolean inst, int userId)255 void setInstalled(boolean inst, int userId) { 256 modifyUserState(userId).installed = inst; 257 } 258 getInstalled(int userId)259 boolean getInstalled(int userId) { 260 return readUserState(userId).installed; 261 } 262 isAnyInstalled(int[] users)263 boolean isAnyInstalled(int[] users) { 264 for (int user: users) { 265 if (readUserState(user).installed) { 266 return true; 267 } 268 } 269 return false; 270 } 271 queryInstalledUsers(int[] users, boolean installed)272 int[] queryInstalledUsers(int[] users, boolean installed) { 273 int num = 0; 274 for (int user : users) { 275 if (getInstalled(user) == installed) { 276 num++; 277 } 278 } 279 int[] res = new int[num]; 280 num = 0; 281 for (int user : users) { 282 if (getInstalled(user) == installed) { 283 res[num] = user; 284 num++; 285 } 286 } 287 return res; 288 } 289 getStopped(int userId)290 boolean getStopped(int userId) { 291 return readUserState(userId).stopped; 292 } 293 setStopped(boolean stop, int userId)294 void setStopped(boolean stop, int userId) { 295 modifyUserState(userId).stopped = stop; 296 } 297 getNotLaunched(int userId)298 boolean getNotLaunched(int userId) { 299 return readUserState(userId).notLaunched; 300 } 301 setNotLaunched(boolean stop, int userId)302 void setNotLaunched(boolean stop, int userId) { 303 modifyUserState(userId).notLaunched = stop; 304 } 305 getHidden(int userId)306 boolean getHidden(int userId) { 307 return readUserState(userId).hidden; 308 } 309 setHidden(boolean hidden, int userId)310 void setHidden(boolean hidden, int userId) { 311 modifyUserState(userId).hidden = hidden; 312 } 313 getBlockUninstall(int userId)314 boolean getBlockUninstall(int userId) { 315 return readUserState(userId).blockUninstall; 316 } 317 setBlockUninstall(boolean blockUninstall, int userId)318 void setBlockUninstall(boolean blockUninstall, int userId) { 319 modifyUserState(userId).blockUninstall = blockUninstall; 320 } 321 setUserState(int userId, int enabled, boolean installed, boolean stopped, boolean notLaunched, boolean hidden, String lastDisableAppCaller, ArraySet<String> enabledComponents, ArraySet<String> disabledComponents, boolean blockUninstall)322 void setUserState(int userId, int enabled, boolean installed, boolean stopped, 323 boolean notLaunched, boolean hidden, 324 String lastDisableAppCaller, ArraySet<String> enabledComponents, 325 ArraySet<String> disabledComponents, boolean blockUninstall) { 326 PackageUserState state = modifyUserState(userId); 327 state.enabled = enabled; 328 state.installed = installed; 329 state.stopped = stopped; 330 state.notLaunched = notLaunched; 331 state.hidden = hidden; 332 state.lastDisableAppCaller = lastDisableAppCaller; 333 state.enabledComponents = enabledComponents; 334 state.disabledComponents = disabledComponents; 335 state.blockUninstall = blockUninstall; 336 } 337 getEnabledComponents(int userId)338 ArraySet<String> getEnabledComponents(int userId) { 339 return readUserState(userId).enabledComponents; 340 } 341 getDisabledComponents(int userId)342 ArraySet<String> getDisabledComponents(int userId) { 343 return readUserState(userId).disabledComponents; 344 } 345 setEnabledComponents(ArraySet<String> components, int userId)346 void setEnabledComponents(ArraySet<String> components, int userId) { 347 modifyUserState(userId).enabledComponents = components; 348 } 349 setDisabledComponents(ArraySet<String> components, int userId)350 void setDisabledComponents(ArraySet<String> components, int userId) { 351 modifyUserState(userId).disabledComponents = components; 352 } 353 setEnabledComponentsCopy(ArraySet<String> components, int userId)354 void setEnabledComponentsCopy(ArraySet<String> components, int userId) { 355 modifyUserState(userId).enabledComponents = components != null 356 ? new ArraySet<String>(components) : null; 357 } 358 setDisabledComponentsCopy(ArraySet<String> components, int userId)359 void setDisabledComponentsCopy(ArraySet<String> components, int userId) { 360 modifyUserState(userId).disabledComponents = components != null 361 ? new ArraySet<String>(components) : null; 362 } 363 modifyUserStateComponents(int userId, boolean disabled, boolean enabled)364 PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) { 365 PackageUserState state = modifyUserState(userId); 366 if (disabled && state.disabledComponents == null) { 367 state.disabledComponents = new ArraySet<String>(1); 368 } 369 if (enabled && state.enabledComponents == null) { 370 state.enabledComponents = new ArraySet<String>(1); 371 } 372 return state; 373 } 374 addDisabledComponent(String componentClassName, int userId)375 void addDisabledComponent(String componentClassName, int userId) { 376 modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName); 377 } 378 addEnabledComponent(String componentClassName, int userId)379 void addEnabledComponent(String componentClassName, int userId) { 380 modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName); 381 } 382 enableComponentLPw(String componentClassName, int userId)383 boolean enableComponentLPw(String componentClassName, int userId) { 384 PackageUserState state = modifyUserStateComponents(userId, false, true); 385 boolean changed = state.disabledComponents != null 386 ? state.disabledComponents.remove(componentClassName) : false; 387 changed |= state.enabledComponents.add(componentClassName); 388 return changed; 389 } 390 disableComponentLPw(String componentClassName, int userId)391 boolean disableComponentLPw(String componentClassName, int userId) { 392 PackageUserState state = modifyUserStateComponents(userId, true, false); 393 boolean changed = state.enabledComponents != null 394 ? state.enabledComponents.remove(componentClassName) : false; 395 changed |= state.disabledComponents.add(componentClassName); 396 return changed; 397 } 398 restoreComponentLPw(String componentClassName, int userId)399 boolean restoreComponentLPw(String componentClassName, int userId) { 400 PackageUserState state = modifyUserStateComponents(userId, true, true); 401 boolean changed = state.disabledComponents != null 402 ? state.disabledComponents.remove(componentClassName) : false; 403 changed |= state.enabledComponents != null 404 ? state.enabledComponents.remove(componentClassName) : false; 405 return changed; 406 } 407 getCurrentEnabledStateLPr(String componentName, int userId)408 int getCurrentEnabledStateLPr(String componentName, int userId) { 409 PackageUserState state = readUserState(userId); 410 if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) { 411 return COMPONENT_ENABLED_STATE_ENABLED; 412 } else if (state.disabledComponents != null 413 && state.disabledComponents.contains(componentName)) { 414 return COMPONENT_ENABLED_STATE_DISABLED; 415 } else { 416 return COMPONENT_ENABLED_STATE_DEFAULT; 417 } 418 } 419 removeUser(int userId)420 void removeUser(int userId) { 421 userState.delete(userId); 422 } 423 } 424