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