PackageSettingBase.java revision 253984ed8c8f39fa0aa9c5f4addf2f44f334c749
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.os.storage.VolumeInfo;
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 */
44abstract 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    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    int[] 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    int 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    PackageSettingBase origPackage;
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            int pVersionCode, int pkgFlags, int pkgPrivateFlags,
153            String parentPackageName, List<String> childPackageNames,
154            String[] usesStaticLibraries, int[] 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, int 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    /**
233     * Makes a shallow copy of the given package settings.
234     *
235     * NOTE: For some fields [such as keySetData, signatures, userState, verificationInfo, etc...],
236     * the original object is copied and a new one is not created.
237     */
238    public void copyFrom(PackageSettingBase orig) {
239        super.copyFrom(orig);
240        doCopy(orig);
241    }
242
243    private void doCopy(PackageSettingBase orig) {
244        childPackageNames = (orig.childPackageNames != null)
245                ? new ArrayList<>(orig.childPackageNames) : null;
246        codePath = orig.codePath;
247        codePathString = orig.codePathString;
248        cpuAbiOverrideString = orig.cpuAbiOverrideString;
249        firstInstallTime = orig.firstInstallTime;
250        installPermissionsFixed = orig.installPermissionsFixed;
251        installStatus = orig.installStatus;
252        installerPackageName = orig.installerPackageName;
253        isOrphaned = orig.isOrphaned;
254        keySetData = orig.keySetData;
255        lastUpdateTime = orig.lastUpdateTime;
256        legacyNativeLibraryPathString = orig.legacyNativeLibraryPathString;
257        // Intentionally skip oldCodePaths; it's not relevant for copies
258        origPackage = orig.origPackage;
259        parentPackageName = orig.parentPackageName;
260        primaryCpuAbiString = orig.primaryCpuAbiString;
261        resourcePath = orig.resourcePath;
262        resourcePathString = orig.resourcePathString;
263        secondaryCpuAbiString = orig.secondaryCpuAbiString;
264        signatures = orig.signatures;
265        timeStamp = orig.timeStamp;
266        uidError = orig.uidError;
267        userState.clear();
268        for (int i=0; i<orig.userState.size(); i++) {
269            userState.put(orig.userState.keyAt(i), orig.userState.valueAt(i));
270        }
271        verificationInfo = orig.verificationInfo;
272        versionCode = orig.versionCode;
273        volumeUuid = orig.volumeUuid;
274        categoryHint = orig.categoryHint;
275        usesStaticLibraries = orig.usesStaticLibraries != null
276                ? Arrays.copyOf(orig.usesStaticLibraries,
277                        orig.usesStaticLibraries.length) : null;
278        usesStaticLibrariesVersions = orig.usesStaticLibrariesVersions != null
279                ? Arrays.copyOf(orig.usesStaticLibrariesVersions,
280                       orig.usesStaticLibrariesVersions.length) : null;
281        updateAvailable = orig.updateAvailable;
282    }
283
284    private PackageUserState modifyUserState(int userId) {
285        PackageUserState state = userState.get(userId);
286        if (state == null) {
287            state = new PackageUserState();
288            userState.put(userId, state);
289        }
290        return state;
291    }
292
293    public PackageUserState readUserState(int userId) {
294        PackageUserState state = userState.get(userId);
295        if (state == null) {
296            return DEFAULT_USER_STATE;
297        }
298        state.categoryHint = categoryHint;
299        return state;
300    }
301
302    void setEnabled(int state, int userId, String callingPackage) {
303        PackageUserState st = modifyUserState(userId);
304        st.enabled = state;
305        st.lastDisableAppCaller = callingPackage;
306    }
307
308    int getEnabled(int userId) {
309        return readUserState(userId).enabled;
310    }
311
312    String getLastDisabledAppCaller(int userId) {
313        return readUserState(userId).lastDisableAppCaller;
314    }
315
316    void setInstalled(boolean inst, int userId) {
317        modifyUserState(userId).installed = inst;
318    }
319
320    boolean getInstalled(int userId) {
321        return readUserState(userId).installed;
322    }
323
324    int getInstallReason(int userId) {
325        return readUserState(userId).installReason;
326    }
327
328    void setInstallReason(int installReason, int userId) {
329        modifyUserState(userId).installReason = installReason;
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, int userId) {
402        modifyUserState(userId).suspended = suspended;
403    }
404
405    boolean getInstantApp(int userId) {
406        return readUserState(userId).instantApp;
407    }
408
409    void setInstantApp(boolean instantApp, int userId) {
410        modifyUserState(userId).instantApp = instantApp;
411    }
412
413    void setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped,
414            boolean notLaunched, boolean hidden, boolean suspended, boolean instantApp,
415            String lastDisableAppCaller, ArraySet<String> enabledComponents,
416            ArraySet<String> disabledComponents, int domainVerifState,
417            int linkGeneration, int installReason) {
418        PackageUserState state = modifyUserState(userId);
419        state.ceDataInode = ceDataInode;
420        state.enabled = enabled;
421        state.installed = installed;
422        state.stopped = stopped;
423        state.notLaunched = notLaunched;
424        state.hidden = hidden;
425        state.suspended = suspended;
426        state.lastDisableAppCaller = lastDisableAppCaller;
427        state.enabledComponents = enabledComponents;
428        state.disabledComponents = disabledComponents;
429        state.domainVerificationStatus = domainVerifState;
430        state.appLinkGeneration = linkGeneration;
431        state.installReason = installReason;
432        state.instantApp = instantApp;
433    }
434
435    ArraySet<String> getEnabledComponents(int userId) {
436        return readUserState(userId).enabledComponents;
437    }
438
439    ArraySet<String> getDisabledComponents(int userId) {
440        return readUserState(userId).disabledComponents;
441    }
442
443    void setEnabledComponents(ArraySet<String> components, int userId) {
444        modifyUserState(userId).enabledComponents = components;
445    }
446
447    void setDisabledComponents(ArraySet<String> components, int userId) {
448        modifyUserState(userId).disabledComponents = components;
449    }
450
451    void setEnabledComponentsCopy(ArraySet<String> components, int userId) {
452        modifyUserState(userId).enabledComponents = components != null
453                ? new ArraySet<String>(components) : null;
454    }
455
456    void setDisabledComponentsCopy(ArraySet<String> components, int userId) {
457        modifyUserState(userId).disabledComponents = components != null
458                ? new ArraySet<String>(components) : null;
459    }
460
461    PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) {
462        PackageUserState state = modifyUserState(userId);
463        if (disabled && state.disabledComponents == null) {
464            state.disabledComponents = new ArraySet<String>(1);
465        }
466        if (enabled && state.enabledComponents == null) {
467            state.enabledComponents = new ArraySet<String>(1);
468        }
469        return state;
470    }
471
472    void addDisabledComponent(String componentClassName, int userId) {
473        modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName);
474    }
475
476    void addEnabledComponent(String componentClassName, int userId) {
477        modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName);
478    }
479
480    boolean enableComponentLPw(String componentClassName, int userId) {
481        PackageUserState state = modifyUserStateComponents(userId, false, true);
482        boolean changed = state.disabledComponents != null
483                ? state.disabledComponents.remove(componentClassName) : false;
484        changed |= state.enabledComponents.add(componentClassName);
485        return changed;
486    }
487
488    boolean disableComponentLPw(String componentClassName, int userId) {
489        PackageUserState state = modifyUserStateComponents(userId, true, false);
490        boolean changed = state.enabledComponents != null
491                ? state.enabledComponents.remove(componentClassName) : false;
492        changed |= state.disabledComponents.add(componentClassName);
493        return changed;
494    }
495
496    boolean restoreComponentLPw(String componentClassName, int userId) {
497        PackageUserState state = modifyUserStateComponents(userId, true, true);
498        boolean changed = state.disabledComponents != null
499                ? state.disabledComponents.remove(componentClassName) : false;
500        changed |= state.enabledComponents != null
501                ? state.enabledComponents.remove(componentClassName) : false;
502        return changed;
503    }
504
505    int getCurrentEnabledStateLPr(String componentName, int userId) {
506        PackageUserState state = readUserState(userId);
507        if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) {
508            return COMPONENT_ENABLED_STATE_ENABLED;
509        } else if (state.disabledComponents != null
510                && state.disabledComponents.contains(componentName)) {
511            return COMPONENT_ENABLED_STATE_DISABLED;
512        } else {
513            return COMPONENT_ENABLED_STATE_DEFAULT;
514        }
515    }
516
517    void removeUser(int userId) {
518        userState.delete(userId);
519    }
520
521    public int[] getNotInstalledUserIds() {
522        int count = 0;
523        int userStateCount = userState.size();
524        for (int i = 0; i < userStateCount; i++) {
525            if (userState.valueAt(i).installed == false) {
526                count++;
527            }
528        }
529        if (count == 0) return EMPTY_INT_ARRAY;
530        int[] excludedUserIds = new int[count];
531        int idx = 0;
532        for (int i = 0; i < userStateCount; i++) {
533            if (userState.valueAt(i).installed == false) {
534                excludedUserIds[idx++] = userState.keyAt(i);
535            }
536        }
537        return excludedUserIds;
538    }
539
540    IntentFilterVerificationInfo getIntentFilterVerificationInfo() {
541        return verificationInfo;
542    }
543
544    void setIntentFilterVerificationInfo(IntentFilterVerificationInfo info) {
545        verificationInfo = info;
546    }
547
548    // Returns a packed value as a long:
549    //
550    // high 'int'-sized word: link status: undefined/ask/never/always.
551    // low 'int'-sized word: relative priority among 'always' results.
552    long getDomainVerificationStatusForUser(int userId) {
553        PackageUserState state = readUserState(userId);
554        long result = (long) state.appLinkGeneration;
555        result |= ((long) state.domainVerificationStatus) << 32;
556        return result;
557    }
558
559    void setDomainVerificationStatusForUser(final int status, int generation, int userId) {
560        PackageUserState state = modifyUserState(userId);
561        state.domainVerificationStatus = status;
562        if (status == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
563            state.appLinkGeneration = generation;
564        }
565    }
566
567    void clearDomainVerificationStatusForUser(int userId) {
568        modifyUserState(userId).domainVerificationStatus =
569                PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
570    }
571
572    protected void writeUsersInfoToProto(ProtoOutputStream proto, long fieldId) {
573        int count = userState.size();
574        for (int i = 0; i < count; i++) {
575            final long userToken = proto.start(fieldId);
576            final int userId = userState.keyAt(i);
577            final PackageUserState state = userState.valueAt(i);
578            proto.write(PackageProto.UserInfoProto.ID, userId);
579            final int installType;
580            if (state.instantApp) {
581                installType = PackageProto.UserInfoProto.INSTANT_APP_INSTALL;
582            } else if (state.installed) {
583                installType = PackageProto.UserInfoProto.FULL_APP_INSTALL;
584            } else {
585                installType = PackageProto.UserInfoProto.NOT_INSTALLED_FOR_USER;
586            }
587            proto.write(PackageProto.UserInfoProto.INSTALL_TYPE, installType);
588            proto.write(PackageProto.UserInfoProto.IS_HIDDEN, state.hidden);
589            proto.write(PackageProto.UserInfoProto.IS_SUSPENDED, state.suspended);
590            proto.write(PackageProto.UserInfoProto.IS_STOPPED, state.stopped);
591            proto.write(PackageProto.UserInfoProto.IS_LAUNCHED, !state.notLaunched);
592            proto.write(PackageProto.UserInfoProto.ENABLED_STATE, state.enabled);
593            proto.write(
594                    PackageProto.UserInfoProto.LAST_DISABLED_APP_CALLER,
595                    state.lastDisableAppCaller);
596            proto.end(userToken);
597        }
598    }
599}
600