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) {
    193         modifyUserState(userId).enabled = state;
    194     }
    195 
    196     int getEnabled(int userId) {
    197         return readUserState(userId).enabled;
    198     }
    199 
    200     void setInstalled(boolean inst, int userId) {
    201         modifyUserState(userId).installed = inst;
    202     }
    203 
    204     boolean getInstalled(int userId) {
    205         return readUserState(userId).installed;
    206     }
    207 
    208     boolean isAnyInstalled(int[] users) {
    209         for (int user: users) {
    210             if (readUserState(user).installed) {
    211                 return true;
    212             }
    213         }
    214         return false;
    215     }
    216 
    217     int[] queryInstalledUsers(int[] users, boolean installed) {
    218         int num = 0;
    219         for (int user : users) {
    220             if (getInstalled(user) == installed) {
    221                 num++;
    222             }
    223         }
    224         int[] res = new int[num];
    225         num = 0;
    226         for (int user : users) {
    227             if (getInstalled(user) == installed) {
    228                 res[num] = user;
    229                 num++;
    230             }
    231         }
    232         return res;
    233     }
    234 
    235     boolean getStopped(int userId) {
    236         return readUserState(userId).stopped;
    237     }
    238 
    239     void setStopped(boolean stop, int userId) {
    240         modifyUserState(userId).stopped = stop;
    241     }
    242 
    243     boolean getNotLaunched(int userId) {
    244         return readUserState(userId).notLaunched;
    245     }
    246 
    247     void setNotLaunched(boolean stop, int userId) {
    248         modifyUserState(userId).notLaunched = stop;
    249     }
    250 
    251     void setUserState(int userId, int enabled, boolean installed, boolean stopped,
    252             boolean notLaunched, HashSet<String> enabledComponents,
    253             HashSet<String> disabledComponents) {
    254         PackageUserState state = modifyUserState(userId);
    255         state.enabled = enabled;
    256         state.installed = installed;
    257         state.stopped = stopped;
    258         state.notLaunched = notLaunched;
    259         state.enabledComponents = enabledComponents;
    260         state.disabledComponents = disabledComponents;
    261     }
    262 
    263     HashSet<String> getEnabledComponents(int userId) {
    264         return readUserState(userId).enabledComponents;
    265     }
    266 
    267     HashSet<String> getDisabledComponents(int userId) {
    268         return readUserState(userId).disabledComponents;
    269     }
    270 
    271     void setEnabledComponents(HashSet<String> components, int userId) {
    272         modifyUserState(userId).enabledComponents = components;
    273     }
    274 
    275     void setDisabledComponents(HashSet<String> components, int userId) {
    276         modifyUserState(userId).disabledComponents = components;
    277     }
    278 
    279     void setEnabledComponentsCopy(HashSet<String> components, int userId) {
    280         modifyUserState(userId).enabledComponents = components != null
    281                 ? new HashSet<String>(components) : null;
    282     }
    283 
    284     void setDisabledComponentsCopy(HashSet<String> components, int userId) {
    285         modifyUserState(userId).disabledComponents = components != null
    286                 ? new HashSet<String>(components) : null;
    287     }
    288 
    289     PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) {
    290         PackageUserState state = modifyUserState(userId);
    291         if (disabled && state.disabledComponents == null) {
    292             state.disabledComponents = new HashSet<String>(1);
    293         }
    294         if (enabled && state.enabledComponents == null) {
    295             state.enabledComponents = new HashSet<String>(1);
    296         }
    297         return state;
    298     }
    299 
    300     void addDisabledComponent(String componentClassName, int userId) {
    301         modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName);
    302     }
    303 
    304     void addEnabledComponent(String componentClassName, int userId) {
    305         modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName);
    306     }
    307 
    308     boolean enableComponentLPw(String componentClassName, int userId) {
    309         PackageUserState state = modifyUserStateComponents(userId, false, true);
    310         boolean changed = state.disabledComponents != null
    311                 ? state.disabledComponents.remove(componentClassName) : false;
    312         changed |= state.enabledComponents.add(componentClassName);
    313         return changed;
    314     }
    315 
    316     boolean disableComponentLPw(String componentClassName, int userId) {
    317         PackageUserState state = modifyUserStateComponents(userId, true, false);
    318         boolean changed = state.enabledComponents != null
    319                 ? state.enabledComponents.remove(componentClassName) : false;
    320         changed |= state.disabledComponents.add(componentClassName);
    321         return changed;
    322     }
    323 
    324     boolean restoreComponentLPw(String componentClassName, int userId) {
    325         PackageUserState state = modifyUserStateComponents(userId, true, true);
    326         boolean changed = state.disabledComponents != null
    327                 ? state.disabledComponents.remove(componentClassName) : false;
    328         changed |= state.enabledComponents != null
    329                 ? state.enabledComponents.remove(componentClassName) : false;
    330         return changed;
    331     }
    332 
    333     int getCurrentEnabledStateLPr(String componentName, int userId) {
    334         PackageUserState state = readUserState(userId);
    335         if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) {
    336             return COMPONENT_ENABLED_STATE_ENABLED;
    337         } else if (state.disabledComponents != null
    338                 && state.disabledComponents.contains(componentName)) {
    339             return COMPONENT_ENABLED_STATE_DISABLED;
    340         } else {
    341             return COMPONENT_ENABLED_STATE_DEFAULT;
    342         }
    343     }
    344 
    345     void removeUser(int userId) {
    346         userState.delete(userId);
    347     }
    348 }
    349