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