PackageSettingBase.java revision 9158825f9c41869689d6b1786d7c7aa8bdd524ce
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
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
23import android.content.pm.ApplicationInfo;
24import android.content.pm.PackageUserState;
25import android.content.pm.UserInfo;
26import android.util.SparseArray;
27
28import java.io.File;
29import java.util.HashSet;
30import java.util.List;
31
32/**
33 * Settings base class for pending and resolved classes.
34 */
35class 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