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