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