PackageSettingBase.java revision 0f877fab392154c77251dbac321b732a2a747911
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.content.pm.Signature;
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 */
44public abstract 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    public 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    long[] 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    long 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
135    /** Package name of the app that installed this package */
136    String installerPackageName;
137    /** Indicates if the package that installed this app has been uninstalled */
138    boolean isOrphaned;
139    /** UUID of {@link VolumeInfo} hosting this app */
140    String volumeUuid;
141    /** The category of this app, as hinted by the installer */
142    int categoryHint = ApplicationInfo.CATEGORY_UNDEFINED;
143    /** Whether or not an update is available. Ostensibly only for instant apps. */
144    boolean updateAvailable;
145
146    IntentFilterVerificationInfo verificationInfo;
147
148    PackageSettingBase(String name, String realName, File codePath, File resourcePath,
149            String legacyNativeLibraryPathString, String primaryCpuAbiString,
150            String secondaryCpuAbiString, String cpuAbiOverrideString,
151            long pVersionCode, int pkgFlags, int pkgPrivateFlags,
152            String parentPackageName, List<String> childPackageNames,
153            String[] usesStaticLibraries, long[] usesStaticLibrariesVersions) {
154        super(pkgFlags, pkgPrivateFlags);
155        this.name = name;
156        this.realName = realName;
157        this.parentPackageName = parentPackageName;
158        this.childPackageNames = (childPackageNames != null)
159                ? new ArrayList<>(childPackageNames) : null;
160        this.usesStaticLibraries = usesStaticLibraries;
161        this.usesStaticLibrariesVersions = usesStaticLibrariesVersions;
162        init(codePath, resourcePath, legacyNativeLibraryPathString, primaryCpuAbiString,
163                secondaryCpuAbiString, cpuAbiOverrideString, pVersionCode);
164    }
165
166    /**
167     * New instance of PackageSetting with one-level-deep cloning.
168     * <p>
169     * IMPORTANT: With a shallow copy, we do NOT create new contained objects.
170     * This means, for example, changes to the user state of the original PackageSetting
171     * will also change the user state in its copy.
172     */
173    PackageSettingBase(PackageSettingBase base, String realName) {
174        super(base);
175        name = base.name;
176        this.realName = realName;
177        doCopy(base);
178    }
179
180    void init(File codePath, File resourcePath, String legacyNativeLibraryPathString,
181              String primaryCpuAbiString, String secondaryCpuAbiString,
182              String cpuAbiOverrideString, long pVersionCode) {
183        this.codePath = codePath;
184        this.codePathString = codePath.toString();
185        this.resourcePath = resourcePath;
186        this.resourcePathString = resourcePath.toString();
187        this.legacyNativeLibraryPathString = legacyNativeLibraryPathString;
188        this.primaryCpuAbiString = primaryCpuAbiString;
189        this.secondaryCpuAbiString = secondaryCpuAbiString;
190        this.cpuAbiOverrideString = cpuAbiOverrideString;
191        this.versionCode = pVersionCode;
192        this.signatures = new PackageSignatures();
193    }
194
195    public void setInstallerPackageName(String packageName) {
196        installerPackageName = packageName;
197    }
198
199    public String getInstallerPackageName() {
200        return installerPackageName;
201    }
202
203    public void setVolumeUuid(String volumeUuid) {
204        this.volumeUuid = volumeUuid;
205    }
206
207    public String getVolumeUuid() {
208        return volumeUuid;
209    }
210
211    public void setInstallStatus(int newStatus) {
212        installStatus = newStatus;
213    }
214
215    public int getInstallStatus() {
216        return installStatus;
217    }
218
219    public void setTimeStamp(long newStamp) {
220        timeStamp = newStamp;
221    }
222
223    public void setUpdateAvailable(boolean updateAvailable) {
224        this.updateAvailable = updateAvailable;
225    }
226
227    public boolean isUpdateAvailable() {
228        return updateAvailable;
229    }
230
231    public boolean isSharedUser() {
232        return false;
233    }
234
235    public Signature[] getSignatures() {
236        return signatures.mSignatures;
237    }
238
239    /**
240     * Makes a shallow copy of the given package settings.
241     *
242     * NOTE: For some fields [such as keySetData, signatures, userState, verificationInfo, etc...],
243     * the original object is copied and a new one is not created.
244     */
245    public void copyFrom(PackageSettingBase orig) {
246        super.copyFrom(orig);
247        doCopy(orig);
248    }
249
250    private void doCopy(PackageSettingBase orig) {
251        childPackageNames = (orig.childPackageNames != null)
252                ? new ArrayList<>(orig.childPackageNames) : null;
253        codePath = orig.codePath;
254        codePathString = orig.codePathString;
255        cpuAbiOverrideString = orig.cpuAbiOverrideString;
256        firstInstallTime = orig.firstInstallTime;
257        installPermissionsFixed = orig.installPermissionsFixed;
258        installStatus = orig.installStatus;
259        installerPackageName = orig.installerPackageName;
260        isOrphaned = orig.isOrphaned;
261        keySetData = orig.keySetData;
262        lastUpdateTime = orig.lastUpdateTime;
263        legacyNativeLibraryPathString = orig.legacyNativeLibraryPathString;
264        // Intentionally skip oldCodePaths; it's not relevant for copies
265        parentPackageName = orig.parentPackageName;
266        primaryCpuAbiString = orig.primaryCpuAbiString;
267        resourcePath = orig.resourcePath;
268        resourcePathString = orig.resourcePathString;
269        secondaryCpuAbiString = orig.secondaryCpuAbiString;
270        signatures = orig.signatures;
271        timeStamp = orig.timeStamp;
272        uidError = orig.uidError;
273        userState.clear();
274        for (int i=0; i<orig.userState.size(); i++) {
275            userState.put(orig.userState.keyAt(i), orig.userState.valueAt(i));
276        }
277        verificationInfo = orig.verificationInfo;
278        versionCode = orig.versionCode;
279        volumeUuid = orig.volumeUuid;
280        categoryHint = orig.categoryHint;
281        usesStaticLibraries = orig.usesStaticLibraries != null
282                ? Arrays.copyOf(orig.usesStaticLibraries,
283                        orig.usesStaticLibraries.length) : null;
284        usesStaticLibrariesVersions = orig.usesStaticLibrariesVersions != null
285                ? Arrays.copyOf(orig.usesStaticLibrariesVersions,
286                       orig.usesStaticLibrariesVersions.length) : null;
287        updateAvailable = orig.updateAvailable;
288    }
289
290    private PackageUserState modifyUserState(int userId) {
291        PackageUserState state = userState.get(userId);
292        if (state == null) {
293            state = new PackageUserState();
294            userState.put(userId, state);
295        }
296        return state;
297    }
298
299    public PackageUserState readUserState(int userId) {
300        PackageUserState state = userState.get(userId);
301        if (state == null) {
302            return DEFAULT_USER_STATE;
303        }
304        state.categoryHint = categoryHint;
305        return state;
306    }
307
308    void setEnabled(int state, int userId, String callingPackage) {
309        PackageUserState st = modifyUserState(userId);
310        st.enabled = state;
311        st.lastDisableAppCaller = callingPackage;
312    }
313
314    int getEnabled(int userId) {
315        return readUserState(userId).enabled;
316    }
317
318    String getLastDisabledAppCaller(int userId) {
319        return readUserState(userId).lastDisableAppCaller;
320    }
321
322    void setInstalled(boolean inst, int userId) {
323        modifyUserState(userId).installed = inst;
324    }
325
326    boolean getInstalled(int userId) {
327        return readUserState(userId).installed;
328    }
329
330    int getInstallReason(int userId) {
331        return readUserState(userId).installReason;
332    }
333
334    void setInstallReason(int installReason, int userId) {
335        modifyUserState(userId).installReason = installReason;
336    }
337
338    void setOverlayPaths(List<String> overlayPaths, int userId) {
339        modifyUserState(userId).overlayPaths = overlayPaths == null ? null :
340            overlayPaths.toArray(new String[overlayPaths.size()]);
341    }
342
343    String[] getOverlayPaths(int userId) {
344        return readUserState(userId).overlayPaths;
345    }
346
347    /** Only use for testing. Do NOT use in production code. */
348    @VisibleForTesting
349    SparseArray<PackageUserState> getUserState() {
350        return userState;
351    }
352
353    boolean isAnyInstalled(int[] users) {
354        for (int user: users) {
355            if (readUserState(user).installed) {
356                return true;
357            }
358        }
359        return false;
360    }
361
362    int[] queryInstalledUsers(int[] users, boolean installed) {
363        int num = 0;
364        for (int user : users) {
365            if (getInstalled(user) == installed) {
366                num++;
367            }
368        }
369        int[] res = new int[num];
370        num = 0;
371        for (int user : users) {
372            if (getInstalled(user) == installed) {
373                res[num] = user;
374                num++;
375            }
376        }
377        return res;
378    }
379
380    long getCeDataInode(int userId) {
381        return readUserState(userId).ceDataInode;
382    }
383
384    void setCeDataInode(long ceDataInode, int userId) {
385        modifyUserState(userId).ceDataInode = ceDataInode;
386    }
387
388    boolean getStopped(int userId) {
389        return readUserState(userId).stopped;
390    }
391
392    void setStopped(boolean stop, int userId) {
393        modifyUserState(userId).stopped = stop;
394    }
395
396    boolean getNotLaunched(int userId) {
397        return readUserState(userId).notLaunched;
398    }
399
400    void setNotLaunched(boolean stop, int userId) {
401        modifyUserState(userId).notLaunched = stop;
402    }
403
404    boolean getHidden(int userId) {
405        return readUserState(userId).hidden;
406    }
407
408    void setHidden(boolean hidden, int userId) {
409        modifyUserState(userId).hidden = hidden;
410    }
411
412    boolean getSuspended(int userId) {
413        return readUserState(userId).suspended;
414    }
415
416    void setSuspended(boolean suspended, int userId) {
417        modifyUserState(userId).suspended = suspended;
418    }
419
420    public boolean getInstantApp(int userId) {
421        return readUserState(userId).instantApp;
422    }
423
424    void setInstantApp(boolean instantApp, int userId) {
425        modifyUserState(userId).instantApp = instantApp;
426    }
427
428    boolean getVirtulalPreload(int userId) {
429        return readUserState(userId).virtualPreload;
430    }
431
432    void setVirtualPreload(boolean virtualPreload, int userId) {
433        modifyUserState(userId).virtualPreload = virtualPreload;
434    }
435
436    void setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped,
437            boolean notLaunched, boolean hidden, boolean suspended, boolean instantApp,
438            boolean virtualPreload, String lastDisableAppCaller,
439            ArraySet<String> enabledComponents, ArraySet<String> disabledComponents,
440            int domainVerifState, int linkGeneration, int installReason) {
441        PackageUserState state = modifyUserState(userId);
442        state.ceDataInode = ceDataInode;
443        state.enabled = enabled;
444        state.installed = installed;
445        state.stopped = stopped;
446        state.notLaunched = notLaunched;
447        state.hidden = hidden;
448        state.suspended = suspended;
449        state.lastDisableAppCaller = lastDisableAppCaller;
450        state.enabledComponents = enabledComponents;
451        state.disabledComponents = disabledComponents;
452        state.domainVerificationStatus = domainVerifState;
453        state.appLinkGeneration = linkGeneration;
454        state.installReason = installReason;
455        state.instantApp = instantApp;
456        state.virtualPreload = virtualPreload;
457    }
458
459    ArraySet<String> getEnabledComponents(int userId) {
460        return readUserState(userId).enabledComponents;
461    }
462
463    ArraySet<String> getDisabledComponents(int userId) {
464        return readUserState(userId).disabledComponents;
465    }
466
467    void setEnabledComponents(ArraySet<String> components, int userId) {
468        modifyUserState(userId).enabledComponents = components;
469    }
470
471    void setDisabledComponents(ArraySet<String> components, int userId) {
472        modifyUserState(userId).disabledComponents = components;
473    }
474
475    void setEnabledComponentsCopy(ArraySet<String> components, int userId) {
476        modifyUserState(userId).enabledComponents = components != null
477                ? new ArraySet<String>(components) : null;
478    }
479
480    void setDisabledComponentsCopy(ArraySet<String> components, int userId) {
481        modifyUserState(userId).disabledComponents = components != null
482                ? new ArraySet<String>(components) : null;
483    }
484
485    PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) {
486        PackageUserState state = modifyUserState(userId);
487        if (disabled && state.disabledComponents == null) {
488            state.disabledComponents = new ArraySet<String>(1);
489        }
490        if (enabled && state.enabledComponents == null) {
491            state.enabledComponents = new ArraySet<String>(1);
492        }
493        return state;
494    }
495
496    void addDisabledComponent(String componentClassName, int userId) {
497        modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName);
498    }
499
500    void addEnabledComponent(String componentClassName, int userId) {
501        modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName);
502    }
503
504    boolean enableComponentLPw(String componentClassName, int userId) {
505        PackageUserState state = modifyUserStateComponents(userId, false, true);
506        boolean changed = state.disabledComponents != null
507                ? state.disabledComponents.remove(componentClassName) : false;
508        changed |= state.enabledComponents.add(componentClassName);
509        return changed;
510    }
511
512    boolean disableComponentLPw(String componentClassName, int userId) {
513        PackageUserState state = modifyUserStateComponents(userId, true, false);
514        boolean changed = state.enabledComponents != null
515                ? state.enabledComponents.remove(componentClassName) : false;
516        changed |= state.disabledComponents.add(componentClassName);
517        return changed;
518    }
519
520    boolean restoreComponentLPw(String componentClassName, int userId) {
521        PackageUserState state = modifyUserStateComponents(userId, true, true);
522        boolean changed = state.disabledComponents != null
523                ? state.disabledComponents.remove(componentClassName) : false;
524        changed |= state.enabledComponents != null
525                ? state.enabledComponents.remove(componentClassName) : false;
526        return changed;
527    }
528
529    int getCurrentEnabledStateLPr(String componentName, int userId) {
530        PackageUserState state = readUserState(userId);
531        if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) {
532            return COMPONENT_ENABLED_STATE_ENABLED;
533        } else if (state.disabledComponents != null
534                && state.disabledComponents.contains(componentName)) {
535            return COMPONENT_ENABLED_STATE_DISABLED;
536        } else {
537            return COMPONENT_ENABLED_STATE_DEFAULT;
538        }
539    }
540
541    void removeUser(int userId) {
542        userState.delete(userId);
543    }
544
545    public int[] getNotInstalledUserIds() {
546        int count = 0;
547        int userStateCount = userState.size();
548        for (int i = 0; i < userStateCount; i++) {
549            if (userState.valueAt(i).installed == false) {
550                count++;
551            }
552        }
553        if (count == 0) return EMPTY_INT_ARRAY;
554        int[] excludedUserIds = new int[count];
555        int idx = 0;
556        for (int i = 0; i < userStateCount; i++) {
557            if (userState.valueAt(i).installed == false) {
558                excludedUserIds[idx++] = userState.keyAt(i);
559            }
560        }
561        return excludedUserIds;
562    }
563
564    IntentFilterVerificationInfo getIntentFilterVerificationInfo() {
565        return verificationInfo;
566    }
567
568    void setIntentFilterVerificationInfo(IntentFilterVerificationInfo info) {
569        verificationInfo = info;
570    }
571
572    // Returns a packed value as a long:
573    //
574    // high 'int'-sized word: link status: undefined/ask/never/always.
575    // low 'int'-sized word: relative priority among 'always' results.
576    long getDomainVerificationStatusForUser(int userId) {
577        PackageUserState state = readUserState(userId);
578        long result = (long) state.appLinkGeneration;
579        result |= ((long) state.domainVerificationStatus) << 32;
580        return result;
581    }
582
583    void setDomainVerificationStatusForUser(final int status, int generation, int userId) {
584        PackageUserState state = modifyUserState(userId);
585        state.domainVerificationStatus = status;
586        if (status == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
587            state.appLinkGeneration = generation;
588        }
589    }
590
591    void clearDomainVerificationStatusForUser(int userId) {
592        modifyUserState(userId).domainVerificationStatus =
593                PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
594    }
595
596    protected void writeUsersInfoToProto(ProtoOutputStream proto, long fieldId) {
597        int count = userState.size();
598        for (int i = 0; i < count; i++) {
599            final long userToken = proto.start(fieldId);
600            final int userId = userState.keyAt(i);
601            final PackageUserState state = userState.valueAt(i);
602            proto.write(PackageProto.UserInfoProto.ID, userId);
603            final int installType;
604            if (state.instantApp) {
605                installType = PackageProto.UserInfoProto.INSTANT_APP_INSTALL;
606            } else if (state.installed) {
607                installType = PackageProto.UserInfoProto.FULL_APP_INSTALL;
608            } else {
609                installType = PackageProto.UserInfoProto.NOT_INSTALLED_FOR_USER;
610            }
611            proto.write(PackageProto.UserInfoProto.INSTALL_TYPE, installType);
612            proto.write(PackageProto.UserInfoProto.IS_HIDDEN, state.hidden);
613            proto.write(PackageProto.UserInfoProto.IS_SUSPENDED, state.suspended);
614            proto.write(PackageProto.UserInfoProto.IS_STOPPED, state.stopped);
615            proto.write(PackageProto.UserInfoProto.IS_LAUNCHED, !state.notLaunched);
616            proto.write(PackageProto.UserInfoProto.ENABLED_STATE, state.enabled);
617            proto.write(
618                    PackageProto.UserInfoProto.LAST_DISABLED_APP_CALLER,
619                    state.lastDisableAppCaller);
620            proto.end(userToken);
621        }
622    }
623}
624