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.util.SparseArray; 24 import android.util.SparseIntArray; 25 26 import java.io.File; 27 import java.util.HashSet; 28 29 /** 30 * Settings base class for pending and resolved classes. 31 */ 32 class 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 File codePath; 49 String codePathString; 50 File resourcePath; 51 String resourcePathString; 52 String nativeLibraryPathString; 53 long timeStamp; 54 long firstInstallTime; 55 long lastUpdateTime; 56 int versionCode; 57 58 boolean uidError; 59 60 PackageSignatures signatures = new PackageSignatures(); 61 62 boolean permissionsFixed; 63 boolean haveGids; 64 65 // Whether this package is currently stopped, thus can not be 66 // started until explicitly launched by the user. 67 private SparseArray<Boolean> stopped = new SparseArray<Boolean>(); 68 69 // Set to true if we have never launched this app. 70 private SparseArray<Boolean> notLaunched = new SparseArray<Boolean>(); 71 72 /* Explicitly disabled components */ 73 private SparseArray<HashSet<String>> disabledComponents = new SparseArray<HashSet<String>>(); 74 /* Explicitly enabled components */ 75 private SparseArray<HashSet<String>> enabledComponents = new SparseArray<HashSet<String>>(); 76 /* Enabled state */ 77 private SparseIntArray enabled = new SparseIntArray(); 78 79 int installStatus = PKG_INSTALL_COMPLETE; 80 81 PackageSettingBase origPackage; 82 83 /* package name of the app that installed this package */ 84 String installerPackageName; 85 PackageSettingBase(String name, String realName, File codePath, File resourcePath, 86 String nativeLibraryPathString, int pVersionCode, int pkgFlags) { 87 super(pkgFlags); 88 this.name = name; 89 this.realName = realName; 90 init(codePath, resourcePath, nativeLibraryPathString, pVersionCode); 91 } 92 93 /** 94 * New instance of PackageSetting with one-level-deep cloning. 95 */ 96 @SuppressWarnings("unchecked") 97 PackageSettingBase(PackageSettingBase base) { 98 super(base); 99 100 name = base.name; 101 realName = base.realName; 102 codePath = base.codePath; 103 codePathString = base.codePathString; 104 resourcePath = base.resourcePath; 105 resourcePathString = base.resourcePathString; 106 nativeLibraryPathString = base.nativeLibraryPathString; 107 timeStamp = base.timeStamp; 108 firstInstallTime = base.firstInstallTime; 109 lastUpdateTime = base.lastUpdateTime; 110 versionCode = base.versionCode; 111 112 uidError = base.uidError; 113 114 signatures = new PackageSignatures(base.signatures); 115 116 permissionsFixed = base.permissionsFixed; 117 haveGids = base.haveGids; 118 notLaunched = base.notLaunched; 119 120 disabledComponents = (SparseArray<HashSet<String>>) base.disabledComponents.clone(); 121 enabledComponents = (SparseArray<HashSet<String>>) base.enabledComponents.clone(); 122 enabled = (SparseIntArray) base.enabled.clone(); 123 stopped = (SparseArray<Boolean>) base.stopped.clone(); 124 installStatus = base.installStatus; 125 126 origPackage = base.origPackage; 127 128 installerPackageName = base.installerPackageName; 129 } 130 131 void init(File codePath, File resourcePath, String nativeLibraryPathString, 132 int pVersionCode) { 133 this.codePath = codePath; 134 this.codePathString = codePath.toString(); 135 this.resourcePath = resourcePath; 136 this.resourcePathString = resourcePath.toString(); 137 this.nativeLibraryPathString = nativeLibraryPathString; 138 this.versionCode = pVersionCode; 139 } 140 141 public void setInstallerPackageName(String packageName) { 142 installerPackageName = packageName; 143 } 144 145 String getInstallerPackageName() { 146 return installerPackageName; 147 } 148 149 public void setInstallStatus(int newStatus) { 150 installStatus = newStatus; 151 } 152 153 public int getInstallStatus() { 154 return installStatus; 155 } 156 157 public void setTimeStamp(long newStamp) { 158 timeStamp = newStamp; 159 } 160 161 /** 162 * Make a shallow copy of this package settings. 163 */ 164 public void copyFrom(PackageSettingBase base) { 165 grantedPermissions = base.grantedPermissions; 166 gids = base.gids; 167 168 timeStamp = base.timeStamp; 169 firstInstallTime = base.firstInstallTime; 170 lastUpdateTime = base.lastUpdateTime; 171 signatures = base.signatures; 172 permissionsFixed = base.permissionsFixed; 173 haveGids = base.haveGids; 174 stopped = base.stopped; 175 notLaunched = base.notLaunched; 176 disabledComponents = base.disabledComponents; 177 enabledComponents = base.enabledComponents; 178 enabled = base.enabled; 179 installStatus = base.installStatus; 180 } 181 182 void setEnabled(int state, int userId) { 183 enabled.put(userId, state); 184 } 185 186 int getEnabled(int userId) { 187 return enabled.get(userId, COMPONENT_ENABLED_STATE_DEFAULT); 188 } 189 190 boolean getStopped(int userId) { 191 return stopped.get(userId, false); 192 } 193 194 void setStopped(boolean stop, int userId) { 195 stopped.put(userId, stop); 196 } 197 198 boolean getNotLaunched(int userId) { 199 return notLaunched.get(userId, false); 200 } 201 202 void setNotLaunched(boolean stop, int userId) { 203 notLaunched.put(userId, stop); 204 } 205 206 HashSet<String> getEnabledComponents(int userId) { 207 return getComponentHashSet(enabledComponents, userId); 208 } 209 210 HashSet<String> getDisabledComponents(int userId) { 211 return getComponentHashSet(disabledComponents, userId); 212 } 213 214 void setEnabledComponents(HashSet<String> components, int userId) { 215 enabledComponents.put(userId, components); 216 } 217 218 void setDisabledComponents(HashSet<String> components, int userId) { 219 disabledComponents.put(userId, components); 220 } 221 222 private HashSet<String> getComponentHashSet(SparseArray<HashSet<String>> setArray, int userId) { 223 HashSet<String> set = setArray.get(userId); 224 if (set == null) { 225 set = new HashSet<String>(1); 226 setArray.put(userId, set); 227 } 228 return set; 229 } 230 231 void addDisabledComponent(String componentClassName, int userId) { 232 HashSet<String> disabled = getComponentHashSet(disabledComponents, userId); 233 disabled.add(componentClassName); 234 } 235 236 void addEnabledComponent(String componentClassName, int userId) { 237 HashSet<String> enabled = getComponentHashSet(enabledComponents, userId); 238 enabled.add(componentClassName); 239 } 240 241 boolean enableComponentLPw(String componentClassName, int userId) { 242 HashSet<String> disabled = getComponentHashSet(disabledComponents, userId); 243 HashSet<String> enabled = getComponentHashSet(enabledComponents, userId); 244 boolean changed = disabled.remove(componentClassName); 245 changed |= enabled.add(componentClassName); 246 return changed; 247 } 248 249 boolean disableComponentLPw(String componentClassName, int userId) { 250 HashSet<String> disabled = getComponentHashSet(disabledComponents, userId); 251 HashSet<String> enabled = getComponentHashSet(enabledComponents, userId); 252 boolean changed = enabled.remove(componentClassName); 253 changed |= disabled.add(componentClassName); 254 return changed; 255 } 256 257 boolean restoreComponentLPw(String componentClassName, int userId) { 258 HashSet<String> disabled = getComponentHashSet(disabledComponents, userId); 259 HashSet<String> enabled = getComponentHashSet(enabledComponents, userId); 260 boolean changed = enabled.remove(componentClassName); 261 changed |= disabled.remove(componentClassName); 262 return changed; 263 } 264 265 int getCurrentEnabledStateLPr(String componentName, int userId) { 266 HashSet<String> disabled = getComponentHashSet(disabledComponents, userId); 267 HashSet<String> enabled = getComponentHashSet(enabledComponents, userId); 268 if (enabled.contains(componentName)) { 269 return COMPONENT_ENABLED_STATE_ENABLED; 270 } else if (disabled.contains(componentName)) { 271 return COMPONENT_ENABLED_STATE_DISABLED; 272 } else { 273 return COMPONENT_ENABLED_STATE_DEFAULT; 274 } 275 } 276 277 void removeUser(int userId) { 278 enabled.delete(userId); 279 stopped.delete(userId); 280 enabledComponents.delete(userId); 281 disabledComponents.delete(userId); 282 notLaunched.delete(userId); 283 } 284 285 } 286