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