PackageSettingBase.java revision 7ee9a4ef141f22b593bcfa6535e5e4c8de46909d
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.ArraySet;
25import android.util.SparseArray;
26
27import java.io.File;
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
59    /**
60     * The path under which native libraries have been unpacked. This path is
61     * always derived at runtime, and is only stored here for cleanup when a
62     * package is uninstalled.
63     */
64    @Deprecated
65    String legacyNativeLibraryPathString;
66
67    /**
68     * The primary CPU abi for this package. This value is regenerated at every
69     * boot scan.
70     */
71    String primaryCpuAbiString;
72
73    /**
74     * The secondary CPU abi for this package. This value is regenerated at every
75     * boot scan.
76     */
77    String secondaryCpuAbiString;
78
79    /**
80     * The install time CPU override, if any. This value is written at install time
81     * and doesn't change during the life of an install. If non-null,
82     * {@code primaryCpuAbiString} will contain the same value.
83     */
84    String cpuAbiOverrideString;
85
86    long timeStamp;
87    long firstInstallTime;
88    long lastUpdateTime;
89    int versionCode;
90
91    boolean uidError;
92
93    PackageSignatures signatures = new PackageSignatures();
94
95    boolean permissionsFixed;
96    boolean haveGids;
97
98    PackageKeySetData keySetData = new PackageKeySetData();
99
100    private static final PackageUserState DEFAULT_USER_STATE = new PackageUserState();
101
102    // Whether this package is currently stopped, thus can not be
103    // started until explicitly launched by the user.
104    private final SparseArray<PackageUserState> userState = new SparseArray<PackageUserState>();
105
106    int installStatus = PKG_INSTALL_COMPLETE;
107
108    PackageSettingBase origPackage;
109
110    /* package name of the app that installed this package */
111    String installerPackageName;
112    PackageSettingBase(String name, String realName, File codePath, File resourcePath,
113            String legacyNativeLibraryPathString, String primaryCpuAbiString,
114            String secondaryCpuAbiString, String cpuAbiOverrideString,
115            int pVersionCode, int pkgFlags, int pkgPrivateFlags) {
116        super(pkgFlags, pkgPrivateFlags);
117        this.name = name;
118        this.realName = realName;
119        init(codePath, resourcePath, legacyNativeLibraryPathString, primaryCpuAbiString,
120                secondaryCpuAbiString, cpuAbiOverrideString, pVersionCode);
121    }
122
123    /**
124     * New instance of PackageSetting with one-level-deep cloning.
125     */
126    @SuppressWarnings("unchecked")
127    PackageSettingBase(PackageSettingBase base) {
128        super(base);
129
130        name = base.name;
131        realName = base.realName;
132        codePath = base.codePath;
133        codePathString = base.codePathString;
134        resourcePath = base.resourcePath;
135        resourcePathString = base.resourcePathString;
136        legacyNativeLibraryPathString = base.legacyNativeLibraryPathString;
137        primaryCpuAbiString = base.primaryCpuAbiString;
138        secondaryCpuAbiString = base.secondaryCpuAbiString;
139        cpuAbiOverrideString = base.cpuAbiOverrideString;
140        timeStamp = base.timeStamp;
141        firstInstallTime = base.firstInstallTime;
142        lastUpdateTime = base.lastUpdateTime;
143        versionCode = base.versionCode;
144
145        uidError = base.uidError;
146
147        signatures = new PackageSignatures(base.signatures);
148
149        permissionsFixed = base.permissionsFixed;
150        haveGids = base.haveGids;
151        userState.clear();
152        for (int i=0; i<base.userState.size(); i++) {
153            userState.put(base.userState.keyAt(i),
154                    new PackageUserState(base.userState.valueAt(i)));
155        }
156        installStatus = base.installStatus;
157
158        origPackage = base.origPackage;
159
160        installerPackageName = base.installerPackageName;
161
162        keySetData = new PackageKeySetData(base.keySetData);
163
164    }
165
166    void init(File codePath, File resourcePath, String legacyNativeLibraryPathString,
167              String primaryCpuAbiString, String secondaryCpuAbiString,
168              String cpuAbiOverrideString, int pVersionCode) {
169        this.codePath = codePath;
170        this.codePathString = codePath.toString();
171        this.resourcePath = resourcePath;
172        this.resourcePathString = resourcePath.toString();
173        this.legacyNativeLibraryPathString = legacyNativeLibraryPathString;
174        this.primaryCpuAbiString = primaryCpuAbiString;
175        this.secondaryCpuAbiString = secondaryCpuAbiString;
176        this.cpuAbiOverrideString = cpuAbiOverrideString;
177        this.versionCode = pVersionCode;
178    }
179
180    public void setInstallerPackageName(String packageName) {
181        installerPackageName = packageName;
182    }
183
184    String getInstallerPackageName() {
185        return installerPackageName;
186    }
187
188    public void setInstallStatus(int newStatus) {
189        installStatus = newStatus;
190    }
191
192    public int getInstallStatus() {
193        return installStatus;
194    }
195
196    public void setTimeStamp(long newStamp) {
197        timeStamp = newStamp;
198    }
199
200    /**
201     * Make a shallow copy of this package settings.
202     */
203    public void copyFrom(PackageSettingBase base) {
204        grantedPermissions = base.grantedPermissions;
205        gids = base.gids;
206
207        primaryCpuAbiString = base.primaryCpuAbiString;
208        secondaryCpuAbiString = base.secondaryCpuAbiString;
209        cpuAbiOverrideString = base.cpuAbiOverrideString;
210        timeStamp = base.timeStamp;
211        firstInstallTime = base.firstInstallTime;
212        lastUpdateTime = base.lastUpdateTime;
213        signatures = base.signatures;
214        permissionsFixed = base.permissionsFixed;
215        haveGids = base.haveGids;
216        userState.clear();
217        for (int i=0; i<base.userState.size(); i++) {
218            userState.put(base.userState.keyAt(i), base.userState.valueAt(i));
219        }
220        installStatus = base.installStatus;
221        keySetData = base.keySetData;
222        installerPackageName = base.installerPackageName;
223    }
224
225    private PackageUserState modifyUserState(int userId) {
226        PackageUserState state = userState.get(userId);
227        if (state == null) {
228            state = new PackageUserState();
229            userState.put(userId, state);
230        }
231        return state;
232    }
233
234    public PackageUserState readUserState(int userId) {
235        PackageUserState state = userState.get(userId);
236        if (state != null) {
237            return state;
238        }
239        return DEFAULT_USER_STATE;
240    }
241
242    void setEnabled(int state, int userId, String callingPackage) {
243        PackageUserState st = modifyUserState(userId);
244        st.enabled = state;
245        st.lastDisableAppCaller = callingPackage;
246    }
247
248    int getEnabled(int userId) {
249        return readUserState(userId).enabled;
250    }
251
252    String getLastDisabledAppCaller(int userId) {
253        return readUserState(userId).lastDisableAppCaller;
254    }
255
256    void setInstalled(boolean inst, int userId) {
257        modifyUserState(userId).installed = inst;
258    }
259
260    boolean getInstalled(int userId) {
261        return readUserState(userId).installed;
262    }
263
264    boolean isAnyInstalled(int[] users) {
265        for (int user: users) {
266            if (readUserState(user).installed) {
267                return true;
268            }
269        }
270        return false;
271    }
272
273    int[] queryInstalledUsers(int[] users, boolean installed) {
274        int num = 0;
275        for (int user : users) {
276            if (getInstalled(user) == installed) {
277                num++;
278            }
279        }
280        int[] res = new int[num];
281        num = 0;
282        for (int user : users) {
283            if (getInstalled(user) == installed) {
284                res[num] = user;
285                num++;
286            }
287        }
288        return res;
289    }
290
291    boolean getStopped(int userId) {
292        return readUserState(userId).stopped;
293    }
294
295    void setStopped(boolean stop, int userId) {
296        modifyUserState(userId).stopped = stop;
297    }
298
299    boolean getNotLaunched(int userId) {
300        return readUserState(userId).notLaunched;
301    }
302
303    void setNotLaunched(boolean stop, int userId) {
304        modifyUserState(userId).notLaunched = stop;
305    }
306
307    boolean getHidden(int userId) {
308        return readUserState(userId).hidden;
309    }
310
311    void setHidden(boolean hidden, int userId) {
312        modifyUserState(userId).hidden = hidden;
313    }
314
315    boolean getBlockUninstall(int userId) {
316        return readUserState(userId).blockUninstall;
317    }
318
319    void setBlockUninstall(boolean blockUninstall, int userId) {
320        modifyUserState(userId).blockUninstall = blockUninstall;
321    }
322
323    void setUserState(int userId, int enabled, boolean installed, boolean stopped,
324            boolean notLaunched, boolean hidden,
325            String lastDisableAppCaller, ArraySet<String> enabledComponents,
326            ArraySet<String> disabledComponents, boolean blockUninstall) {
327        PackageUserState state = modifyUserState(userId);
328        state.enabled = enabled;
329        state.installed = installed;
330        state.stopped = stopped;
331        state.notLaunched = notLaunched;
332        state.hidden = hidden;
333        state.lastDisableAppCaller = lastDisableAppCaller;
334        state.enabledComponents = enabledComponents;
335        state.disabledComponents = disabledComponents;
336        state.blockUninstall = blockUninstall;
337    }
338
339    ArraySet<String> getEnabledComponents(int userId) {
340        return readUserState(userId).enabledComponents;
341    }
342
343    ArraySet<String> getDisabledComponents(int userId) {
344        return readUserState(userId).disabledComponents;
345    }
346
347    void setEnabledComponents(ArraySet<String> components, int userId) {
348        modifyUserState(userId).enabledComponents = components;
349    }
350
351    void setDisabledComponents(ArraySet<String> components, int userId) {
352        modifyUserState(userId).disabledComponents = components;
353    }
354
355    void setEnabledComponentsCopy(ArraySet<String> components, int userId) {
356        modifyUserState(userId).enabledComponents = components != null
357                ? new ArraySet<String>(components) : null;
358    }
359
360    void setDisabledComponentsCopy(ArraySet<String> components, int userId) {
361        modifyUserState(userId).disabledComponents = components != null
362                ? new ArraySet<String>(components) : null;
363    }
364
365    PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) {
366        PackageUserState state = modifyUserState(userId);
367        if (disabled && state.disabledComponents == null) {
368            state.disabledComponents = new ArraySet<String>(1);
369        }
370        if (enabled && state.enabledComponents == null) {
371            state.enabledComponents = new ArraySet<String>(1);
372        }
373        return state;
374    }
375
376    void addDisabledComponent(String componentClassName, int userId) {
377        modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName);
378    }
379
380    void addEnabledComponent(String componentClassName, int userId) {
381        modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName);
382    }
383
384    boolean enableComponentLPw(String componentClassName, int userId) {
385        PackageUserState state = modifyUserStateComponents(userId, false, true);
386        boolean changed = state.disabledComponents != null
387                ? state.disabledComponents.remove(componentClassName) : false;
388        changed |= state.enabledComponents.add(componentClassName);
389        return changed;
390    }
391
392    boolean disableComponentLPw(String componentClassName, int userId) {
393        PackageUserState state = modifyUserStateComponents(userId, true, false);
394        boolean changed = state.enabledComponents != null
395                ? state.enabledComponents.remove(componentClassName) : false;
396        changed |= state.disabledComponents.add(componentClassName);
397        return changed;
398    }
399
400    boolean restoreComponentLPw(String componentClassName, int userId) {
401        PackageUserState state = modifyUserStateComponents(userId, true, true);
402        boolean changed = state.disabledComponents != null
403                ? state.disabledComponents.remove(componentClassName) : false;
404        changed |= state.enabledComponents != null
405                ? state.enabledComponents.remove(componentClassName) : false;
406        return changed;
407    }
408
409    int getCurrentEnabledStateLPr(String componentName, int userId) {
410        PackageUserState state = readUserState(userId);
411        if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) {
412            return COMPONENT_ENABLED_STATE_ENABLED;
413        } else if (state.disabledComponents != null
414                && state.disabledComponents.contains(componentName)) {
415            return COMPONENT_ENABLED_STATE_DISABLED;
416        } else {
417            return COMPONENT_ENABLED_STATE_DEFAULT;
418        }
419    }
420
421    void removeUser(int userId) {
422        userState.delete(userId);
423    }
424}
425