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