blob: 6d31f0e81db1310cf56c5c3a4fa249bf96f838ec [file] [log] [blame]
Kenny Rootcf0b38c2011-03-22 14:17:59 -07001/*
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
Dianne Hackborn7767eac2012-08-23 18:25:40 -070023import android.content.pm.PackageUserState;
24import android.content.pm.UserInfo;
Amith Yamasani483f3b02012-03-13 16:08:00 -070025import android.util.SparseArray;
Kenny Rootcf0b38c2011-03-22 14:17:59 -070026
27import java.io.File;
28import java.util.HashSet;
Dianne Hackborn7767eac2012-08-23 18:25:40 -070029import java.util.List;
Kenny Rootcf0b38c2011-03-22 14:17:59 -070030
31/**
32 * Settings base class for pending and resolved classes.
33 */
34class PackageSettingBase extends GrantedPermissions {
35 /**
36 * Indicates the state of installation. Used by PackageManager to figure out
37 * incomplete installations. Say a package is being installed (the state is
38 * set to PKG_INSTALL_INCOMPLETE) and remains so till the package
39 * installation is successful or unsuccessful in which case the
40 * PackageManager will no longer maintain state information associated with
41 * the package. If some exception(like device freeze or battery being pulled
42 * out) occurs during installation of a package, the PackageManager needs
43 * this information to clean up the previously failed installation.
44 */
45 static final int PKG_INSTALL_COMPLETE = 1;
46 static final int PKG_INSTALL_INCOMPLETE = 0;
47
48 final String name;
49 final String realName;
50 File codePath;
51 String codePathString;
52 File resourcePath;
53 String resourcePathString;
54 String nativeLibraryPathString;
55 long timeStamp;
56 long firstInstallTime;
57 long lastUpdateTime;
58 int versionCode;
59
60 boolean uidError;
61
62 PackageSignatures signatures = new PackageSignatures();
63
64 boolean permissionsFixed;
65 boolean haveGids;
66
Dianne Hackborn7767eac2012-08-23 18:25:40 -070067 private static final PackageUserState DEFAULT_USER_STATE = new PackageUserState();
68
Kenny Rootcf0b38c2011-03-22 14:17:59 -070069 // Whether this package is currently stopped, thus can not be
70 // started until explicitly launched by the user.
Dianne Hackborn7767eac2012-08-23 18:25:40 -070071 private final SparseArray<PackageUserState> userState = new SparseArray<PackageUserState>();
Amith Yamasani483f3b02012-03-13 16:08:00 -070072
Kenny Rootcf0b38c2011-03-22 14:17:59 -070073 int installStatus = PKG_INSTALL_COMPLETE;
74
75 PackageSettingBase origPackage;
Amith Yamasani483f3b02012-03-13 16:08:00 -070076
Kenny Rootcf0b38c2011-03-22 14:17:59 -070077 /* package name of the app that installed this package */
78 String installerPackageName;
79 PackageSettingBase(String name, String realName, File codePath, File resourcePath,
80 String nativeLibraryPathString, int pVersionCode, int pkgFlags) {
81 super(pkgFlags);
82 this.name = name;
83 this.realName = realName;
84 init(codePath, resourcePath, nativeLibraryPathString, pVersionCode);
85 }
86
87 /**
88 * New instance of PackageSetting with one-level-deep cloning.
89 */
90 @SuppressWarnings("unchecked")
91 PackageSettingBase(PackageSettingBase base) {
92 super(base);
93
94 name = base.name;
95 realName = base.realName;
96 codePath = base.codePath;
97 codePathString = base.codePathString;
98 resourcePath = base.resourcePath;
99 resourcePathString = base.resourcePathString;
100 nativeLibraryPathString = base.nativeLibraryPathString;
101 timeStamp = base.timeStamp;
102 firstInstallTime = base.firstInstallTime;
103 lastUpdateTime = base.lastUpdateTime;
104 versionCode = base.versionCode;
105
106 uidError = base.uidError;
107
108 signatures = new PackageSignatures(base.signatures);
109
110 permissionsFixed = base.permissionsFixed;
111 haveGids = base.haveGids;
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700112 userState.clear();
113 for (int i=0; i<base.userState.size(); i++) {
114 userState.put(base.userState.keyAt(i),
115 new PackageUserState(base.userState.valueAt(i)));
116 }
Kenny Rootcf0b38c2011-03-22 14:17:59 -0700117 installStatus = base.installStatus;
118
119 origPackage = base.origPackage;
120
121 installerPackageName = base.installerPackageName;
122 }
123
124 void init(File codePath, File resourcePath, String nativeLibraryPathString,
125 int pVersionCode) {
126 this.codePath = codePath;
127 this.codePathString = codePath.toString();
128 this.resourcePath = resourcePath;
129 this.resourcePathString = resourcePath.toString();
130 this.nativeLibraryPathString = nativeLibraryPathString;
131 this.versionCode = pVersionCode;
132 }
133
134 public void setInstallerPackageName(String packageName) {
135 installerPackageName = packageName;
136 }
137
138 String getInstallerPackageName() {
139 return installerPackageName;
140 }
141
142 public void setInstallStatus(int newStatus) {
143 installStatus = newStatus;
144 }
145
146 public int getInstallStatus() {
147 return installStatus;
148 }
149
150 public void setTimeStamp(long newStamp) {
151 timeStamp = newStamp;
152 }
153
154 /**
155 * Make a shallow copy of this package settings.
156 */
157 public void copyFrom(PackageSettingBase base) {
158 grantedPermissions = base.grantedPermissions;
159 gids = base.gids;
160
161 timeStamp = base.timeStamp;
162 firstInstallTime = base.firstInstallTime;
163 lastUpdateTime = base.lastUpdateTime;
164 signatures = base.signatures;
165 permissionsFixed = base.permissionsFixed;
166 haveGids = base.haveGids;
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700167 userState.clear();
168 for (int i=0; i<base.userState.size(); i++) {
169 userState.put(base.userState.keyAt(i), base.userState.valueAt(i));
170 }
Kenny Rootcf0b38c2011-03-22 14:17:59 -0700171 installStatus = base.installStatus;
172 }
173
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700174 private PackageUserState modifyUserState(int userId) {
175 PackageUserState state = userState.get(userId);
176 if (state == null) {
177 state = new PackageUserState();
178 userState.put(userId, state);
179 }
180 return state;
181 }
182
183 public PackageUserState readUserState(int userId) {
184 PackageUserState state = userState.get(userId);
185 return state != null ? state : DEFAULT_USER_STATE;
186 }
187
Amith Yamasani483f3b02012-03-13 16:08:00 -0700188 void setEnabled(int state, int userId) {
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700189 modifyUserState(userId).enabled = state;
Amith Yamasani483f3b02012-03-13 16:08:00 -0700190 }
191
192 int getEnabled(int userId) {
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700193 return readUserState(userId).enabled;
194 }
195
196 void setInstalled(boolean inst, int userId) {
197 modifyUserState(userId).installed = inst;
198 }
199
200 boolean getInstalled(int userId) {
201 return readUserState(userId).installed;
202 }
203
204 boolean isAnyInstalled(int[] users) {
205 for (int user: users) {
206 if (readUserState(user).installed) {
207 return true;
208 }
209 }
210 return false;
211 }
212
213 int[] getInstalledUsers(int[] users) {
214 int num = 0;
215 for (int user : users) {
216 if (getInstalled(user)) {
217 num++;
218 }
219 }
220 int[] res = new int[num];
221 num = 0;
222 for (int user : users) {
223 if (getInstalled(user)) {
224 res[num] = user;
225 num++;
226 }
227 }
228 return res;
Amith Yamasani483f3b02012-03-13 16:08:00 -0700229 }
230
231 boolean getStopped(int userId) {
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700232 return readUserState(userId).stopped;
Amith Yamasani483f3b02012-03-13 16:08:00 -0700233 }
234
235 void setStopped(boolean stop, int userId) {
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700236 modifyUserState(userId).stopped = stop;
Amith Yamasani483f3b02012-03-13 16:08:00 -0700237 }
238
239 boolean getNotLaunched(int userId) {
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700240 return readUserState(userId).notLaunched;
Amith Yamasani483f3b02012-03-13 16:08:00 -0700241 }
242
243 void setNotLaunched(boolean stop, int userId) {
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700244 modifyUserState(userId).notLaunched = stop;
245 }
246
247 void setUserState(int userId, int enabled, boolean installed, boolean stopped,
248 boolean notLaunched, HashSet<String> enabledComponents,
249 HashSet<String> disabledComponents) {
250 PackageUserState state = modifyUserState(userId);
251 state.enabled = enabled;
252 state.installed = installed;
253 state.stopped = stopped;
254 state.notLaunched = notLaunched;
255 state.enabledComponents = enabledComponents;
256 state.disabledComponents = disabledComponents;
Amith Yamasani483f3b02012-03-13 16:08:00 -0700257 }
258
259 HashSet<String> getEnabledComponents(int userId) {
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700260 return readUserState(userId).enabledComponents;
Amith Yamasani483f3b02012-03-13 16:08:00 -0700261 }
262
263 HashSet<String> getDisabledComponents(int userId) {
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700264 return readUserState(userId).disabledComponents;
Amith Yamasani483f3b02012-03-13 16:08:00 -0700265 }
266
267 void setEnabledComponents(HashSet<String> components, int userId) {
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700268 modifyUserState(userId).enabledComponents = components;
Amith Yamasani483f3b02012-03-13 16:08:00 -0700269 }
270
271 void setDisabledComponents(HashSet<String> components, int userId) {
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700272 modifyUserState(userId).disabledComponents = components;
Amith Yamasani483f3b02012-03-13 16:08:00 -0700273 }
274
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700275 void setEnabledComponentsCopy(HashSet<String> components, int userId) {
276 modifyUserState(userId).enabledComponents = components != null
277 ? new HashSet<String>(components) : null;
278 }
279
280 void setDisabledComponentsCopy(HashSet<String> components, int userId) {
281 modifyUserState(userId).disabledComponents = components != null
282 ? new HashSet<String>(components) : null;
283 }
284
285 PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) {
286 PackageUserState state = modifyUserState(userId);
287 if (disabled && state.disabledComponents == null) {
288 state.disabledComponents = new HashSet<String>(1);
Amith Yamasani483f3b02012-03-13 16:08:00 -0700289 }
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700290 if (enabled && state.enabledComponents == null) {
291 state.enabledComponents = new HashSet<String>(1);
292 }
293 return state;
Amith Yamasani483f3b02012-03-13 16:08:00 -0700294 }
295
296 void addDisabledComponent(String componentClassName, int userId) {
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700297 modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName);
Amith Yamasani483f3b02012-03-13 16:08:00 -0700298 }
299
300 void addEnabledComponent(String componentClassName, int userId) {
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700301 modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName);
Amith Yamasani483f3b02012-03-13 16:08:00 -0700302 }
303
304 boolean enableComponentLPw(String componentClassName, int userId) {
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700305 PackageUserState state = modifyUserStateComponents(userId, false, true);
306 boolean changed = state.disabledComponents != null
307 ? state.disabledComponents.remove(componentClassName) : false;
308 changed |= state.enabledComponents.add(componentClassName);
Kenny Rootcf0b38c2011-03-22 14:17:59 -0700309 return changed;
310 }
311
Amith Yamasani483f3b02012-03-13 16:08:00 -0700312 boolean disableComponentLPw(String componentClassName, int userId) {
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700313 PackageUserState state = modifyUserStateComponents(userId, true, false);
314 boolean changed = state.enabledComponents != null
315 ? state.enabledComponents.remove(componentClassName) : false;
316 changed |= state.disabledComponents.add(componentClassName);
Kenny Rootcf0b38c2011-03-22 14:17:59 -0700317 return changed;
318 }
319
Amith Yamasani483f3b02012-03-13 16:08:00 -0700320 boolean restoreComponentLPw(String componentClassName, int userId) {
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700321 PackageUserState state = modifyUserStateComponents(userId, true, true);
322 boolean changed = state.disabledComponents != null
323 ? state.disabledComponents.remove(componentClassName) : false;
324 changed |= state.enabledComponents != null
325 ? state.enabledComponents.remove(componentClassName) : false;
Kenny Rootcf0b38c2011-03-22 14:17:59 -0700326 return changed;
327 }
328
Amith Yamasani483f3b02012-03-13 16:08:00 -0700329 int getCurrentEnabledStateLPr(String componentName, int userId) {
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700330 PackageUserState state = readUserState(userId);
331 if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) {
Kenny Rootcf0b38c2011-03-22 14:17:59 -0700332 return COMPONENT_ENABLED_STATE_ENABLED;
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700333 } else if (state.disabledComponents != null
334 && state.disabledComponents.contains(componentName)) {
Kenny Rootcf0b38c2011-03-22 14:17:59 -0700335 return COMPONENT_ENABLED_STATE_DISABLED;
336 } else {
337 return COMPONENT_ENABLED_STATE_DEFAULT;
338 }
339 }
Amith Yamasani13593602012-03-22 16:16:17 -0700340
341 void removeUser(int userId) {
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700342 userState.delete(userId);
Amith Yamasani13593602012-03-22 16:16:17 -0700343 }
Amith Yamasani483f3b02012-03-13 16:08:00 -0700344}