Home | History | Annotate | Download | only in pm
      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 
     17 package com.android.server.pm;
     18 
     19 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
     20 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
     21 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
     22 
     23 import android.content.pm.ApplicationInfo;
     24 import android.content.pm.IntentFilterVerificationInfo;
     25 import android.content.pm.PackageManager;
     26 import android.content.pm.PackageUserState;
     27 import android.os.storage.VolumeInfo;
     28 import android.service.pm.PackageProto;
     29 import android.util.ArraySet;
     30 import android.util.SparseArray;
     31 import android.util.proto.ProtoOutputStream;
     32 
     33 import com.android.internal.annotations.VisibleForTesting;
     34 import com.google.android.collect.Lists;
     35 
     36 import java.io.File;
     37 import java.util.ArrayList;
     38 import java.util.Arrays;
     39 import java.util.List;
     40 import java.util.Set;
     41 
     42 /**
     43  * Settings base class for pending and resolved classes.
     44  */
     45 abstract class PackageSettingBase extends SettingBase {
     46 
     47     private static final int[] EMPTY_INT_ARRAY = new int[0];
     48 
     49     /**
     50      * Indicates the state of installation. Used by PackageManager to figure out
     51      * incomplete installations. Say a package is being installed (the state is
     52      * set to PKG_INSTALL_INCOMPLETE) and remains so till the package
     53      * installation is successful or unsuccessful in which case the
     54      * PackageManager will no longer maintain state information associated with
     55      * the package. If some exception(like device freeze or battery being pulled
     56      * out) occurs during installation of a package, the PackageManager needs
     57      * this information to clean up the previously failed installation.
     58      */
     59     static final int PKG_INSTALL_COMPLETE = 1;
     60     static final int PKG_INSTALL_INCOMPLETE = 0;
     61 
     62     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