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