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