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