PackageSettingBase.java revision ff110bd61a69f7ed8602ae14b27f7befec76b2e7
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 17package com.android.server.pm; 18 19import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 20import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; 21import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 22 23import android.content.pm.PackageUserState; 24import android.util.SparseArray; 25 26import java.io.File; 27import java.util.HashSet; 28 29/** 30 * Settings base class for pending and resolved classes. 31 */ 32class 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 for legacy apps are unpacked. 61 * Will be set to {@code null} for newer installs, where the path can be 62 * derived from {@link #codePath} unambiguously. 63 */ 64 String legacyNativeLibraryPathString; 65 66 String primaryCpuAbiString; 67 String secondaryCpuAbiString; 68 long timeStamp; 69 long firstInstallTime; 70 long lastUpdateTime; 71 int versionCode; 72 73 boolean uidError; 74 75 PackageSignatures signatures = new PackageSignatures(); 76 77 boolean permissionsFixed; 78 boolean haveGids; 79 80 PackageKeySetData keySetData = new PackageKeySetData(); 81 82 private static final PackageUserState DEFAULT_USER_STATE = new PackageUserState(); 83 84 // Whether this package is currently stopped, thus can not be 85 // started until explicitly launched by the user. 86 private final SparseArray<PackageUserState> userState = new SparseArray<PackageUserState>(); 87 88 int installStatus = PKG_INSTALL_COMPLETE; 89 90 PackageSettingBase origPackage; 91 92 /* package name of the app that installed this package */ 93 String installerPackageName; 94 PackageSettingBase(String name, String realName, File codePath, File resourcePath, 95 String legacyNativeLibraryPathString, String primaryCpuAbiString, 96 String secondaryCpuAbiString, int pVersionCode, int pkgFlags) { 97 super(pkgFlags); 98 this.name = name; 99 this.realName = realName; 100 init(codePath, resourcePath, legacyNativeLibraryPathString, primaryCpuAbiString, 101 secondaryCpuAbiString, pVersionCode); 102 } 103 104 /** 105 * New instance of PackageSetting with one-level-deep cloning. 106 */ 107 @SuppressWarnings("unchecked") 108 PackageSettingBase(PackageSettingBase base) { 109 super(base); 110 111 name = base.name; 112 realName = base.realName; 113 codePath = base.codePath; 114 codePathString = base.codePathString; 115 resourcePath = base.resourcePath; 116 resourcePathString = base.resourcePathString; 117 legacyNativeLibraryPathString = base.legacyNativeLibraryPathString; 118 primaryCpuAbiString = base.primaryCpuAbiString; 119 secondaryCpuAbiString = base.secondaryCpuAbiString; 120 timeStamp = base.timeStamp; 121 firstInstallTime = base.firstInstallTime; 122 lastUpdateTime = base.lastUpdateTime; 123 versionCode = base.versionCode; 124 125 uidError = base.uidError; 126 127 signatures = new PackageSignatures(base.signatures); 128 129 permissionsFixed = base.permissionsFixed; 130 haveGids = base.haveGids; 131 userState.clear(); 132 for (int i=0; i<base.userState.size(); i++) { 133 userState.put(base.userState.keyAt(i), 134 new PackageUserState(base.userState.valueAt(i))); 135 } 136 installStatus = base.installStatus; 137 138 origPackage = base.origPackage; 139 140 installerPackageName = base.installerPackageName; 141 142 keySetData = new PackageKeySetData(base.keySetData); 143 144 } 145 146 void init(File codePath, File resourcePath, String legacyNativeLibraryPathString, 147 String primaryCpuAbiString, String secondaryCpuAbiString, int pVersionCode) { 148 this.codePath = codePath; 149 this.codePathString = codePath.toString(); 150 this.resourcePath = resourcePath; 151 this.resourcePathString = resourcePath.toString(); 152 this.legacyNativeLibraryPathString = legacyNativeLibraryPathString; 153 this.primaryCpuAbiString = primaryCpuAbiString; 154 this.secondaryCpuAbiString = secondaryCpuAbiString; 155 this.versionCode = pVersionCode; 156 } 157 158 public void setInstallerPackageName(String packageName) { 159 installerPackageName = packageName; 160 } 161 162 String getInstallerPackageName() { 163 return installerPackageName; 164 } 165 166 public void setInstallStatus(int newStatus) { 167 installStatus = newStatus; 168 } 169 170 public int getInstallStatus() { 171 return installStatus; 172 } 173 174 public void setTimeStamp(long newStamp) { 175 timeStamp = newStamp; 176 } 177 178 /** 179 * Make a shallow copy of this package settings. 180 */ 181 public void copyFrom(PackageSettingBase base) { 182 grantedPermissions = base.grantedPermissions; 183 gids = base.gids; 184 185 primaryCpuAbiString = base.primaryCpuAbiString; 186 secondaryCpuAbiString = base.secondaryCpuAbiString; 187 timeStamp = base.timeStamp; 188 firstInstallTime = base.firstInstallTime; 189 lastUpdateTime = base.lastUpdateTime; 190 signatures = base.signatures; 191 permissionsFixed = base.permissionsFixed; 192 haveGids = base.haveGids; 193 userState.clear(); 194 for (int i=0; i<base.userState.size(); i++) { 195 userState.put(base.userState.keyAt(i), base.userState.valueAt(i)); 196 } 197 installStatus = base.installStatus; 198 keySetData = base.keySetData; 199 } 200 201 private PackageUserState modifyUserState(int userId) { 202 PackageUserState state = userState.get(userId); 203 if (state == null) { 204 state = new PackageUserState(); 205 userState.put(userId, state); 206 } 207 return state; 208 } 209 210 public PackageUserState readUserState(int userId) { 211 PackageUserState state = userState.get(userId); 212 if (state != null) { 213 return state; 214 } 215 return DEFAULT_USER_STATE; 216 } 217 218 void setEnabled(int state, int userId, String callingPackage) { 219 PackageUserState st = modifyUserState(userId); 220 st.enabled = state; 221 st.lastDisableAppCaller = callingPackage; 222 } 223 224 int getEnabled(int userId) { 225 return readUserState(userId).enabled; 226 } 227 228 String getLastDisabledAppCaller(int userId) { 229 return readUserState(userId).lastDisableAppCaller; 230 } 231 232 void setInstalled(boolean inst, int userId) { 233 modifyUserState(userId).installed = inst; 234 } 235 236 boolean getInstalled(int userId) { 237 return readUserState(userId).installed; 238 } 239 240 boolean isAnyInstalled(int[] users) { 241 for (int user: users) { 242 if (readUserState(user).installed) { 243 return true; 244 } 245 } 246 return false; 247 } 248 249 int[] queryInstalledUsers(int[] users, boolean installed) { 250 int num = 0; 251 for (int user : users) { 252 if (getInstalled(user) == installed) { 253 num++; 254 } 255 } 256 int[] res = new int[num]; 257 num = 0; 258 for (int user : users) { 259 if (getInstalled(user) == installed) { 260 res[num] = user; 261 num++; 262 } 263 } 264 return res; 265 } 266 267 boolean getStopped(int userId) { 268 return readUserState(userId).stopped; 269 } 270 271 void setStopped(boolean stop, int userId) { 272 modifyUserState(userId).stopped = stop; 273 } 274 275 boolean getNotLaunched(int userId) { 276 return readUserState(userId).notLaunched; 277 } 278 279 void setNotLaunched(boolean stop, int userId) { 280 modifyUserState(userId).notLaunched = stop; 281 } 282 283 boolean getBlocked(int userId) { 284 return readUserState(userId).blocked; 285 } 286 287 void setBlocked(boolean blocked, int userId) { 288 modifyUserState(userId).blocked = blocked; 289 } 290 291 boolean getBlockUninstall(int userId) { 292 return readUserState(userId).blockUninstall; 293 } 294 295 void setBlockUninstall(boolean blockUninstall, int userId) { 296 modifyUserState(userId).blockUninstall = blockUninstall; 297 } 298 299 void setUserState(int userId, int enabled, boolean installed, boolean stopped, 300 boolean notLaunched, boolean blocked, 301 String lastDisableAppCaller, HashSet<String> enabledComponents, 302 HashSet<String> disabledComponents, boolean blockUninstall) { 303 PackageUserState state = modifyUserState(userId); 304 state.enabled = enabled; 305 state.installed = installed; 306 state.stopped = stopped; 307 state.notLaunched = notLaunched; 308 state.blocked = blocked; 309 state.lastDisableAppCaller = lastDisableAppCaller; 310 state.enabledComponents = enabledComponents; 311 state.disabledComponents = disabledComponents; 312 state.blockUninstall = blockUninstall; 313 } 314 315 HashSet<String> getEnabledComponents(int userId) { 316 return readUserState(userId).enabledComponents; 317 } 318 319 HashSet<String> getDisabledComponents(int userId) { 320 return readUserState(userId).disabledComponents; 321 } 322 323 void setEnabledComponents(HashSet<String> components, int userId) { 324 modifyUserState(userId).enabledComponents = components; 325 } 326 327 void setDisabledComponents(HashSet<String> components, int userId) { 328 modifyUserState(userId).disabledComponents = components; 329 } 330 331 void setEnabledComponentsCopy(HashSet<String> components, int userId) { 332 modifyUserState(userId).enabledComponents = components != null 333 ? new HashSet<String>(components) : null; 334 } 335 336 void setDisabledComponentsCopy(HashSet<String> components, int userId) { 337 modifyUserState(userId).disabledComponents = components != null 338 ? new HashSet<String>(components) : null; 339 } 340 341 PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) { 342 PackageUserState state = modifyUserState(userId); 343 if (disabled && state.disabledComponents == null) { 344 state.disabledComponents = new HashSet<String>(1); 345 } 346 if (enabled && state.enabledComponents == null) { 347 state.enabledComponents = new HashSet<String>(1); 348 } 349 return state; 350 } 351 352 void addDisabledComponent(String componentClassName, int userId) { 353 modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName); 354 } 355 356 void addEnabledComponent(String componentClassName, int userId) { 357 modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName); 358 } 359 360 boolean enableComponentLPw(String componentClassName, int userId) { 361 PackageUserState state = modifyUserStateComponents(userId, false, true); 362 boolean changed = state.disabledComponents != null 363 ? state.disabledComponents.remove(componentClassName) : false; 364 changed |= state.enabledComponents.add(componentClassName); 365 return changed; 366 } 367 368 boolean disableComponentLPw(String componentClassName, int userId) { 369 PackageUserState state = modifyUserStateComponents(userId, true, false); 370 boolean changed = state.enabledComponents != null 371 ? state.enabledComponents.remove(componentClassName) : false; 372 changed |= state.disabledComponents.add(componentClassName); 373 return changed; 374 } 375 376 boolean restoreComponentLPw(String componentClassName, int userId) { 377 PackageUserState state = modifyUserStateComponents(userId, true, true); 378 boolean changed = state.disabledComponents != null 379 ? state.disabledComponents.remove(componentClassName) : false; 380 changed |= state.enabledComponents != null 381 ? state.enabledComponents.remove(componentClassName) : false; 382 return changed; 383 } 384 385 int getCurrentEnabledStateLPr(String componentName, int userId) { 386 PackageUserState state = readUserState(userId); 387 if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) { 388 return COMPONENT_ENABLED_STATE_ENABLED; 389 } else if (state.disabledComponents != null 390 && state.disabledComponents.contains(componentName)) { 391 return COMPONENT_ENABLED_STATE_DISABLED; 392 } else { 393 return COMPONENT_ENABLED_STATE_DEFAULT; 394 } 395 } 396 397 void removeUser(int userId) { 398 userState.delete(userId); 399 } 400} 401