PackageSettingBase.java revision 77029c5b16351775cb2333369ef9a4bc1d9acf58
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.mSigningDetails.signatures;
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            String harmfulAppWarning) {
442        PackageUserState state = modifyUserState(userId);
443        state.ceDataInode = ceDataInode;
444        state.enabled = enabled;
445        state.installed = installed;
446        state.stopped = stopped;
447        state.notLaunched = notLaunched;
448        state.hidden = hidden;
449        state.suspended = suspended;
450        state.lastDisableAppCaller = lastDisableAppCaller;
451        state.enabledComponents = enabledComponents;
452        state.disabledComponents = disabledComponents;
453        state.domainVerificationStatus = domainVerifState;
454        state.appLinkGeneration = linkGeneration;
455        state.installReason = installReason;
456        state.instantApp = instantApp;
457        state.virtualPreload = virtualPreload;
458        state.harmfulAppWarning = harmfulAppWarning;
459    }
460
461    ArraySet<String> getEnabledComponents(int userId) {
462        return readUserState(userId).enabledComponents;
463    }
464
465    ArraySet<String> getDisabledComponents(int userId) {
466        return readUserState(userId).disabledComponents;
467    }
468
469    void setEnabledComponents(ArraySet<String> components, int userId) {
470        modifyUserState(userId).enabledComponents = components;
471    }
472
473    void setDisabledComponents(ArraySet<String> components, int userId) {
474        modifyUserState(userId).disabledComponents = components;
475    }
476
477    void setEnabledComponentsCopy(ArraySet<String> components, int userId) {
478        modifyUserState(userId).enabledComponents = components != null
479                ? new ArraySet<String>(components) : null;
480    }
481
482    void setDisabledComponentsCopy(ArraySet<String> components, int userId) {
483        modifyUserState(userId).disabledComponents = components != null
484                ? new ArraySet<String>(components) : null;
485    }
486
487    PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) {
488        PackageUserState state = modifyUserState(userId);
489        if (disabled && state.disabledComponents == null) {
490            state.disabledComponents = new ArraySet<String>(1);
491        }
492        if (enabled && state.enabledComponents == null) {
493            state.enabledComponents = new ArraySet<String>(1);
494        }
495        return state;
496    }
497
498    void addDisabledComponent(String componentClassName, int userId) {
499        modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName);
500    }
501
502    void addEnabledComponent(String componentClassName, int userId) {
503        modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName);
504    }
505
506    boolean enableComponentLPw(String componentClassName, int userId) {
507        PackageUserState state = modifyUserStateComponents(userId, false, true);
508        boolean changed = state.disabledComponents != null
509                ? state.disabledComponents.remove(componentClassName) : false;
510        changed |= state.enabledComponents.add(componentClassName);
511        return changed;
512    }
513
514    boolean disableComponentLPw(String componentClassName, int userId) {
515        PackageUserState state = modifyUserStateComponents(userId, true, false);
516        boolean changed = state.enabledComponents != null
517                ? state.enabledComponents.remove(componentClassName) : false;
518        changed |= state.disabledComponents.add(componentClassName);
519        return changed;
520    }
521
522    boolean restoreComponentLPw(String componentClassName, int userId) {
523        PackageUserState state = modifyUserStateComponents(userId, true, true);
524        boolean changed = state.disabledComponents != null
525                ? state.disabledComponents.remove(componentClassName) : false;
526        changed |= state.enabledComponents != null
527                ? state.enabledComponents.remove(componentClassName) : false;
528        return changed;
529    }
530
531    int getCurrentEnabledStateLPr(String componentName, int userId) {
532        PackageUserState state = readUserState(userId);
533        if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) {
534            return COMPONENT_ENABLED_STATE_ENABLED;
535        } else if (state.disabledComponents != null
536                && state.disabledComponents.contains(componentName)) {
537            return COMPONENT_ENABLED_STATE_DISABLED;
538        } else {
539            return COMPONENT_ENABLED_STATE_DEFAULT;
540        }
541    }
542
543    void removeUser(int userId) {
544        userState.delete(userId);
545    }
546
547    public int[] getNotInstalledUserIds() {
548        int count = 0;
549        int userStateCount = userState.size();
550        for (int i = 0; i < userStateCount; i++) {
551            if (userState.valueAt(i).installed == false) {
552                count++;
553            }
554        }
555        if (count == 0) return EMPTY_INT_ARRAY;
556        int[] excludedUserIds = new int[count];
557        int idx = 0;
558        for (int i = 0; i < userStateCount; i++) {
559            if (userState.valueAt(i).installed == false) {
560                excludedUserIds[idx++] = userState.keyAt(i);
561            }
562        }
563        return excludedUserIds;
564    }
565
566    IntentFilterVerificationInfo getIntentFilterVerificationInfo() {
567        return verificationInfo;
568    }
569
570    void setIntentFilterVerificationInfo(IntentFilterVerificationInfo info) {
571        verificationInfo = info;
572    }
573
574    // Returns a packed value as a long:
575    //
576    // high 'int'-sized word: link status: undefined/ask/never/always.
577    // low 'int'-sized word: relative priority among 'always' results.
578    long getDomainVerificationStatusForUser(int userId) {
579        PackageUserState state = readUserState(userId);
580        long result = (long) state.appLinkGeneration;
581        result |= ((long) state.domainVerificationStatus) << 32;
582        return result;
583    }
584
585    void setDomainVerificationStatusForUser(final int status, int generation, int userId) {
586        PackageUserState state = modifyUserState(userId);
587        state.domainVerificationStatus = status;
588        if (status == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
589            state.appLinkGeneration = generation;
590        }
591    }
592
593    void clearDomainVerificationStatusForUser(int userId) {
594        modifyUserState(userId).domainVerificationStatus =
595                PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
596    }
597
598    protected void writeUsersInfoToProto(ProtoOutputStream proto, long fieldId) {
599        int count = userState.size();
600        for (int i = 0; i < count; i++) {
601            final long userToken = proto.start(fieldId);
602            final int userId = userState.keyAt(i);
603            final PackageUserState state = userState.valueAt(i);
604            proto.write(PackageProto.UserInfoProto.ID, userId);
605            final int installType;
606            if (state.instantApp) {
607                installType = PackageProto.UserInfoProto.INSTANT_APP_INSTALL;
608            } else if (state.installed) {
609                installType = PackageProto.UserInfoProto.FULL_APP_INSTALL;
610            } else {
611                installType = PackageProto.UserInfoProto.NOT_INSTALLED_FOR_USER;
612            }
613            proto.write(PackageProto.UserInfoProto.INSTALL_TYPE, installType);
614            proto.write(PackageProto.UserInfoProto.IS_HIDDEN, state.hidden);
615            proto.write(PackageProto.UserInfoProto.IS_SUSPENDED, state.suspended);
616            proto.write(PackageProto.UserInfoProto.IS_STOPPED, state.stopped);
617            proto.write(PackageProto.UserInfoProto.IS_LAUNCHED, !state.notLaunched);
618            proto.write(PackageProto.UserInfoProto.ENABLED_STATE, state.enabled);
619            proto.write(
620                    PackageProto.UserInfoProto.LAST_DISABLED_APP_CALLER,
621                    state.lastDisableAppCaller);
622            proto.end(userToken);
623        }
624    }
625
626    void setHarmfulAppWarning(int userId, String harmfulAppWarning) {
627        PackageUserState userState = modifyUserState(userId);
628        userState.harmfulAppWarning = harmfulAppWarning;
629    }
630
631    String getHarmfulAppWarning(int userId) {
632        PackageUserState userState = readUserState(userId);
633        return userState.harmfulAppWarning;
634    }
635}
636