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, String callingPackage) { 193 PackageUserState st = modifyUserState(userId); 194 st.enabled = state; 195 st.lastDisableAppCaller = callingPackage; 196 } 197 198 int getEnabled(int userId) { 199 return readUserState(userId).enabled; 200 } 201 202 String getLastDisabledAppCaller(int userId) { 203 return readUserState(userId).lastDisableAppCaller; 204 } 205 206 void setInstalled(boolean inst, int userId) { 207 modifyUserState(userId).installed = inst; 208 } 209 210 boolean getInstalled(int userId) { 211 return readUserState(userId).installed; 212 } 213 214 boolean isAnyInstalled(int[] users) { 215 for (int user: users) { 216 if (readUserState(user).installed) { 217 return true; 218 } 219 } 220 return false; 221 } 222 223 int[] queryInstalledUsers(int[] users, boolean installed) { 224 int num = 0; 225 for (int user : users) { 226 if (getInstalled(user) == installed) { 227 num++; 228 } 229 } 230 int[] res = new int[num]; 231 num = 0; 232 for (int user : users) { 233 if (getInstalled(user) == installed) { 234 res[num] = user; 235 num++; 236 } 237 } 238 return res; 239 } 240 241 boolean getStopped(int userId) { 242 return readUserState(userId).stopped; 243 } 244 245 void setStopped(boolean stop, int userId) { 246 modifyUserState(userId).stopped = stop; 247 } 248 249 boolean getNotLaunched(int userId) { 250 return readUserState(userId).notLaunched; 251 } 252 253 void setNotLaunched(boolean stop, int userId) { 254 modifyUserState(userId).notLaunched = stop; 255 } 256 257 void setUserState(int userId, int enabled, boolean installed, boolean stopped, 258 boolean notLaunched, String lastDisableAppCaller, HashSet<String> enabledComponents, 259 HashSet<String> disabledComponents) { 260 PackageUserState state = modifyUserState(userId); 261 state.enabled = enabled; 262 state.installed = installed; 263 state.stopped = stopped; 264 state.notLaunched = notLaunched; 265 state.lastDisableAppCaller = lastDisableAppCaller; 266 state.enabledComponents = enabledComponents; 267 state.disabledComponents = disabledComponents; 268 } 269 270 HashSet<String> getEnabledComponents(int userId) { 271 return readUserState(userId).enabledComponents; 272 } 273 274 HashSet<String> getDisabledComponents(int userId) { 275 return readUserState(userId).disabledComponents; 276 } 277 278 void setEnabledComponents(HashSet<String> components, int userId) { 279 modifyUserState(userId).enabledComponents = components; 280 } 281 282 void setDisabledComponents(HashSet<String> components, int userId) { 283 modifyUserState(userId).disabledComponents = components; 284 } 285 286 void setEnabledComponentsCopy(HashSet<String> components, int userId) { 287 modifyUserState(userId).enabledComponents = components != null 288 ? new HashSet<String>(components) : null; 289 } 290 291 void setDisabledComponentsCopy(HashSet<String> components, int userId) { 292 modifyUserState(userId).disabledComponents = components != null 293 ? new HashSet<String>(components) : null; 294 } 295 296 PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) { 297 PackageUserState state = modifyUserState(userId); 298 if (disabled && state.disabledComponents == null) { 299 state.disabledComponents = new HashSet<String>(1); 300 } 301 if (enabled && state.enabledComponents == null) { 302 state.enabledComponents = new HashSet<String>(1); 303 } 304 return state; 305 } 306 307 void addDisabledComponent(String componentClassName, int userId) { 308 modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName); 309 } 310 311 void addEnabledComponent(String componentClassName, int userId) { 312 modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName); 313 } 314 315 boolean enableComponentLPw(String componentClassName, int userId) { 316 PackageUserState state = modifyUserStateComponents(userId, false, true); 317 boolean changed = state.disabledComponents != null 318 ? state.disabledComponents.remove(componentClassName) : false; 319 changed |= state.enabledComponents.add(componentClassName); 320 return changed; 321 } 322 323 boolean disableComponentLPw(String componentClassName, int userId) { 324 PackageUserState state = modifyUserStateComponents(userId, true, false); 325 boolean changed = state.enabledComponents != null 326 ? state.enabledComponents.remove(componentClassName) : false; 327 changed |= state.disabledComponents.add(componentClassName); 328 return changed; 329 } 330 331 boolean restoreComponentLPw(String componentClassName, int userId) { 332 PackageUserState state = modifyUserStateComponents(userId, true, true); 333 boolean changed = state.disabledComponents != null 334 ? state.disabledComponents.remove(componentClassName) : false; 335 changed |= state.enabledComponents != null 336 ? state.enabledComponents.remove(componentClassName) : false; 337 return changed; 338 } 339 340 int getCurrentEnabledStateLPr(String componentName, int userId) { 341 PackageUserState state = readUserState(userId); 342 if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) { 343 return COMPONENT_ENABLED_STATE_ENABLED; 344 } else if (state.disabledComponents != null 345 && state.disabledComponents.contains(componentName)) { 346 return COMPONENT_ENABLED_STATE_DISABLED; 347 } else { 348 return COMPONENT_ENABLED_STATE_DEFAULT; 349 } 350 } 351 352 void removeUser(int userId) { 353 userState.delete(userId); 354 } 355 } 356