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