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