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 /**
35  * Per-user state information about a package.
36  * @hide
37  */
38 public class PackageUserState {
39     public long ceDataInode;
40     public boolean installed;
41     public boolean stopped;
42     public boolean notLaunched;
43     public boolean hidden; // Is the app restricted by owner / admin
44     public boolean suspended;
45     public boolean blockUninstall;
46     public int enabled;
47     public String lastDisableAppCaller;
48     public int domainVerificationStatus;
49     public int appLinkGeneration;
50 
51     public ArraySet<String> disabledComponents;
52     public ArraySet<String> enabledComponents;
53 
PackageUserState()54     public PackageUserState() {
55         installed = true;
56         hidden = false;
57         suspended = false;
58         enabled = COMPONENT_ENABLED_STATE_DEFAULT;
59         domainVerificationStatus =
60                 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
61     }
62 
PackageUserState(PackageUserState o)63     public PackageUserState(PackageUserState o) {
64         ceDataInode = o.ceDataInode;
65         installed = o.installed;
66         stopped = o.stopped;
67         notLaunched = o.notLaunched;
68         hidden = o.hidden;
69         suspended = o.suspended;
70         blockUninstall = o.blockUninstall;
71         enabled = o.enabled;
72         lastDisableAppCaller = o.lastDisableAppCaller;
73         domainVerificationStatus = o.domainVerificationStatus;
74         appLinkGeneration = o.appLinkGeneration;
75         disabledComponents = ArrayUtils.cloneOrNull(o.disabledComponents);
76         enabledComponents = ArrayUtils.cloneOrNull(o.enabledComponents);
77     }
78 
79     /**
80      * Test if this package is installed.
81      */
isInstalled(int flags)82     public boolean isInstalled(int flags) {
83         return (this.installed && !this.hidden)
84                 || (flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0;
85     }
86 
87     /**
88      * Test if the given component is considered installed, enabled and a match
89      * for the given flags.
90      *
91      * <p>
92      * Expects at least one of {@link PackageManager#MATCH_DIRECT_BOOT_AWARE} and
93      * {@link PackageManager#MATCH_DIRECT_BOOT_UNAWARE} are specified in {@code flags}.
94      * </p>
95      */
isMatch(ComponentInfo componentInfo, int flags)96     public boolean isMatch(ComponentInfo componentInfo, int flags) {
97         if (!isInstalled(flags)) return false;
98         if (!isEnabled(componentInfo, flags)) return false;
99 
100         if ((flags & MATCH_SYSTEM_ONLY) != 0) {
101             if (!componentInfo.applicationInfo.isSystemApp()) {
102                 return false;
103             }
104         }
105 
106         final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
107                 && !componentInfo.directBootAware;
108         final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
109                 && componentInfo.directBootAware;
110         return matchesUnaware || matchesAware;
111     }
112 
113     /**
114      * Test if the given component is considered enabled.
115      */
isEnabled(ComponentInfo componentInfo, int flags)116     public boolean isEnabled(ComponentInfo componentInfo, int flags) {
117         if ((flags & MATCH_DISABLED_COMPONENTS) != 0) {
118             return true;
119         }
120 
121         // First check if the overall package is disabled; if the package is
122         // enabled then fall through to check specific component
123         switch (this.enabled) {
124             case COMPONENT_ENABLED_STATE_DISABLED:
125             case COMPONENT_ENABLED_STATE_DISABLED_USER:
126                 return false;
127             case COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
128                 if ((flags & MATCH_DISABLED_UNTIL_USED_COMPONENTS) == 0) {
129                     return false;
130                 }
131             case COMPONENT_ENABLED_STATE_DEFAULT:
132                 if (!componentInfo.applicationInfo.enabled) {
133                     return false;
134                 }
135             case COMPONENT_ENABLED_STATE_ENABLED:
136                 break;
137         }
138 
139         // Check if component has explicit state before falling through to
140         // the manifest default
141         if (ArrayUtils.contains(this.enabledComponents, componentInfo.name)) {
142             return true;
143         }
144         if (ArrayUtils.contains(this.disabledComponents, componentInfo.name)) {
145             return false;
146         }
147 
148         return componentInfo.enabled;
149     }
150 }
151