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