PackageSettingBase.java revision b274947dfb03f04872546774af0f8770ade5bed7
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;
34import com.google.android.collect.Lists;
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 */
45abstract 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    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    int[] 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    int 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    PackageSettingBase origPackage;
136
137    /** Package name of the app that installed this package */
138    String installerPackageName;
139    /** Indicates if the package that installed this app has been uninstalled */
140    boolean isOrphaned;
141    /** UUID of {@link VolumeInfo} hosting this app */
142    String volumeUuid;
143    /** The category of this app, as hinted by the installer */
144    int categoryHint = ApplicationInfo.CATEGORY_UNDEFINED;
145    /** Whether or not an update is available. Ostensibly only for instant apps. */
146    boolean updateAvailable;
147
148    IntentFilterVerificationInfo verificationInfo;
149
150    PackageSettingBase(String name, String realName, File codePath, File resourcePath,
151            String legacyNativeLibraryPathString, String primaryCpuAbiString,
152            String secondaryCpuAbiString, String cpuAbiOverrideString,
153            int pVersionCode, int pkgFlags, int pkgPrivateFlags,
154            String parentPackageName, List<String> childPackageNames,
155            String[] usesStaticLibraries, int[] usesStaticLibrariesVersions) {
156        super(pkgFlags, pkgPrivateFlags);
157        this.name = name;
158        this.realName = realName;
159        this.parentPackageName = parentPackageName;
160        this.childPackageNames = (childPackageNames != null)
161                ? new ArrayList<>(childPackageNames) : null;
162        this.usesStaticLibraries = usesStaticLibraries;
163        this.usesStaticLibrariesVersions = usesStaticLibrariesVersions;
164        init(codePath, resourcePath, legacyNativeLibraryPathString, primaryCpuAbiString,
165                secondaryCpuAbiString, cpuAbiOverrideString, pVersionCode);
166    }
167
168    /**
169     * New instance of PackageSetting with one-level-deep cloning.
170     * <p>
171     * IMPORTANT: With a shallow copy, we do NOT create new contained objects.
172     * This means, for example, changes to the user state of the original PackageSetting
173     * will also change the user state in its copy.
174     */
175    PackageSettingBase(PackageSettingBase base, String realName) {
176        super(base);
177        name = base.name;
178        this.realName = realName;
179        doCopy(base);
180    }
181
182    void init(File codePath, File resourcePath, String legacyNativeLibraryPathString,
183              String primaryCpuAbiString, String secondaryCpuAbiString,
184              String cpuAbiOverrideString, int pVersionCode) {
185        this.codePath = codePath;
186        this.codePathString = codePath.toString();
187        this.resourcePath = resourcePath;
188        this.resourcePathString = resourcePath.toString();
189        this.legacyNativeLibraryPathString = legacyNativeLibraryPathString;
190        this.primaryCpuAbiString = primaryCpuAbiString;
191        this.secondaryCpuAbiString = secondaryCpuAbiString;
192        this.cpuAbiOverrideString = cpuAbiOverrideString;
193        this.versionCode = pVersionCode;
194        this.signatures = new PackageSignatures();
195    }
196
197    public void setInstallerPackageName(String packageName) {
198        installerPackageName = packageName;
199    }
200
201    public String getInstallerPackageName() {
202        return installerPackageName;
203    }
204
205    public void setVolumeUuid(String volumeUuid) {
206        this.volumeUuid = volumeUuid;
207    }
208
209    public String getVolumeUuid() {
210        return volumeUuid;
211    }
212
213    public void setInstallStatus(int newStatus) {
214        installStatus = newStatus;
215    }
216
217    public int getInstallStatus() {
218        return installStatus;
219    }
220
221    public void setTimeStamp(long newStamp) {
222        timeStamp = newStamp;
223    }
224
225    public void setUpdateAvailable(boolean updateAvailable) {
226        this.updateAvailable = updateAvailable;
227    }
228
229    public boolean isUpdateAvailable() {
230        return updateAvailable;
231    }
232
233    /**
234     * Makes a shallow copy of the given package settings.
235     *
236     * NOTE: For some fields [such as keySetData, signatures, userState, verificationInfo, etc...],
237     * the original object is copied and a new one is not created.
238     */
239    public void copyFrom(PackageSettingBase orig) {
240        super.copyFrom(orig);
241        doCopy(orig);
242    }
243
244    private void doCopy(PackageSettingBase orig) {
245        childPackageNames = (orig.childPackageNames != null)
246                ? new ArrayList<>(orig.childPackageNames) : null;
247        codePath = orig.codePath;
248        codePathString = orig.codePathString;
249        cpuAbiOverrideString = orig.cpuAbiOverrideString;
250        firstInstallTime = orig.firstInstallTime;
251        installPermissionsFixed = orig.installPermissionsFixed;
252        installStatus = orig.installStatus;
253        installerPackageName = orig.installerPackageName;
254        isOrphaned = orig.isOrphaned;
255        keySetData = orig.keySetData;
256        lastUpdateTime = orig.lastUpdateTime;
257        legacyNativeLibraryPathString = orig.legacyNativeLibraryPathString;
258        // Intentionally skip oldCodePaths; it's not relevant for copies
259        origPackage = orig.origPackage;
260        parentPackageName = orig.parentPackageName;
261        primaryCpuAbiString = orig.primaryCpuAbiString;
262        resourcePath = orig.resourcePath;
263        resourcePathString = orig.resourcePathString;
264        secondaryCpuAbiString = orig.secondaryCpuAbiString;
265        signatures = orig.signatures;
266        timeStamp = orig.timeStamp;
267        uidError = orig.uidError;
268        userState.clear();
269        for (int i=0; i<orig.userState.size(); i++) {
270            userState.put(orig.userState.keyAt(i), orig.userState.valueAt(i));
271        }
272        verificationInfo = orig.verificationInfo;
273        versionCode = orig.versionCode;
274        volumeUuid = orig.volumeUuid;
275        categoryHint = orig.categoryHint;
276        usesStaticLibraries = orig.usesStaticLibraries != null
277                ? Arrays.copyOf(orig.usesStaticLibraries,
278                        orig.usesStaticLibraries.length) : null;
279        usesStaticLibrariesVersions = orig.usesStaticLibrariesVersions != null
280                ? Arrays.copyOf(orig.usesStaticLibrariesVersions,
281                       orig.usesStaticLibrariesVersions.length) : null;
282        updateAvailable = orig.updateAvailable;
283    }
284
285    private PackageUserState modifyUserState(int userId) {
286        PackageUserState state = userState.get(userId);
287        if (state == null) {
288            state = new PackageUserState();
289            userState.put(userId, state);
290        }
291        return state;
292    }
293
294    public PackageUserState readUserState(int userId) {
295        PackageUserState state = userState.get(userId);
296        if (state == null) {
297            return DEFAULT_USER_STATE;
298        }
299        state.categoryHint = categoryHint;
300        return state;
301    }
302
303    void setEnabled(int state, int userId, String callingPackage) {
304        PackageUserState st = modifyUserState(userId);
305        st.enabled = state;
306        st.lastDisableAppCaller = callingPackage;
307    }
308
309    int getEnabled(int userId) {
310        return readUserState(userId).enabled;
311    }
312
313    String getLastDisabledAppCaller(int userId) {
314        return readUserState(userId).lastDisableAppCaller;
315    }
316
317    void setInstalled(boolean inst, int userId) {
318        modifyUserState(userId).installed = inst;
319    }
320
321    boolean getInstalled(int userId) {
322        return readUserState(userId).installed;
323    }
324
325    int getInstallReason(int userId) {
326        return readUserState(userId).installReason;
327    }
328
329    void setInstallReason(int installReason, int userId) {
330        modifyUserState(userId).installReason = installReason;
331    }
332
333    void setOverlayPaths(List<String> overlayPaths, String[] frameworkOverlayPaths, int userId) {
334        if (overlayPaths == null && frameworkOverlayPaths == null) {
335            modifyUserState(userId).overlayPaths = null;
336            return;
337        }
338        final List<String> paths;
339        if (frameworkOverlayPaths == null) {
340            paths = overlayPaths;
341        } else {
342            paths = Lists.newArrayList(frameworkOverlayPaths);
343            if (overlayPaths != null) {
344                paths.addAll(overlayPaths);
345            }
346        }
347        modifyUserState(userId).overlayPaths = paths.toArray(new String[paths.size()]);
348    }
349
350    String[] getOverlayPaths(int userId) {
351        return readUserState(userId).overlayPaths;
352    }
353
354    /** Only use for testing. Do NOT use in production code. */
355    @VisibleForTesting
356    SparseArray<PackageUserState> getUserState() {
357        return userState;
358    }
359
360    boolean isAnyInstalled(int[] users) {
361        for (int user: users) {
362            if (readUserState(user).installed) {
363                return true;
364            }
365        }
366        return false;
367    }
368
369    int[] queryInstalledUsers(int[] users, boolean installed) {
370        int num = 0;
371        for (int user : users) {
372            if (getInstalled(user) == installed) {
373                num++;
374            }
375        }
376        int[] res = new int[num];
377        num = 0;
378        for (int user : users) {
379            if (getInstalled(user) == installed) {
380                res[num] = user;
381                num++;
382            }
383        }
384        return res;
385    }
386
387    long getCeDataInode(int userId) {
388        return readUserState(userId).ceDataInode;
389    }
390
391    void setCeDataInode(long ceDataInode, int userId) {
392        modifyUserState(userId).ceDataInode = ceDataInode;
393    }
394
395    boolean getStopped(int userId) {
396        return readUserState(userId).stopped;
397    }
398
399    void setStopped(boolean stop, int userId) {
400        modifyUserState(userId).stopped = stop;
401    }
402
403    boolean getNotLaunched(int userId) {
404        return readUserState(userId).notLaunched;
405    }
406
407    void setNotLaunched(boolean stop, int userId) {
408        modifyUserState(userId).notLaunched = stop;
409    }
410
411    boolean getHidden(int userId) {
412        return readUserState(userId).hidden;
413    }
414
415    void setHidden(boolean hidden, int userId) {
416        modifyUserState(userId).hidden = hidden;
417    }
418
419    boolean getSuspended(int userId) {
420        return readUserState(userId).suspended;
421    }
422
423    void setSuspended(boolean suspended, int userId) {
424        modifyUserState(userId).suspended = suspended;
425    }
426
427    boolean getInstantApp(int userId) {
428        return readUserState(userId).instantApp;
429    }
430
431    void setInstantApp(boolean instantApp, int userId) {
432        modifyUserState(userId).instantApp = instantApp;
433    }
434
435    void setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped,
436            boolean notLaunched, boolean hidden, boolean suspended, boolean instantApp,
437            String lastDisableAppCaller, ArraySet<String> enabledComponents,
438            ArraySet<String> disabledComponents, int domainVerifState,
439            int linkGeneration, int installReason) {
440        PackageUserState state = modifyUserState(userId);
441        state.ceDataInode = ceDataInode;
442        state.enabled = enabled;
443        state.installed = installed;
444        state.stopped = stopped;
445        state.notLaunched = notLaunched;
446        state.hidden = hidden;
447        state.suspended = suspended;
448        state.lastDisableAppCaller = lastDisableAppCaller;
449        state.enabledComponents = enabledComponents;
450        state.disabledComponents = disabledComponents;
451        state.domainVerificationStatus = domainVerifState;
452        state.appLinkGeneration = linkGeneration;
453        state.installReason = installReason;
454        state.instantApp = instantApp;
455    }
456
457    ArraySet<String> getEnabledComponents(int userId) {
458        return readUserState(userId).enabledComponents;
459    }
460
461    ArraySet<String> getDisabledComponents(int userId) {
462        return readUserState(userId).disabledComponents;
463    }
464
465    void setEnabledComponents(ArraySet<String> components, int userId) {
466        modifyUserState(userId).enabledComponents = components;
467    }
468
469    void setDisabledComponents(ArraySet<String> components, int userId) {
470        modifyUserState(userId).disabledComponents = components;
471    }
472
473    void setEnabledComponentsCopy(ArraySet<String> components, int userId) {
474        modifyUserState(userId).enabledComponents = components != null
475                ? new ArraySet<String>(components) : null;
476    }
477
478    void setDisabledComponentsCopy(ArraySet<String> components, int userId) {
479        modifyUserState(userId).disabledComponents = components != null
480                ? new ArraySet<String>(components) : null;
481    }
482
483    PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) {
484        PackageUserState state = modifyUserState(userId);
485        if (disabled && state.disabledComponents == null) {
486            state.disabledComponents = new ArraySet<String>(1);
487        }
488        if (enabled && state.enabledComponents == null) {
489            state.enabledComponents = new ArraySet<String>(1);
490        }
491        return state;
492    }
493
494    void addDisabledComponent(String componentClassName, int userId) {
495        modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName);
496    }
497
498    void addEnabledComponent(String componentClassName, int userId) {
499        modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName);
500    }
501
502    boolean enableComponentLPw(String componentClassName, int userId) {
503        PackageUserState state = modifyUserStateComponents(userId, false, true);
504        boolean changed = state.disabledComponents != null
505                ? state.disabledComponents.remove(componentClassName) : false;
506        changed |= state.enabledComponents.add(componentClassName);
507        return changed;
508    }
509
510    boolean disableComponentLPw(String componentClassName, int userId) {
511        PackageUserState state = modifyUserStateComponents(userId, true, false);
512        boolean changed = state.enabledComponents != null
513                ? state.enabledComponents.remove(componentClassName) : false;
514        changed |= state.disabledComponents.add(componentClassName);
515        return changed;
516    }
517
518    boolean restoreComponentLPw(String componentClassName, int userId) {
519        PackageUserState state = modifyUserStateComponents(userId, true, true);
520        boolean changed = state.disabledComponents != null
521                ? state.disabledComponents.remove(componentClassName) : false;
522        changed |= state.enabledComponents != null
523                ? state.enabledComponents.remove(componentClassName) : false;
524        return changed;
525    }
526
527    int getCurrentEnabledStateLPr(String componentName, int userId) {
528        PackageUserState state = readUserState(userId);
529        if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) {
530            return COMPONENT_ENABLED_STATE_ENABLED;
531        } else if (state.disabledComponents != null
532                && state.disabledComponents.contains(componentName)) {
533            return COMPONENT_ENABLED_STATE_DISABLED;
534        } else {
535            return COMPONENT_ENABLED_STATE_DEFAULT;
536        }
537    }
538
539    void removeUser(int userId) {
540        userState.delete(userId);
541    }
542
543    public int[] getNotInstalledUserIds() {
544        int count = 0;
545        int userStateCount = userState.size();
546        for (int i = 0; i < userStateCount; i++) {
547            if (userState.valueAt(i).installed == false) {
548                count++;
549            }
550        }
551        if (count == 0) return EMPTY_INT_ARRAY;
552        int[] excludedUserIds = new int[count];
553        int idx = 0;
554        for (int i = 0; i < userStateCount; i++) {
555            if (userState.valueAt(i).installed == false) {
556                excludedUserIds[idx++] = userState.keyAt(i);
557            }
558        }
559        return excludedUserIds;
560    }
561
562    IntentFilterVerificationInfo getIntentFilterVerificationInfo() {
563        return verificationInfo;
564    }
565
566    void setIntentFilterVerificationInfo(IntentFilterVerificationInfo info) {
567        verificationInfo = info;
568    }
569
570    // Returns a packed value as a long:
571    //
572    // high 'int'-sized word: link status: undefined/ask/never/always.
573    // low 'int'-sized word: relative priority among 'always' results.
574    long getDomainVerificationStatusForUser(int userId) {
575        PackageUserState state = readUserState(userId);
576        long result = (long) state.appLinkGeneration;
577        result |= ((long) state.domainVerificationStatus) << 32;
578        return result;
579    }
580
581    void setDomainVerificationStatusForUser(final int status, int generation, int userId) {
582        PackageUserState state = modifyUserState(userId);
583        state.domainVerificationStatus = status;
584        if (status == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
585            state.appLinkGeneration = generation;
586        }
587    }
588
589    void clearDomainVerificationStatusForUser(int userId) {
590        modifyUserState(userId).domainVerificationStatus =
591                PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
592    }
593
594    protected void writeUsersInfoToProto(ProtoOutputStream proto, long fieldId) {
595        int count = userState.size();
596        for (int i = 0; i < count; i++) {
597            final long userToken = proto.start(fieldId);
598            final int userId = userState.keyAt(i);
599            final PackageUserState state = userState.valueAt(i);
600            proto.write(PackageProto.UserInfoProto.ID, userId);
601            final int installType;
602            if (state.instantApp) {
603                installType = PackageProto.UserInfoProto.INSTANT_APP_INSTALL;
604            } else if (state.installed) {
605                installType = PackageProto.UserInfoProto.FULL_APP_INSTALL;
606            } else {
607                installType = PackageProto.UserInfoProto.NOT_INSTALLED_FOR_USER;
608            }
609            proto.write(PackageProto.UserInfoProto.INSTALL_TYPE, installType);
610            proto.write(PackageProto.UserInfoProto.IS_HIDDEN, state.hidden);
611            proto.write(PackageProto.UserInfoProto.IS_SUSPENDED, state.suspended);
612            proto.write(PackageProto.UserInfoProto.IS_STOPPED, state.stopped);
613            proto.write(PackageProto.UserInfoProto.IS_LAUNCHED, !state.notLaunched);
614            proto.write(PackageProto.UserInfoProto.ENABLED_STATE, state.enabled);
615            proto.write(
616                    PackageProto.UserInfoProto.LAST_DISABLED_APP_CALLER,
617                    state.lastDisableAppCaller);
618            proto.end(userToken);
619        }
620    }
621}
622