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