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