PackageSettingBase.java revision 354cd3ce2213a1032d9138ea6fa1420f055ab08c
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.IntentFilterVerificationInfo;
24import android.content.pm.PackageManager;
25import android.content.pm.PackageUserState;
26import android.os.storage.VolumeInfo;
27import android.util.ArraySet;
28import android.util.SparseArray;
29
30import java.io.File;
31import java.util.ArrayList;
32import java.util.List;
33
34/**
35 * Settings base class for pending and resolved classes.
36 */
37abstract class PackageSettingBase extends SettingBase {
38    /**
39     * Indicates the state of installation. Used by PackageManager to figure out
40     * incomplete installations. Say a package is being installed (the state is
41     * set to PKG_INSTALL_INCOMPLETE) and remains so till the package
42     * installation is successful or unsuccessful in which case the
43     * PackageManager will no longer maintain state information associated with
44     * the package. If some exception(like device freeze or battery being pulled
45     * out) occurs during installation of a package, the PackageManager needs
46     * this information to clean up the previously failed installation.
47     */
48    static final int PKG_INSTALL_COMPLETE = 1;
49    static final int PKG_INSTALL_INCOMPLETE = 0;
50
51    final String name;
52    final String realName;
53
54    String parentPackageName;
55    List<String> childPackageNames;
56
57    /**
58     * Path where this package was found on disk. For monolithic packages
59     * this is path to single base APK file; for cluster packages this is
60     * path to the cluster directory.
61     */
62    File codePath;
63    String codePathString;
64    File resourcePath;
65    String resourcePathString;
66
67    /**
68     * The path under which native libraries have been unpacked. This path is
69     * always derived at runtime, and is only stored here for cleanup when a
70     * package is uninstalled.
71     */
72    @Deprecated
73    String legacyNativeLibraryPathString;
74
75    /**
76     * The primary CPU abi for this package. This value is regenerated at every
77     * boot scan.
78     */
79    String primaryCpuAbiString;
80
81    /**
82     * The secondary CPU abi for this package. This value is regenerated at every
83     * boot scan.
84     */
85    String secondaryCpuAbiString;
86
87    /**
88     * The install time CPU override, if any. This value is written at install time
89     * and doesn't change during the life of an install. If non-null,
90     * {@code primaryCpuAbiString} will contain the same value.
91     */
92    String cpuAbiOverrideString;
93
94    long timeStamp;
95    long firstInstallTime;
96    long lastUpdateTime;
97    int versionCode;
98
99    boolean uidError;
100
101    PackageSignatures signatures = new PackageSignatures();
102
103    boolean installPermissionsFixed;
104
105    PackageKeySetData keySetData = new PackageKeySetData();
106
107    private static final PackageUserState DEFAULT_USER_STATE = new PackageUserState();
108
109    // Whether this package is currently stopped, thus can not be
110    // started until explicitly launched by the user.
111    private final SparseArray<PackageUserState> userState = new SparseArray<PackageUserState>();
112
113    int installStatus = PKG_INSTALL_COMPLETE;
114
115    /**
116     * Non-persisted value indicating this package has been temporarily frozen,
117     * usually during a critical section of the package update pipeline. The
118     * platform will refuse to launch packages in a frozen state.
119     */
120    boolean frozen = false;
121
122    PackageSettingBase origPackage;
123
124    /** Package name of the app that installed this package */
125    String installerPackageName;
126    /** UUID of {@link VolumeInfo} hosting this app */
127    String volumeUuid;
128
129    IntentFilterVerificationInfo verificationInfo;
130
131    PackageSettingBase(String name, String realName, File codePath, File resourcePath,
132            String legacyNativeLibraryPathString, String primaryCpuAbiString,
133            String secondaryCpuAbiString, String cpuAbiOverrideString,
134            int pVersionCode, int pkgFlags, int pkgPrivateFlags,
135            String parentPackageName, List<String> childPackageNames) {
136        super(pkgFlags, pkgPrivateFlags);
137        this.name = name;
138        this.realName = realName;
139        this.parentPackageName = parentPackageName;
140        this.childPackageNames = (childPackageNames != null)
141                ? new ArrayList<>(childPackageNames) : null;
142        init(codePath, resourcePath, legacyNativeLibraryPathString, primaryCpuAbiString,
143                secondaryCpuAbiString, cpuAbiOverrideString, pVersionCode);
144    }
145
146    /**
147     * New instance of PackageSetting with one-level-deep cloning.
148     */
149    @SuppressWarnings("unchecked")
150    PackageSettingBase(PackageSettingBase base) {
151        super(base);
152
153        name = base.name;
154        realName = base.realName;
155        codePath = base.codePath;
156        codePathString = base.codePathString;
157        resourcePath = base.resourcePath;
158        resourcePathString = base.resourcePathString;
159        legacyNativeLibraryPathString = base.legacyNativeLibraryPathString;
160        primaryCpuAbiString = base.primaryCpuAbiString;
161        secondaryCpuAbiString = base.secondaryCpuAbiString;
162        cpuAbiOverrideString = base.cpuAbiOverrideString;
163        timeStamp = base.timeStamp;
164        firstInstallTime = base.firstInstallTime;
165        lastUpdateTime = base.lastUpdateTime;
166        versionCode = base.versionCode;
167
168        uidError = base.uidError;
169
170        signatures = new PackageSignatures(base.signatures);
171
172        installPermissionsFixed = base.installPermissionsFixed;
173        userState.clear();
174        for (int i=0; i<base.userState.size(); i++) {
175            userState.put(base.userState.keyAt(i),
176                    new PackageUserState(base.userState.valueAt(i)));
177        }
178        installStatus = base.installStatus;
179
180        origPackage = base.origPackage;
181
182        installerPackageName = base.installerPackageName;
183        volumeUuid = base.volumeUuid;
184
185        keySetData = new PackageKeySetData(base.keySetData);
186
187        parentPackageName = base.parentPackageName;
188        childPackageNames = (base.childPackageNames != null)
189                ? new ArrayList<>(base.childPackageNames) : null;
190    }
191
192    void init(File codePath, File resourcePath, String legacyNativeLibraryPathString,
193              String primaryCpuAbiString, String secondaryCpuAbiString,
194              String cpuAbiOverrideString, int pVersionCode) {
195        this.codePath = codePath;
196        this.codePathString = codePath.toString();
197        this.resourcePath = resourcePath;
198        this.resourcePathString = resourcePath.toString();
199        this.legacyNativeLibraryPathString = legacyNativeLibraryPathString;
200        this.primaryCpuAbiString = primaryCpuAbiString;
201        this.secondaryCpuAbiString = secondaryCpuAbiString;
202        this.cpuAbiOverrideString = cpuAbiOverrideString;
203        this.versionCode = pVersionCode;
204    }
205
206    public void setInstallerPackageName(String packageName) {
207        installerPackageName = packageName;
208    }
209
210    public String getInstallerPackageName() {
211        return installerPackageName;
212    }
213
214    public void setVolumeUuid(String volumeUuid) {
215        this.volumeUuid = volumeUuid;
216    }
217
218    public String getVolumeUuid() {
219        return volumeUuid;
220    }
221
222    public void setInstallStatus(int newStatus) {
223        installStatus = newStatus;
224    }
225
226    public int getInstallStatus() {
227        return installStatus;
228    }
229
230    public void setTimeStamp(long newStamp) {
231        timeStamp = newStamp;
232    }
233
234    /**
235     * Make a shallow copy of this package settings.
236     */
237    public void copyFrom(PackageSettingBase base) {
238        mPermissionsState.copyFrom(base.mPermissionsState);
239        primaryCpuAbiString = base.primaryCpuAbiString;
240        secondaryCpuAbiString = base.secondaryCpuAbiString;
241        cpuAbiOverrideString = base.cpuAbiOverrideString;
242        timeStamp = base.timeStamp;
243        firstInstallTime = base.firstInstallTime;
244        lastUpdateTime = base.lastUpdateTime;
245        signatures = base.signatures;
246        installPermissionsFixed = base.installPermissionsFixed;
247        userState.clear();
248        for (int i=0; i<base.userState.size(); i++) {
249            userState.put(base.userState.keyAt(i), base.userState.valueAt(i));
250        }
251        installStatus = base.installStatus;
252        keySetData = base.keySetData;
253        verificationInfo = base.verificationInfo;
254        installerPackageName = base.installerPackageName;
255        volumeUuid = base.volumeUuid;
256    }
257
258    private PackageUserState modifyUserState(int userId) {
259        PackageUserState state = userState.get(userId);
260        if (state == null) {
261            state = new PackageUserState();
262            userState.put(userId, state);
263        }
264        return state;
265    }
266
267    public PackageUserState readUserState(int userId) {
268        PackageUserState state = userState.get(userId);
269        if (state != null) {
270            return state;
271        }
272        return DEFAULT_USER_STATE;
273    }
274
275    void setEnabled(int state, int userId, String callingPackage) {
276        PackageUserState st = modifyUserState(userId);
277        st.enabled = state;
278        st.lastDisableAppCaller = callingPackage;
279    }
280
281    int getEnabled(int userId) {
282        return readUserState(userId).enabled;
283    }
284
285    String getLastDisabledAppCaller(int userId) {
286        return readUserState(userId).lastDisableAppCaller;
287    }
288
289    void setInstalled(boolean inst, int userId) {
290        modifyUserState(userId).installed = inst;
291    }
292
293    boolean getInstalled(int userId) {
294        return readUserState(userId).installed;
295    }
296
297    boolean isAnyInstalled(int[] users) {
298        for (int user: users) {
299            if (readUserState(user).installed) {
300                return true;
301            }
302        }
303        return false;
304    }
305
306    int[] queryInstalledUsers(int[] users, boolean installed) {
307        int num = 0;
308        for (int user : users) {
309            if (getInstalled(user) == installed) {
310                num++;
311            }
312        }
313        int[] res = new int[num];
314        num = 0;
315        for (int user : users) {
316            if (getInstalled(user) == installed) {
317                res[num] = user;
318                num++;
319            }
320        }
321        return res;
322    }
323
324    boolean getStopped(int userId) {
325        return readUserState(userId).stopped;
326    }
327
328    void setStopped(boolean stop, int userId) {
329        modifyUserState(userId).stopped = stop;
330    }
331
332    boolean getNotLaunched(int userId) {
333        return readUserState(userId).notLaunched;
334    }
335
336    void setNotLaunched(boolean stop, int userId) {
337        modifyUserState(userId).notLaunched = stop;
338    }
339
340    boolean getHidden(int userId) {
341        return readUserState(userId).hidden;
342    }
343
344    void setHidden(boolean hidden, int userId) {
345        modifyUserState(userId).hidden = hidden;
346    }
347
348    boolean getSuspended(int userId) {
349        return readUserState(userId).suspended;
350    }
351
352    void setSuspended(boolean suspended, int userId) {
353        modifyUserState(userId).suspended = suspended;
354    }
355
356    boolean getBlockUninstall(int userId) {
357        return readUserState(userId).blockUninstall;
358    }
359
360    void setBlockUninstall(boolean blockUninstall, int userId) {
361        modifyUserState(userId).blockUninstall = blockUninstall;
362    }
363
364    void setUserState(int userId, int enabled, boolean installed, boolean stopped,
365            boolean notLaunched, boolean hidden, boolean suspended,
366            String lastDisableAppCaller, ArraySet<String> enabledComponents,
367            ArraySet<String> disabledComponents, boolean blockUninstall, int domainVerifState,
368            int linkGeneration) {
369        PackageUserState state = modifyUserState(userId);
370        state.enabled = enabled;
371        state.installed = installed;
372        state.stopped = stopped;
373        state.notLaunched = notLaunched;
374        state.hidden = hidden;
375        state.suspended = suspended;
376        state.lastDisableAppCaller = lastDisableAppCaller;
377        state.enabledComponents = enabledComponents;
378        state.disabledComponents = disabledComponents;
379        state.blockUninstall = blockUninstall;
380        state.domainVerificationStatus = domainVerifState;
381        state.appLinkGeneration = linkGeneration;
382    }
383
384    ArraySet<String> getEnabledComponents(int userId) {
385        return readUserState(userId).enabledComponents;
386    }
387
388    ArraySet<String> getDisabledComponents(int userId) {
389        return readUserState(userId).disabledComponents;
390    }
391
392    void setEnabledComponents(ArraySet<String> components, int userId) {
393        modifyUserState(userId).enabledComponents = components;
394    }
395
396    void setDisabledComponents(ArraySet<String> components, int userId) {
397        modifyUserState(userId).disabledComponents = components;
398    }
399
400    void setEnabledComponentsCopy(ArraySet<String> components, int userId) {
401        modifyUserState(userId).enabledComponents = components != null
402                ? new ArraySet<String>(components) : null;
403    }
404
405    void setDisabledComponentsCopy(ArraySet<String> components, int userId) {
406        modifyUserState(userId).disabledComponents = components != null
407                ? new ArraySet<String>(components) : null;
408    }
409
410    PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) {
411        PackageUserState state = modifyUserState(userId);
412        if (disabled && state.disabledComponents == null) {
413            state.disabledComponents = new ArraySet<String>(1);
414        }
415        if (enabled && state.enabledComponents == null) {
416            state.enabledComponents = new ArraySet<String>(1);
417        }
418        return state;
419    }
420
421    void addDisabledComponent(String componentClassName, int userId) {
422        modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName);
423    }
424
425    void addEnabledComponent(String componentClassName, int userId) {
426        modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName);
427    }
428
429    boolean enableComponentLPw(String componentClassName, int userId) {
430        PackageUserState state = modifyUserStateComponents(userId, false, true);
431        boolean changed = state.disabledComponents != null
432                ? state.disabledComponents.remove(componentClassName) : false;
433        changed |= state.enabledComponents.add(componentClassName);
434        return changed;
435    }
436
437    boolean disableComponentLPw(String componentClassName, int userId) {
438        PackageUserState state = modifyUserStateComponents(userId, true, false);
439        boolean changed = state.enabledComponents != null
440                ? state.enabledComponents.remove(componentClassName) : false;
441        changed |= state.disabledComponents.add(componentClassName);
442        return changed;
443    }
444
445    boolean restoreComponentLPw(String componentClassName, int userId) {
446        PackageUserState state = modifyUserStateComponents(userId, true, true);
447        boolean changed = state.disabledComponents != null
448                ? state.disabledComponents.remove(componentClassName) : false;
449        changed |= state.enabledComponents != null
450                ? state.enabledComponents.remove(componentClassName) : false;
451        return changed;
452    }
453
454    int getCurrentEnabledStateLPr(String componentName, int userId) {
455        PackageUserState state = readUserState(userId);
456        if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) {
457            return COMPONENT_ENABLED_STATE_ENABLED;
458        } else if (state.disabledComponents != null
459                && state.disabledComponents.contains(componentName)) {
460            return COMPONENT_ENABLED_STATE_DISABLED;
461        } else {
462            return COMPONENT_ENABLED_STATE_DEFAULT;
463        }
464    }
465
466    void removeUser(int userId) {
467        userState.delete(userId);
468    }
469
470    IntentFilterVerificationInfo getIntentFilterVerificationInfo() {
471        return verificationInfo;
472    }
473
474    void setIntentFilterVerificationInfo(IntentFilterVerificationInfo info) {
475        verificationInfo = info;
476    }
477
478    // Returns a packed value as a long:
479    //
480    // high 'int'-sized word: link status: undefined/ask/never/always.
481    // low 'int'-sized word: relative priority among 'always' results.
482    long getDomainVerificationStatusForUser(int userId) {
483        PackageUserState state = readUserState(userId);
484        long result = (long) state.appLinkGeneration;
485        result |= ((long) state.domainVerificationStatus) << 32;
486        return result;
487    }
488
489    void setDomainVerificationStatusForUser(final int status, int generation, int userId) {
490        PackageUserState state = modifyUserState(userId);
491        state.domainVerificationStatus = status;
492        if (status == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
493            state.appLinkGeneration = generation;
494        }
495    }
496
497    void clearDomainVerificationStatusForUser(int userId) {
498        modifyUserState(userId).domainVerificationStatus =
499                PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
500    }
501}
502