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