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.PackageUserState;
     25 import android.content.pm.UserInfo;
     26 import android.util.SparseArray;
     27 
     28 import java.io.File;
     29 import java.util.HashSet;
     30 import java.util.List;
     31 
     32 /**
     33  * Settings base class for pending and resolved classes.
     34  */
     35 class PackageSettingBase extends GrantedPermissions {
     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     File codePath;
     52     String codePathString;
     53     File resourcePath;
     54     String resourcePathString;
     55     String nativeLibraryPathString;
     56     long timeStamp;
     57     long firstInstallTime;
     58     long lastUpdateTime;
     59     int versionCode;
     60 
     61     boolean uidError;
     62 
     63     PackageSignatures signatures = new PackageSignatures();
     64 
     65     boolean permissionsFixed;
     66     boolean haveGids;
     67 
     68     PackageKeySetData keySetData = new PackageKeySetData();
     69 
     70     private static final PackageUserState DEFAULT_USER_STATE = new PackageUserState();
     71 
     72     // Whether this package is currently stopped, thus can not be
     73     // started until explicitly launched by the user.
     74     private final SparseArray<PackageUserState> userState = new SparseArray<PackageUserState>();
     75 
     76     int installStatus = PKG_INSTALL_COMPLETE;
     77 
     78     PackageSettingBase origPackage;
     79 
     80     /* package name of the app that installed this package */
     81     String installerPackageName;
     82     PackageSettingBase(String name, String realName, File codePath, File resourcePath,
     83             String nativeLibraryPathString, int pVersionCode, int pkgFlags) {
     84         super(pkgFlags);
     85         this.name = name;
     86         this.realName = realName;
     87         init(codePath, resourcePath, nativeLibraryPathString, pVersionCode);
     88     }
     89 
     90     /**
     91      * New instance of PackageSetting with one-level-deep cloning.
     92      */
     93     @SuppressWarnings("unchecked")
     94     PackageSettingBase(PackageSettingBase base) {
     95         super(base);
     96 
     97         name = base.name;
     98         realName = base.realName;
     99         codePath = base.codePath;
    100         codePathString = base.codePathString;
    101         resourcePath = base.resourcePath;
    102         resourcePathString = base.resourcePathString;
    103         nativeLibraryPathString = base.nativeLibraryPathString;
    104         timeStamp = base.timeStamp;
    105         firstInstallTime = base.firstInstallTime;
    106         lastUpdateTime = base.lastUpdateTime;
    107         versionCode = base.versionCode;
    108 
    109         uidError = base.uidError;
    110 
    111         signatures = new PackageSignatures(base.signatures);
    112 
    113         permissionsFixed = base.permissionsFixed;
    114         haveGids = base.haveGids;
    115         userState.clear();
    116         for (int i=0; i<base.userState.size(); i++) {
    117             userState.put(base.userState.keyAt(i),
    118                     new PackageUserState(base.userState.valueAt(i)));
    119         }
    120         installStatus = base.installStatus;
    121 
    122         origPackage = base.origPackage;
    123 
    124         installerPackageName = base.installerPackageName;
    125 
    126         keySetData = new PackageKeySetData(base.keySetData);
    127 
    128     }
    129 
    130     void init(File codePath, File resourcePath, String nativeLibraryPathString,
    131             int pVersionCode) {
    132         this.codePath = codePath;
    133         this.codePathString = codePath.toString();
    134         this.resourcePath = resourcePath;
    135         this.resourcePathString = resourcePath.toString();
    136         this.nativeLibraryPathString = nativeLibraryPathString;
    137         this.versionCode = pVersionCode;
    138     }
    139 
    140     public void setInstallerPackageName(String packageName) {
    141         installerPackageName = packageName;
    142     }
    143 
    144     String getInstallerPackageName() {
    145         return installerPackageName;
    146     }
    147 
    148     public void setInstallStatus(int newStatus) {
    149         installStatus = newStatus;
    150     }
    151 
    152     public int getInstallStatus() {
    153         return installStatus;
    154     }
    155 
    156     public void setTimeStamp(long newStamp) {
    157         timeStamp = newStamp;
    158     }
    159 
    160     /**
    161      * Make a shallow copy of this package settings.
    162      */
    163     public void copyFrom(PackageSettingBase base) {
    164         grantedPermissions = base.grantedPermissions;
    165         gids = base.gids;
    166 
    167         timeStamp = base.timeStamp;
    168         firstInstallTime = base.firstInstallTime;
    169         lastUpdateTime = base.lastUpdateTime;
    170         signatures = base.signatures;
    171         permissionsFixed = base.permissionsFixed;
    172         haveGids = base.haveGids;
    173         userState.clear();
    174         for (int i=0; i<base.userState.size(); i++) {
    175             userState.put(base.userState.keyAt(i), base.userState.valueAt(i));
    176         }
    177         installStatus = base.installStatus;
    178         keySetData = base.keySetData;
    179     }
    180 
    181     private PackageUserState modifyUserState(int userId) {
    182         PackageUserState state = userState.get(userId);
    183         if (state == null) {
    184             state = new PackageUserState();
    185             userState.put(userId, state);
    186         }
    187         return state;
    188     }
    189 
    190     public PackageUserState readUserState(int userId) {
    191         PackageUserState state = userState.get(userId);
    192         if (state != null) {
    193             return state;
    194         }
    195         return DEFAULT_USER_STATE;
    196     }
    197 
    198     void setEnabled(int state, int userId, String callingPackage) {
    199         PackageUserState st = modifyUserState(userId);
    200         st.enabled = state;
    201         st.lastDisableAppCaller = callingPackage;
    202     }
    203 
    204     int getEnabled(int userId) {
    205         return readUserState(userId).enabled;
    206     }
    207 
    208     String getLastDisabledAppCaller(int userId) {
    209         return readUserState(userId).lastDisableAppCaller;
    210     }
    211 
    212     void setInstalled(boolean inst, int userId) {
    213         modifyUserState(userId).installed = inst;
    214     }
    215 
    216     boolean getInstalled(int userId) {
    217         return readUserState(userId).installed;
    218     }
    219 
    220     boolean isAnyInstalled(int[] users) {
    221         for (int user: users) {
    222             if (readUserState(user).installed) {
    223                 return true;
    224             }
    225         }
    226         return false;
    227     }
    228 
    229     int[] queryInstalledUsers(int[] users, boolean installed) {
    230         int num = 0;
    231         for (int user : users) {
    232             if (getInstalled(user) == installed) {
    233                 num++;
    234             }
    235         }
    236         int[] res = new int[num];
    237         num = 0;
    238         for (int user : users) {
    239             if (getInstalled(user) == installed) {
    240                 res[num] = user;
    241                 num++;
    242             }
    243         }
    244         return res;
    245     }
    246 
    247     boolean getStopped(int userId) {
    248         return readUserState(userId).stopped;
    249     }
    250 
    251     void setStopped(boolean stop, int userId) {
    252         modifyUserState(userId).stopped = stop;
    253     }
    254 
    255     boolean getNotLaunched(int userId) {
    256         return readUserState(userId).notLaunched;
    257     }
    258 
    259     void setNotLaunched(boolean stop, int userId) {
    260         modifyUserState(userId).notLaunched = stop;
    261     }
    262 
    263     boolean getBlocked(int userId) {
    264         return readUserState(userId).blocked;
    265     }
    266 
    267     void setBlocked(boolean blocked, int userId) {
    268         modifyUserState(userId).blocked = blocked;
    269     }
    270 
    271     void setUserState(int userId, int enabled, boolean installed, boolean stopped,
    272             boolean notLaunched, boolean blocked,
    273             String lastDisableAppCaller, HashSet<String> enabledComponents,
    274             HashSet<String> disabledComponents) {
    275         PackageUserState state = modifyUserState(userId);
    276         state.enabled = enabled;
    277         state.installed = installed;
    278         state.stopped = stopped;
    279         state.notLaunched = notLaunched;
    280         state.blocked = blocked;
    281         state.lastDisableAppCaller = lastDisableAppCaller;
    282         state.enabledComponents = enabledComponents;
    283         state.disabledComponents = disabledComponents;
    284     }
    285 
    286     HashSet<String> getEnabledComponents(int userId) {
    287         return readUserState(userId).enabledComponents;
    288     }
    289 
    290     HashSet<String> getDisabledComponents(int userId) {
    291         return readUserState(userId).disabledComponents;
    292     }
    293 
    294     void setEnabledComponents(HashSet<String> components, int userId) {
    295         modifyUserState(userId).enabledComponents = components;
    296     }
    297 
    298     void setDisabledComponents(HashSet<String> components, int userId) {
    299         modifyUserState(userId).disabledComponents = components;
    300     }
    301 
    302     void setEnabledComponentsCopy(HashSet<String> components, int userId) {
    303         modifyUserState(userId).enabledComponents = components != null
    304                 ? new HashSet<String>(components) : null;
    305     }
    306 
    307     void setDisabledComponentsCopy(HashSet<String> components, int userId) {
    308         modifyUserState(userId).disabledComponents = components != null
    309                 ? new HashSet<String>(components) : null;
    310     }
    311 
    312     PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) {
    313         PackageUserState state = modifyUserState(userId);
    314         if (disabled && state.disabledComponents == null) {
    315             state.disabledComponents = new HashSet<String>(1);
    316         }
    317         if (enabled && state.enabledComponents == null) {
    318             state.enabledComponents = new HashSet<String>(1);
    319         }
    320         return state;
    321     }
    322 
    323     void addDisabledComponent(String componentClassName, int userId) {
    324         modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName);
    325     }
    326 
    327     void addEnabledComponent(String componentClassName, int userId) {
    328         modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName);
    329     }
    330 
    331     boolean enableComponentLPw(String componentClassName, int userId) {
    332         PackageUserState state = modifyUserStateComponents(userId, false, true);
    333         boolean changed = state.disabledComponents != null
    334                 ? state.disabledComponents.remove(componentClassName) : false;
    335         changed |= state.enabledComponents.add(componentClassName);
    336         return changed;
    337     }
    338 
    339     boolean disableComponentLPw(String componentClassName, int userId) {
    340         PackageUserState state = modifyUserStateComponents(userId, true, false);
    341         boolean changed = state.enabledComponents != null
    342                 ? state.enabledComponents.remove(componentClassName) : false;
    343         changed |= state.disabledComponents.add(componentClassName);
    344         return changed;
    345     }
    346 
    347     boolean restoreComponentLPw(String componentClassName, int userId) {
    348         PackageUserState state = modifyUserStateComponents(userId, true, true);
    349         boolean changed = state.disabledComponents != null
    350                 ? state.disabledComponents.remove(componentClassName) : false;
    351         changed |= state.enabledComponents != null
    352                 ? state.enabledComponents.remove(componentClassName) : false;
    353         return changed;
    354     }
    355 
    356     int getCurrentEnabledStateLPr(String componentName, int userId) {
    357         PackageUserState state = readUserState(userId);
    358         if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) {
    359             return COMPONENT_ENABLED_STATE_ENABLED;
    360         } else if (state.disabledComponents != null
    361                 && state.disabledComponents.contains(componentName)) {
    362             return COMPONENT_ENABLED_STATE_DISABLED;
    363         } else {
    364             return COMPONENT_ENABLED_STATE_DEFAULT;
    365         }
    366     }
    367 
    368     void removeUser(int userId) {
    369         userState.delete(userId);
    370     }
    371 }
    372