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