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