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