• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
PackageUserState()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 
PackageUserState(PackageUserState o)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      */
isAvailable(int flags)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      */
isMatch(ComponentInfo componentInfo, int flags)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      */
isEnabled(ComponentInfo componentInfo, int flags)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
equals(Object obj)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