Home | History | Annotate | Download | only in pm
      1 /*
      2  * Copyright (C) 2012 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 android.content.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_DISABLED_UNTIL_USED;
     22 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
     23 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
     24 import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
     25 import static android.content.pm.PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
     26 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
     27 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
     28 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
     29 
     30 import android.util.ArraySet;
     31 
     32 import com.android.internal.util.ArrayUtils;
     33 
     34 import java.util.Arrays;
     35 
     36 /**
     37  * Per-user state information about a package.
     38  * @hide
     39  */
     40 public class PackageUserState {
     41     public long ceDataInode;
     42     public boolean installed;
     43     public boolean stopped;
     44     public boolean notLaunched;
     45     public boolean hidden; // Is the app restricted by owner / admin
     46     public boolean suspended;
     47     public boolean instantApp;
     48     public int enabled;
     49     public String lastDisableAppCaller;
     50     public int domainVerificationStatus;
     51     public int appLinkGeneration;
     52     public int categoryHint = ApplicationInfo.CATEGORY_UNDEFINED;
     53     public int installReason;
     54 
     55     public ArraySet<String> disabledComponents;
     56     public ArraySet<String> enabledComponents;
     57 
     58     public String[] overlayPaths;
     59 
     60     public PackageUserState() {
     61         installed = true;
     62         hidden = false;
     63         suspended = false;
     64         enabled = COMPONENT_ENABLED_STATE_DEFAULT;
     65         domainVerificationStatus =
     66                 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
     67         installReason = PackageManager.INSTALL_REASON_UNKNOWN;
     68     }
     69 
     70     public PackageUserState(PackageUserState o) {
     71         ceDataInode = o.ceDataInode;
     72         installed = o.installed;
     73         stopped = o.stopped;
     74         notLaunched = o.notLaunched;
     75         hidden = o.hidden;
     76         suspended = o.suspended;
     77         instantApp = o.instantApp;
     78         enabled = o.enabled;
     79         lastDisableAppCaller = o.lastDisableAppCaller;
     80         domainVerificationStatus = o.domainVerificationStatus;
     81         appLinkGeneration = o.appLinkGeneration;
     82         categoryHint = o.categoryHint;
     83         installReason = o.installReason;
     84         disabledComponents = ArrayUtils.cloneOrNull(o.disabledComponents);
     85         enabledComponents = ArrayUtils.cloneOrNull(o.enabledComponents);
     86         overlayPaths =
     87             o.overlayPaths == null ? null : Arrays.copyOf(o.overlayPaths, o.overlayPaths.length);
     88     }
     89 
     90     /**
     91      * Test if this package is installed.
     92      */
     93     public boolean isAvailable(int flags) {
     94         // True if it is installed for this user and it is not hidden. If it is hidden,
     95         // still return true if the caller requested MATCH_UNINSTALLED_PACKAGES
     96         final boolean matchAnyUser = (flags & PackageManager.MATCH_ANY_USER) != 0;
     97         final boolean matchUninstalled = (flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0;
     98         return matchAnyUser
     99                 || (this.installed
    100                         && (!this.hidden || matchUninstalled));
    101     }
    102 
    103     /**
    104      * Test if the given component is considered installed, enabled and a match
    105      * for the given flags.
    106      *
    107      * <p>
    108      * Expects at least one of {@link PackageManager#MATCH_DIRECT_BOOT_AWARE} and
    109      * {@link PackageManager#MATCH_DIRECT_BOOT_UNAWARE} are specified in {@code flags}.
    110      * </p>
    111      */
    112     public boolean isMatch(ComponentInfo componentInfo, int flags) {
    113         final boolean isSystemApp = componentInfo.applicationInfo.isSystemApp();
    114         final boolean matchUninstalled = (flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0;
    115         if (!isAvailable(flags)
    116                 && !(isSystemApp && matchUninstalled)) return false;
    117         if (!isEnabled(componentInfo, flags)) return false;
    118 
    119         if ((flags & MATCH_SYSTEM_ONLY) != 0) {
    120             if (!isSystemApp) {
    121                 return false;
    122             }
    123         }
    124 
    125         final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
    126                 && !componentInfo.directBootAware;
    127         final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
    128                 && componentInfo.directBootAware;
    129         return matchesUnaware || matchesAware;
    130     }
    131 
    132     /**
    133      * Test if the given component is considered enabled.
    134      */
    135     public boolean isEnabled(ComponentInfo componentInfo, int flags) {
    136         if ((flags & MATCH_DISABLED_COMPONENTS) != 0) {
    137             return true;
    138         }
    139 
    140         // First check if the overall package is disabled; if the package is
    141         // enabled then fall through to check specific component
    142         switch (this.enabled) {
    143             case COMPONENT_ENABLED_STATE_DISABLED:
    144             case COMPONENT_ENABLED_STATE_DISABLED_USER:
    145                 return false;
    146             case COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
    147                 if ((flags & MATCH_DISABLED_UNTIL_USED_COMPONENTS) == 0) {
    148                     return false;
    149                 }
    150             case COMPONENT_ENABLED_STATE_DEFAULT:
    151                 if (!componentInfo.applicationInfo.enabled) {
    152                     return false;
    153                 }
    154             case COMPONENT_ENABLED_STATE_ENABLED:
    155                 break;
    156         }
    157 
    158         // Check if component has explicit state before falling through to
    159         // the manifest default
    160         if (ArrayUtils.contains(this.enabledComponents, componentInfo.name)) {
    161             return true;
    162         }
    163         if (ArrayUtils.contains(this.disabledComponents, componentInfo.name)) {
    164             return false;
    165         }
    166 
    167         return componentInfo.enabled;
    168     }
    169 
    170     @Override
    171     final public boolean equals(Object obj) {
    172         if (!(obj instanceof PackageUserState)) {
    173             return false;
    174         }
    175         final PackageUserState oldState = (PackageUserState) obj;
    176         if (ceDataInode != oldState.ceDataInode) {
    177             return false;
    178         }
    179         if (installed != oldState.installed) {
    180             return false;
    181         }
    182         if (stopped != oldState.stopped) {
    183             return false;
    184         }
    185         if (notLaunched != oldState.notLaunched) {
    186             return false;
    187         }
    188         if (hidden != oldState.hidden) {
    189             return false;
    190         }
    191         if (suspended != oldState.suspended) {
    192             return false;
    193         }
    194         if (instantApp != oldState.instantApp) {
    195             return false;
    196         }
    197         if (enabled != oldState.enabled) {
    198             return false;
    199         }
    200         if ((lastDisableAppCaller == null && oldState.lastDisableAppCaller != null)
    201                 || (lastDisableAppCaller != null
    202                         && !lastDisableAppCaller.equals(oldState.lastDisableAppCaller))) {
    203             return false;
    204         }
    205         if (domainVerificationStatus != oldState.domainVerificationStatus) {
    206             return false;
    207         }
    208         if (appLinkGeneration != oldState.appLinkGeneration) {
    209             return false;
    210         }
    211         if (categoryHint != oldState.categoryHint) {
    212             return false;
    213         }
    214         if (installReason != oldState.installReason) {
    215             return false;
    216         }
    217         if ((disabledComponents == null && oldState.disabledComponents != null)
    218                 || (disabledComponents != null && oldState.disabledComponents == null)) {
    219             return false;
    220         }
    221         if (disabledComponents != null) {
    222             if (disabledComponents.size() != oldState.disabledComponents.size()) {
    223                 return false;
    224             }
    225             for (int i = disabledComponents.size() - 1; i >=0; --i) {
    226                 if (!oldState.disabledComponents.contains(disabledComponents.valueAt(i))) {
    227                     return false;
    228                 }
    229             }
    230         }
    231         if ((enabledComponents == null && oldState.enabledComponents != null)
    232                 || (enabledComponents != null && oldState.enabledComponents == null)) {
    233             return false;
    234         }
    235         if (enabledComponents != null) {
    236             if (enabledComponents.size() != oldState.enabledComponents.size()) {
    237                 return false;
    238             }
    239             for (int i = enabledComponents.size() - 1; i >=0; --i) {
    240                 if (!oldState.enabledComponents.contains(enabledComponents.valueAt(i))) {
    241                     return false;
    242                 }
    243             }
    244         }
    245         return true;
    246     }
    247 }
    248