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