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, int userId) {
334        modifyUserState(userId).overlayPaths = overlayPaths == null ? null :
335            overlayPaths.toArray(new String[overlayPaths.size()]);
336    }
337
338    String[] getOverlayPaths(int userId) {
339        return readUserState(userId).overlayPaths;
340    }
341
342    /** Only use for testing. Do NOT use in production code. */
343    @VisibleForTesting
344    SparseArray<PackageUserState> getUserState() {
345        return userState;
346    }
347
348    boolean isAnyInstalled(int[] users) {
349        for (int user: users) {
350            if (readUserState(user).installed) {
351                return true;
352            }
353        }
354        return false;
355    }
356
357    int[] queryInstalledUsers(int[] users, boolean installed) {
358        int num = 0;
359        for (int user : users) {
360            if (getInstalled(user) == installed) {
361                num++;
362            }
363        }
364        int[] res = new int[num];
365        num = 0;
366        for (int user : users) {
367            if (getInstalled(user) == installed) {
368                res[num] = user;
369                num++;
370            }
371        }
372        return res;
373    }
374
375    long getCeDataInode(int userId) {
376        return readUserState(userId).ceDataInode;
377    }
378
379    void setCeDataInode(long ceDataInode, int userId) {
380        modifyUserState(userId).ceDataInode = ceDataInode;
381    }
382
383    boolean getStopped(int userId) {
384        return readUserState(userId).stopped;
385    }
386
387    void setStopped(boolean stop, int userId) {
388        modifyUserState(userId).stopped = stop;
389    }
390
391    boolean getNotLaunched(int userId) {
392        return readUserState(userId).notLaunched;
393    }
394
395    void setNotLaunched(boolean stop, int userId) {
396        modifyUserState(userId).notLaunched = stop;
397    }
398
399    boolean getHidden(int userId) {
400        return readUserState(userId).hidden;
401    }
402
403    void setHidden(boolean hidden, int userId) {
404        modifyUserState(userId).hidden = hidden;
405    }
406
407    boolean getSuspended(int userId) {
408        return readUserState(userId).suspended;
409    }
410
411    void setSuspended(boolean suspended, int userId) {
412        modifyUserState(userId).suspended = suspended;
413    }
414
415    boolean getInstantApp(int userId) {
416        return readUserState(userId).instantApp;
417    }
418
419    void setInstantApp(boolean instantApp, int userId) {
420        modifyUserState(userId).instantApp = instantApp;
421    }
422
423    void setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped,
424            boolean notLaunched, boolean hidden, boolean suspended, boolean instantApp,
425            String lastDisableAppCaller, ArraySet<String> enabledComponents,
426            ArraySet<String> disabledComponents, int domainVerifState,
427            int linkGeneration, int installReason) {
428        PackageUserState state = modifyUserState(userId);
429        state.ceDataInode = ceDataInode;
430        state.enabled = enabled;
431        state.installed = installed;
432        state.stopped = stopped;
433        state.notLaunched = notLaunched;
434        state.hidden = hidden;
435        state.suspended = suspended;
436        state.lastDisableAppCaller = lastDisableAppCaller;
437        state.enabledComponents = enabledComponents;
438        state.disabledComponents = disabledComponents;
439        state.domainVerificationStatus = domainVerifState;
440        state.appLinkGeneration = linkGeneration;
441        state.installReason = installReason;
442        state.instantApp = instantApp;
443    }
444
445    ArraySet<String> getEnabledComponents(int userId) {
446        return readUserState(userId).enabledComponents;
447    }
448
449    ArraySet<String> getDisabledComponents(int userId) {
450        return readUserState(userId).disabledComponents;
451    }
452
453    void setEnabledComponents(ArraySet<String> components, int userId) {
454        modifyUserState(userId).enabledComponents = components;
455    }
456
457    void setDisabledComponents(ArraySet<String> components, int userId) {
458        modifyUserState(userId).disabledComponents = components;
459    }
460
461    void setEnabledComponentsCopy(ArraySet<String> components, int userId) {
462        modifyUserState(userId).enabledComponents = components != null
463                ? new ArraySet<String>(components) : null;
464    }
465
466    void setDisabledComponentsCopy(ArraySet<String> components, int userId) {
467        modifyUserState(userId).disabledComponents = components != null
468                ? new ArraySet<String>(components) : null;
469    }
470
471    PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) {
472        PackageUserState state = modifyUserState(userId);
473        if (disabled && state.disabledComponents == null) {
474            state.disabledComponents = new ArraySet<String>(1);
475        }
476        if (enabled && state.enabledComponents == null) {
477            state.enabledComponents = new ArraySet<String>(1);
478        }
479        return state;
480    }
481
482    void addDisabledComponent(String componentClassName, int userId) {
483        modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName);
484    }
485
486    void addEnabledComponent(String componentClassName, int userId) {
487        modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName);
488    }
489
490    boolean enableComponentLPw(String componentClassName, int userId) {
491        PackageUserState state = modifyUserStateComponents(userId, false, true);
492        boolean changed = state.disabledComponents != null
493                ? state.disabledComponents.remove(componentClassName) : false;
494        changed |= state.enabledComponents.add(componentClassName);
495        return changed;
496    }
497
498    boolean disableComponentLPw(String componentClassName, int userId) {
499        PackageUserState state = modifyUserStateComponents(userId, true, false);
500        boolean changed = state.enabledComponents != null
501                ? state.enabledComponents.remove(componentClassName) : false;
502        changed |= state.disabledComponents.add(componentClassName);
503        return changed;
504    }
505
506    boolean restoreComponentLPw(String componentClassName, int userId) {
507        PackageUserState state = modifyUserStateComponents(userId, true, true);
508        boolean changed = state.disabledComponents != null
509                ? state.disabledComponents.remove(componentClassName) : false;
510        changed |= state.enabledComponents != null
511                ? state.enabledComponents.remove(componentClassName) : false;
512        return changed;
513    }
514
515    int getCurrentEnabledStateLPr(String componentName, int userId) {
516        PackageUserState state = readUserState(userId);
517        if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) {
518            return COMPONENT_ENABLED_STATE_ENABLED;
519        } else if (state.disabledComponents != null
520                && state.disabledComponents.contains(componentName)) {
521            return COMPONENT_ENABLED_STATE_DISABLED;
522        } else {
523            return COMPONENT_ENABLED_STATE_DEFAULT;
524        }
525    }
526
527    void removeUser(int userId) {
528        userState.delete(userId);
529    }
530
531    public int[] getNotInstalledUserIds() {
532        int count = 0;
533        int userStateCount = userState.size();
534        for (int i = 0; i < userStateCount; i++) {
535            if (userState.valueAt(i).installed == false) {
536                count++;
537            }
538        }
539        if (count == 0) return EMPTY_INT_ARRAY;
540        int[] excludedUserIds = new int[count];
541        int idx = 0;
542        for (int i = 0; i < userStateCount; i++) {
543            if (userState.valueAt(i).installed == false) {
544                excludedUserIds[idx++] = userState.keyAt(i);
545            }
546        }
547        return excludedUserIds;
548    }
549
550    IntentFilterVerificationInfo getIntentFilterVerificationInfo() {
551        return verificationInfo;
552    }
553
554    void setIntentFilterVerificationInfo(IntentFilterVerificationInfo info) {
555        verificationInfo = info;
556    }
557
558    // Returns a packed value as a long:
559    //
560    // high 'int'-sized word: link status: undefined/ask/never/always.
561    // low 'int'-sized word: relative priority among 'always' results.
562    long getDomainVerificationStatusForUser(int userId) {
563        PackageUserState state = readUserState(userId);
564        long result = (long) state.appLinkGeneration;
565        result |= ((long) state.domainVerificationStatus) << 32;
566        return result;
567    }
568
569    void setDomainVerificationStatusForUser(final int status, int generation, int userId) {
570        PackageUserState state = modifyUserState(userId);
571        state.domainVerificationStatus = status;
572        if (status == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
573            state.appLinkGeneration = generation;
574        }
575    }
576
577    void clearDomainVerificationStatusForUser(int userId) {
578        modifyUserState(userId).domainVerificationStatus =
579                PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
580    }
581
582    protected void writeUsersInfoToProto(ProtoOutputStream proto, long fieldId) {
583        int count = userState.size();
584        for (int i = 0; i < count; i++) {
585            final long userToken = proto.start(fieldId);
586            final int userId = userState.keyAt(i);
587            final PackageUserState state = userState.valueAt(i);
588            proto.write(PackageProto.UserInfoProto.ID, userId);
589            final int installType;
590            if (state.instantApp) {
591                installType = PackageProto.UserInfoProto.INSTANT_APP_INSTALL;
592            } else if (state.installed) {
593                installType = PackageProto.UserInfoProto.FULL_APP_INSTALL;
594            } else {
595                installType = PackageProto.UserInfoProto.NOT_INSTALLED_FOR_USER;
596            }
597            proto.write(PackageProto.UserInfoProto.INSTALL_TYPE, installType);
598            proto.write(PackageProto.UserInfoProto.IS_HIDDEN, state.hidden);
599            proto.write(PackageProto.UserInfoProto.IS_SUSPENDED, state.suspended);
600            proto.write(PackageProto.UserInfoProto.IS_STOPPED, state.stopped);
601            proto.write(PackageProto.UserInfoProto.IS_LAUNCHED, !state.notLaunched);
602            proto.write(PackageProto.UserInfoProto.ENABLED_STATE, state.enabled);
603            proto.write(
604                    PackageProto.UserInfoProto.LAST_DISABLED_APP_CALLER,
605                    state.lastDisableAppCaller);
606            proto.end(userToken);
607        }
608    }
609}
610