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.IntentFilterVerificationInfo;
     24 import android.content.pm.PackageManager;
     25 import android.content.pm.PackageUserState;
     26 import android.os.storage.VolumeInfo;
     27 import android.util.ArraySet;
     28 import android.util.SparseArray;
     29 
     30 import java.io.File;
     31 
     32 /**
     33  * Settings base class for pending and resolved classes.
     34  */
     35 abstract class PackageSettingBase extends SettingBase {
     36     /**
     37      * Indicates the state of installation. Used by PackageManager to figure out
     38      * incomplete installations. Say a package is being installed (the state is
     39      * set to PKG_INSTALL_INCOMPLETE) and remains so till the package
     40      * installation is successful or unsuccessful in which case the
     41      * PackageManager will no longer maintain state information associated with
     42      * the package. If some exception(like device freeze or battery being pulled
     43      * out) occurs during installation of a package, the PackageManager needs
     44      * this information to clean up the previously failed installation.
     45      */
     46     static final int PKG_INSTALL_COMPLETE = 1;
     47     static final int PKG_INSTALL_INCOMPLETE = 0;
     48 
     49     final String name;
     50     final String realName;
     51 
     52     /**
     53      * Path where this package was found on disk. For monolithic packages
     54      * this is path to single base APK file; for cluster packages this is
     55      * path to the cluster directory.
     56      */
     57     File codePath;
     58     String codePathString;
     59     File resourcePath;
     60     String resourcePathString;
     61 
     62     /**
     63      * The path under which native libraries have been unpacked. This path is
     64      * always derived at runtime, and is only stored here for cleanup when a
     65      * package is uninstalled.
     66      */
     67     @Deprecated
     68     String legacyNativeLibraryPathString;
     69 
     70     /**
     71      * The primary CPU abi for this package. This value is regenerated at every
     72      * boot scan.
     73      */
     74     String primaryCpuAbiString;
     75 
     76     /**
     77      * The secondary CPU abi for this package. This value is regenerated at every
     78      * boot scan.
     79      */
     80     String secondaryCpuAbiString;
     81 
     82     /**
     83      * The install time CPU override, if any. This value is written at install time
     84      * and doesn't change during the life of an install. If non-null,
     85      * {@code primaryCpuAbiString} will contain the same value.
     86      */
     87     String cpuAbiOverrideString;
     88 
     89     long timeStamp;
     90     long firstInstallTime;
     91     long lastUpdateTime;
     92     int versionCode;
     93 
     94     boolean uidError;
     95 
     96     PackageSignatures signatures = new PackageSignatures();
     97 
     98     boolean installPermissionsFixed;
     99 
    100     PackageKeySetData keySetData = new PackageKeySetData();
    101 
    102     private static final PackageUserState DEFAULT_USER_STATE = new PackageUserState();
    103 
    104     // Whether this package is currently stopped, thus can not be
    105     // started until explicitly launched by the user.
    106     private final SparseArray<PackageUserState> userState = new SparseArray<PackageUserState>();
    107 
    108     int installStatus = PKG_INSTALL_COMPLETE;
    109 
    110     /**
    111      * Non-persisted value indicating this package has been temporarily frozen,
    112      * usually during a critical section of the package update pipeline. The
    113      * platform will refuse to launch packages in a frozen state.
    114      */
    115     boolean frozen = false;
    116 
    117     PackageSettingBase origPackage;
    118 
    119     /** Package name of the app that installed this package */
    120     String installerPackageName;
    121     /** UUID of {@link VolumeInfo} hosting this app */
    122     String volumeUuid;
    123 
    124     IntentFilterVerificationInfo verificationInfo;
    125 
    126     PackageSettingBase(String name, String realName, File codePath, File resourcePath,
    127             String legacyNativeLibraryPathString, String primaryCpuAbiString,
    128             String secondaryCpuAbiString, String cpuAbiOverrideString,
    129             int pVersionCode, int pkgFlags, int pkgPrivateFlags) {
    130         super(pkgFlags, pkgPrivateFlags);
    131         this.name = name;
    132         this.realName = realName;
    133         init(codePath, resourcePath, legacyNativeLibraryPathString, primaryCpuAbiString,
    134                 secondaryCpuAbiString, cpuAbiOverrideString, pVersionCode);
    135     }
    136 
    137     /**
    138      * New instance of PackageSetting with one-level-deep cloning.
    139      */
    140     @SuppressWarnings("unchecked")
    141     PackageSettingBase(PackageSettingBase base) {
    142         super(base);
    143 
    144         name = base.name;
    145         realName = base.realName;
    146         codePath = base.codePath;
    147         codePathString = base.codePathString;
    148         resourcePath = base.resourcePath;
    149         resourcePathString = base.resourcePathString;
    150         legacyNativeLibraryPathString = base.legacyNativeLibraryPathString;
    151         primaryCpuAbiString = base.primaryCpuAbiString;
    152         secondaryCpuAbiString = base.secondaryCpuAbiString;
    153         cpuAbiOverrideString = base.cpuAbiOverrideString;
    154         timeStamp = base.timeStamp;
    155         firstInstallTime = base.firstInstallTime;
    156         lastUpdateTime = base.lastUpdateTime;
    157         versionCode = base.versionCode;
    158 
    159         uidError = base.uidError;
    160 
    161         signatures = new PackageSignatures(base.signatures);
    162 
    163         installPermissionsFixed = base.installPermissionsFixed;
    164         userState.clear();
    165         for (int i=0; i<base.userState.size(); i++) {
    166             userState.put(base.userState.keyAt(i),
    167                     new PackageUserState(base.userState.valueAt(i)));
    168         }
    169         installStatus = base.installStatus;
    170 
    171         origPackage = base.origPackage;
    172 
    173         installerPackageName = base.installerPackageName;
    174         volumeUuid = base.volumeUuid;
    175 
    176         keySetData = new PackageKeySetData(base.keySetData);
    177     }
    178 
    179     void init(File codePath, File resourcePath, String legacyNativeLibraryPathString,
    180               String primaryCpuAbiString, String secondaryCpuAbiString,
    181               String cpuAbiOverrideString, int pVersionCode) {
    182         this.codePath = codePath;
    183         this.codePathString = codePath.toString();
    184         this.resourcePath = resourcePath;
    185         this.resourcePathString = resourcePath.toString();
    186         this.legacyNativeLibraryPathString = legacyNativeLibraryPathString;
    187         this.primaryCpuAbiString = primaryCpuAbiString;
    188         this.secondaryCpuAbiString = secondaryCpuAbiString;
    189         this.cpuAbiOverrideString = cpuAbiOverrideString;
    190         this.versionCode = pVersionCode;
    191     }
    192 
    193     public void setInstallerPackageName(String packageName) {
    194         installerPackageName = packageName;
    195     }
    196 
    197     public String getInstallerPackageName() {
    198         return installerPackageName;
    199     }
    200 
    201     public void setVolumeUuid(String volumeUuid) {
    202         this.volumeUuid = volumeUuid;
    203     }
    204 
    205     public String getVolumeUuid() {
    206         return volumeUuid;
    207     }
    208 
    209     public void setInstallStatus(int newStatus) {
    210         installStatus = newStatus;
    211     }
    212 
    213     public int getInstallStatus() {
    214         return installStatus;
    215     }
    216 
    217     public void setTimeStamp(long newStamp) {
    218         timeStamp = newStamp;
    219     }
    220 
    221     /**
    222      * Make a shallow copy of this package settings.
    223      */
    224     public void copyFrom(PackageSettingBase base) {
    225         mPermissionsState.copyFrom(base.mPermissionsState);
    226         primaryCpuAbiString = base.primaryCpuAbiString;
    227         secondaryCpuAbiString = base.secondaryCpuAbiString;
    228         cpuAbiOverrideString = base.cpuAbiOverrideString;
    229         timeStamp = base.timeStamp;
    230         firstInstallTime = base.firstInstallTime;
    231         lastUpdateTime = base.lastUpdateTime;
    232         signatures = base.signatures;
    233         installPermissionsFixed = base.installPermissionsFixed;
    234         userState.clear();
    235         for (int i=0; i<base.userState.size(); i++) {
    236             userState.put(base.userState.keyAt(i), base.userState.valueAt(i));
    237         }
    238         installStatus = base.installStatus;
    239         keySetData = base.keySetData;
    240         verificationInfo = base.verificationInfo;
    241         installerPackageName = base.installerPackageName;
    242     }
    243 
    244     private PackageUserState modifyUserState(int userId) {
    245         PackageUserState state = userState.get(userId);
    246         if (state == null) {
    247             state = new PackageUserState();
    248             userState.put(userId, state);
    249         }
    250         return state;
    251     }
    252 
    253     public PackageUserState readUserState(int userId) {
    254         PackageUserState state = userState.get(userId);
    255         if (state != null) {
    256             return state;
    257         }
    258         return DEFAULT_USER_STATE;
    259     }
    260 
    261     void setEnabled(int state, int userId, String callingPackage) {
    262         PackageUserState st = modifyUserState(userId);
    263         st.enabled = state;
    264         st.lastDisableAppCaller = callingPackage;
    265     }
    266 
    267     int getEnabled(int userId) {
    268         return readUserState(userId).enabled;
    269     }
    270 
    271     String getLastDisabledAppCaller(int userId) {
    272         return readUserState(userId).lastDisableAppCaller;
    273     }
    274 
    275     void setInstalled(boolean inst, int userId) {
    276         modifyUserState(userId).installed = inst;
    277     }
    278 
    279     boolean getInstalled(int userId) {
    280         return readUserState(userId).installed;
    281     }
    282 
    283     boolean isAnyInstalled(int[] users) {
    284         for (int user: users) {
    285             if (readUserState(user).installed) {
    286                 return true;
    287             }
    288         }
    289         return false;
    290     }
    291 
    292     int[] queryInstalledUsers(int[] users, boolean installed) {
    293         int num = 0;
    294         for (int user : users) {
    295             if (getInstalled(user) == installed) {
    296                 num++;
    297             }
    298         }
    299         int[] res = new int[num];
    300         num = 0;
    301         for (int user : users) {
    302             if (getInstalled(user) == installed) {
    303                 res[num] = user;
    304                 num++;
    305             }
    306         }
    307         return res;
    308     }
    309 
    310     boolean getStopped(int userId) {
    311         return readUserState(userId).stopped;
    312     }
    313 
    314     void setStopped(boolean stop, int userId) {
    315         modifyUserState(userId).stopped = stop;
    316     }
    317 
    318     boolean getNotLaunched(int userId) {
    319         return readUserState(userId).notLaunched;
    320     }
    321 
    322     void setNotLaunched(boolean stop, int userId) {
    323         modifyUserState(userId).notLaunched = stop;
    324     }
    325 
    326     boolean getHidden(int userId) {
    327         return readUserState(userId).hidden;
    328     }
    329 
    330     void setHidden(boolean hidden, int userId) {
    331         modifyUserState(userId).hidden = hidden;
    332     }
    333 
    334     boolean getBlockUninstall(int userId) {
    335         return readUserState(userId).blockUninstall;
    336     }
    337 
    338     void setBlockUninstall(boolean blockUninstall, int userId) {
    339         modifyUserState(userId).blockUninstall = blockUninstall;
    340     }
    341 
    342     void setUserState(int userId, int enabled, boolean installed, boolean stopped,
    343             boolean notLaunched, boolean hidden,
    344             String lastDisableAppCaller, ArraySet<String> enabledComponents,
    345             ArraySet<String> disabledComponents, boolean blockUninstall, int domainVerifState,
    346             int linkGeneration) {
    347         PackageUserState state = modifyUserState(userId);
    348         state.enabled = enabled;
    349         state.installed = installed;
    350         state.stopped = stopped;
    351         state.notLaunched = notLaunched;
    352         state.hidden = hidden;
    353         state.lastDisableAppCaller = lastDisableAppCaller;
    354         state.enabledComponents = enabledComponents;
    355         state.disabledComponents = disabledComponents;
    356         state.blockUninstall = blockUninstall;
    357         state.domainVerificationStatus = domainVerifState;
    358         state.appLinkGeneration = linkGeneration;
    359     }
    360 
    361     ArraySet<String> getEnabledComponents(int userId) {
    362         return readUserState(userId).enabledComponents;
    363     }
    364 
    365     ArraySet<String> getDisabledComponents(int userId) {
    366         return readUserState(userId).disabledComponents;
    367     }
    368 
    369     void setEnabledComponents(ArraySet<String> components, int userId) {
    370         modifyUserState(userId).enabledComponents = components;
    371     }
    372 
    373     void setDisabledComponents(ArraySet<String> components, int userId) {
    374         modifyUserState(userId).disabledComponents = components;
    375     }
    376 
    377     void setEnabledComponentsCopy(ArraySet<String> components, int userId) {
    378         modifyUserState(userId).enabledComponents = components != null
    379                 ? new ArraySet<String>(components) : null;
    380     }
    381 
    382     void setDisabledComponentsCopy(ArraySet<String> components, int userId) {
    383         modifyUserState(userId).disabledComponents = components != null
    384                 ? new ArraySet<String>(components) : null;
    385     }
    386 
    387     PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) {
    388         PackageUserState state = modifyUserState(userId);
    389         if (disabled && state.disabledComponents == null) {
    390             state.disabledComponents = new ArraySet<String>(1);
    391         }
    392         if (enabled && state.enabledComponents == null) {
    393             state.enabledComponents = new ArraySet<String>(1);
    394         }
    395         return state;
    396     }
    397 
    398     void addDisabledComponent(String componentClassName, int userId) {
    399         modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName);
    400     }
    401 
    402     void addEnabledComponent(String componentClassName, int userId) {
    403         modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName);
    404     }
    405 
    406     boolean enableComponentLPw(String componentClassName, int userId) {
    407         PackageUserState state = modifyUserStateComponents(userId, false, true);
    408         boolean changed = state.disabledComponents != null
    409                 ? state.disabledComponents.remove(componentClassName) : false;
    410         changed |= state.enabledComponents.add(componentClassName);
    411         return changed;
    412     }
    413 
    414     boolean disableComponentLPw(String componentClassName, int userId) {
    415         PackageUserState state = modifyUserStateComponents(userId, true, false);
    416         boolean changed = state.enabledComponents != null
    417                 ? state.enabledComponents.remove(componentClassName) : false;
    418         changed |= state.disabledComponents.add(componentClassName);
    419         return changed;
    420     }
    421 
    422     boolean restoreComponentLPw(String componentClassName, int userId) {
    423         PackageUserState state = modifyUserStateComponents(userId, true, true);
    424         boolean changed = state.disabledComponents != null
    425                 ? state.disabledComponents.remove(componentClassName) : false;
    426         changed |= state.enabledComponents != null
    427                 ? state.enabledComponents.remove(componentClassName) : false;
    428         return changed;
    429     }
    430 
    431     int getCurrentEnabledStateLPr(String componentName, int userId) {
    432         PackageUserState state = readUserState(userId);
    433         if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) {
    434             return COMPONENT_ENABLED_STATE_ENABLED;
    435         } else if (state.disabledComponents != null
    436                 && state.disabledComponents.contains(componentName)) {
    437             return COMPONENT_ENABLED_STATE_DISABLED;
    438         } else {
    439             return COMPONENT_ENABLED_STATE_DEFAULT;
    440         }
    441     }
    442 
    443     void removeUser(int userId) {
    444         userState.delete(userId);
    445     }
    446 
    447     IntentFilterVerificationInfo getIntentFilterVerificationInfo() {
    448         return verificationInfo;
    449     }
    450 
    451     void setIntentFilterVerificationInfo(IntentFilterVerificationInfo info) {
    452         verificationInfo = info;
    453     }
    454 
    455     // Returns a packed value as a long:
    456     //
    457     // high 'int'-sized word: link status: undefined/ask/never/always.
    458     // low 'int'-sized word: relative priority among 'always' results.
    459     long getDomainVerificationStatusForUser(int userId) {
    460         PackageUserState state = readUserState(userId);
    461         long result = (long) state.appLinkGeneration;
    462         result |= ((long) state.domainVerificationStatus) << 32;
    463         return result;
    464     }
    465 
    466     void setDomainVerificationStatusForUser(final int status, int generation, int userId) {
    467         PackageUserState state = modifyUserState(userId);
    468         state.domainVerificationStatus = status;
    469         if (status == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
    470             state.appLinkGeneration = generation;
    471         }
    472     }
    473 
    474     void clearDomainVerificationStatusForUser(int userId) {
    475         modifyUserState(userId).domainVerificationStatus =
    476                 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
    477     }
    478 }
    479