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; 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") 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 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 180 public void setInstallerPackageName(String packageName) { 181 installerPackageName = packageName; 182 } 183 184 String getInstallerPackageName() { 185 return installerPackageName; 186 } 187 188 public void setInstallStatus(int newStatus) { 189 installStatus = newStatus; 190 } 191 192 public int getInstallStatus() { 193 return installStatus; 194 } 195 196 public void setTimeStamp(long newStamp) { 197 timeStamp = newStamp; 198 } 199 200 /** 201 * Make a shallow copy of this package settings. 202 */ 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 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 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 241 void setEnabled(int state, int userId, String callingPackage) { 242 PackageUserState st = modifyUserState(userId); 243 st.enabled = state; 244 st.lastDisableAppCaller = callingPackage; 245 } 246 247 int getEnabled(int userId) { 248 return readUserState(userId).enabled; 249 } 250 251 String getLastDisabledAppCaller(int userId) { 252 return readUserState(userId).lastDisableAppCaller; 253 } 254 255 void setInstalled(boolean inst, int userId) { 256 modifyUserState(userId).installed = inst; 257 } 258 259 boolean getInstalled(int userId) { 260 return readUserState(userId).installed; 261 } 262 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 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 290 boolean getStopped(int userId) { 291 return readUserState(userId).stopped; 292 } 293 294 void setStopped(boolean stop, int userId) { 295 modifyUserState(userId).stopped = stop; 296 } 297 298 boolean getNotLaunched(int userId) { 299 return readUserState(userId).notLaunched; 300 } 301 302 void setNotLaunched(boolean stop, int userId) { 303 modifyUserState(userId).notLaunched = stop; 304 } 305 306 boolean getHidden(int userId) { 307 return readUserState(userId).hidden; 308 } 309 310 void setHidden(boolean hidden, int userId) { 311 modifyUserState(userId).hidden = hidden; 312 } 313 314 boolean getBlockUninstall(int userId) { 315 return readUserState(userId).blockUninstall; 316 } 317 318 void setBlockUninstall(boolean blockUninstall, int userId) { 319 modifyUserState(userId).blockUninstall = blockUninstall; 320 } 321 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 338 ArraySet<String> getEnabledComponents(int userId) { 339 return readUserState(userId).enabledComponents; 340 } 341 342 ArraySet<String> getDisabledComponents(int userId) { 343 return readUserState(userId).disabledComponents; 344 } 345 346 void setEnabledComponents(ArraySet<String> components, int userId) { 347 modifyUserState(userId).enabledComponents = components; 348 } 349 350 void setDisabledComponents(ArraySet<String> components, int userId) { 351 modifyUserState(userId).disabledComponents = components; 352 } 353 354 void setEnabledComponentsCopy(ArraySet<String> components, int userId) { 355 modifyUserState(userId).enabledComponents = components != null 356 ? new ArraySet<String>(components) : null; 357 } 358 359 void setDisabledComponentsCopy(ArraySet<String> components, int userId) { 360 modifyUserState(userId).disabledComponents = components != null 361 ? new ArraySet<String>(components) : null; 362 } 363 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 375 void addDisabledComponent(String componentClassName, int userId) { 376 modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName); 377 } 378 379 void addEnabledComponent(String componentClassName, int userId) { 380 modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName); 381 } 382 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 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 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 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 420 void removeUser(int userId) { 421 userState.delete(userId); 422 } 423 } 424