blob: 069b2d4e02b5f2312d63e1ae090f99dff636c303 [file] [log] [blame]
Dianne Hackborn7767eac2012-08-23 18:25:40 -07001/*
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
17package android.content.pm;
18
19import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
Jeff Sharkey2bd31db2016-01-09 16:58:14 -070020import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
21import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
22import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
23import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
Jeff Sharkey8a372a02016-03-16 16:25:45 -060024import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
25import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
Todd Kennedy5eb5a7d2017-08-01 07:42:47 -070026import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
27import static android.content.pm.PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
Jeff Sharkey2bd31db2016-01-09 16:58:14 -070028import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
Dianne Hackborn7767eac2012-08-23 18:25:40 -070029
Jeff Sharkey9f837a92014-10-24 12:07:24 -070030import android.util.ArraySet;
Dianne Hackborn7767eac2012-08-23 18:25:40 -070031
Jeff Sharkey2bd31db2016-01-09 16:58:14 -070032import com.android.internal.util.ArrayUtils;
33
Mårten Kongstad2e0d0f32016-06-02 09:35:31 +020034import java.util.Arrays;
35
Dianne Hackborn7767eac2012-08-23 18:25:40 -070036/**
37 * Per-user state information about a package.
Dianne Hackborn8832c182012-09-17 17:20:24 -070038 * @hide
Dianne Hackborn7767eac2012-08-23 18:25:40 -070039 */
40public class PackageUserState {
Jeff Sharkey42884192016-04-09 16:12:01 -060041 public long ceDataInode;
42 public boolean installed;
Dianne Hackborn7767eac2012-08-23 18:25:40 -070043 public boolean stopped;
44 public boolean notLaunched;
Amith Yamasanie5bcff62014-07-19 15:44:09 -070045 public boolean hidden; // Is the app restricted by owner / admin
Andrei Stingaceanu1e283912015-11-26 15:26:28 +000046 public boolean suspended;
Todd Kennedybe0b8892017-02-15 14:13:52 -080047 public boolean instantApp;
Todd Kennedy5eb5a7d2017-08-01 07:42:47 -070048 public boolean virtualPreload;
Jeff Sharkey42884192016-04-09 16:12:01 -060049 public int enabled;
Dianne Hackborn3fa3c28a2013-03-26 16:15:41 -070050 public String lastDisableAppCaller;
Jeff Sharkey42884192016-04-09 16:12:01 -060051 public int domainVerificationStatus;
52 public int appLinkGeneration;
Jeff Sharkey9bc89af2017-01-11 11:25:50 -070053 public int categoryHint = ApplicationInfo.CATEGORY_UNDEFINED;
Bartosz Fabianowskia34f53f2017-01-11 18:08:47 +010054 public int installReason;
Dianne Hackborn3fa3c28a2013-03-26 16:15:41 -070055
Jeff Sharkey9f837a92014-10-24 12:07:24 -070056 public ArraySet<String> disabledComponents;
57 public ArraySet<String> enabledComponents;
Dianne Hackborn7767eac2012-08-23 18:25:40 -070058
Todd Kennedyb2749472017-06-13 08:24:32 -070059 public String[] overlayPaths;
Mårten Kongstad2e0d0f32016-06-02 09:35:31 +020060
Dianne Hackborn7767eac2012-08-23 18:25:40 -070061 public PackageUserState() {
Dianne Hackborn7767eac2012-08-23 18:25:40 -070062 installed = true;
Amith Yamasanie5bcff62014-07-19 15:44:09 -070063 hidden = false;
Andrei Stingaceanu1e283912015-11-26 15:26:28 +000064 suspended = false;
Dianne Hackborn7767eac2012-08-23 18:25:40 -070065 enabled = COMPONENT_ENABLED_STATE_DEFAULT;
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -080066 domainVerificationStatus =
67 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
Bartosz Fabianowskia34f53f2017-01-11 18:08:47 +010068 installReason = PackageManager.INSTALL_REASON_UNKNOWN;
Dianne Hackborn7767eac2012-08-23 18:25:40 -070069 }
70
71 public PackageUserState(PackageUserState o) {
Jeff Sharkey42884192016-04-09 16:12:01 -060072 ceDataInode = o.ceDataInode;
Dianne Hackborn7767eac2012-08-23 18:25:40 -070073 installed = o.installed;
74 stopped = o.stopped;
75 notLaunched = o.notLaunched;
Amith Yamasanie5bcff62014-07-19 15:44:09 -070076 hidden = o.hidden;
Andrei Stingaceanu1e283912015-11-26 15:26:28 +000077 suspended = o.suspended;
Todd Kennedybe0b8892017-02-15 14:13:52 -080078 instantApp = o.instantApp;
Todd Kennedy5eb5a7d2017-08-01 07:42:47 -070079 virtualPreload = o.virtualPreload;
Jeff Sharkey42884192016-04-09 16:12:01 -060080 enabled = o.enabled;
81 lastDisableAppCaller = o.lastDisableAppCaller;
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -080082 domainVerificationStatus = o.domainVerificationStatus;
Christopher Tatef0d6cb32015-07-10 17:44:53 -070083 appLinkGeneration = o.appLinkGeneration;
Jeff Sharkey9bc89af2017-01-11 11:25:50 -070084 categoryHint = o.categoryHint;
Bartosz Fabianowskia34f53f2017-01-11 18:08:47 +010085 installReason = o.installReason;
Jeff Sharkey42884192016-04-09 16:12:01 -060086 disabledComponents = ArrayUtils.cloneOrNull(o.disabledComponents);
87 enabledComponents = ArrayUtils.cloneOrNull(o.enabledComponents);
Todd Kennedyb2749472017-06-13 08:24:32 -070088 overlayPaths =
89 o.overlayPaths == null ? null : Arrays.copyOf(o.overlayPaths, o.overlayPaths.length);
Dianne Hackborn7767eac2012-08-23 18:25:40 -070090 }
Jeff Sharkey2bd31db2016-01-09 16:58:14 -070091
92 /**
93 * Test if this package is installed.
94 */
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -070095 public boolean isAvailable(int flags) {
96 // True if it is installed for this user and it is not hidden. If it is hidden,
97 // still return true if the caller requested MATCH_UNINSTALLED_PACKAGES
98 final boolean matchAnyUser = (flags & PackageManager.MATCH_ANY_USER) != 0;
99 final boolean matchUninstalled = (flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0;
100 return matchAnyUser
101 || (this.installed
102 && (!this.hidden || matchUninstalled));
Jeff Sharkey2bd31db2016-01-09 16:58:14 -0700103 }
104
105 /**
106 * Test if the given component is considered installed, enabled and a match
107 * for the given flags.
Bernard Chau186f29b2016-04-13 15:58:38 +0100108 *
109 * <p>
110 * Expects at least one of {@link PackageManager#MATCH_DIRECT_BOOT_AWARE} and
111 * {@link PackageManager#MATCH_DIRECT_BOOT_UNAWARE} are specified in {@code flags}.
112 * </p>
Jeff Sharkey2bd31db2016-01-09 16:58:14 -0700113 */
114 public boolean isMatch(ComponentInfo componentInfo, int flags) {
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -0700115 final boolean isSystemApp = componentInfo.applicationInfo.isSystemApp();
116 final boolean matchUninstalled = (flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0;
117 if (!isAvailable(flags)
118 && !(isSystemApp && matchUninstalled)) return false;
Jeff Sharkey2bd31db2016-01-09 16:58:14 -0700119 if (!isEnabled(componentInfo, flags)) return false;
120
121 if ((flags & MATCH_SYSTEM_ONLY) != 0) {
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -0700122 if (!isSystemApp) {
Jeff Sharkey2bd31db2016-01-09 16:58:14 -0700123 return false;
124 }
125 }
126
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600127 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
128 && !componentInfo.directBootAware;
129 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
130 && componentInfo.directBootAware;
Jeff Sharkey2bd31db2016-01-09 16:58:14 -0700131 return matchesUnaware || matchesAware;
132 }
133
134 /**
135 * Test if the given component is considered enabled.
136 */
137 public boolean isEnabled(ComponentInfo componentInfo, int flags) {
138 if ((flags & MATCH_DISABLED_COMPONENTS) != 0) {
139 return true;
140 }
141
142 // First check if the overall package is disabled; if the package is
143 // enabled then fall through to check specific component
144 switch (this.enabled) {
145 case COMPONENT_ENABLED_STATE_DISABLED:
146 case COMPONENT_ENABLED_STATE_DISABLED_USER:
147 return false;
148 case COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
149 if ((flags & MATCH_DISABLED_UNTIL_USED_COMPONENTS) == 0) {
150 return false;
151 }
152 case COMPONENT_ENABLED_STATE_DEFAULT:
153 if (!componentInfo.applicationInfo.enabled) {
154 return false;
155 }
156 case COMPONENT_ENABLED_STATE_ENABLED:
157 break;
158 }
159
160 // Check if component has explicit state before falling through to
161 // the manifest default
162 if (ArrayUtils.contains(this.enabledComponents, componentInfo.name)) {
163 return true;
164 }
165 if (ArrayUtils.contains(this.disabledComponents, componentInfo.name)) {
166 return false;
167 }
168
169 return componentInfo.enabled;
170 }
Todd Kennedy13715d52016-08-01 13:38:57 -0700171
172 @Override
173 final public boolean equals(Object obj) {
174 if (!(obj instanceof PackageUserState)) {
175 return false;
176 }
177 final PackageUserState oldState = (PackageUserState) obj;
178 if (ceDataInode != oldState.ceDataInode) {
179 return false;
180 }
181 if (installed != oldState.installed) {
182 return false;
183 }
184 if (stopped != oldState.stopped) {
185 return false;
186 }
187 if (notLaunched != oldState.notLaunched) {
188 return false;
189 }
190 if (hidden != oldState.hidden) {
191 return false;
192 }
193 if (suspended != oldState.suspended) {
194 return false;
195 }
Todd Kennedybe0b8892017-02-15 14:13:52 -0800196 if (instantApp != oldState.instantApp) {
197 return false;
198 }
Todd Kennedy5eb5a7d2017-08-01 07:42:47 -0700199 if (virtualPreload != oldState.virtualPreload) {
200 return false;
201 }
Todd Kennedy13715d52016-08-01 13:38:57 -0700202 if (enabled != oldState.enabled) {
203 return false;
204 }
205 if ((lastDisableAppCaller == null && oldState.lastDisableAppCaller != null)
206 || (lastDisableAppCaller != null
207 && !lastDisableAppCaller.equals(oldState.lastDisableAppCaller))) {
208 return false;
209 }
210 if (domainVerificationStatus != oldState.domainVerificationStatus) {
211 return false;
212 }
213 if (appLinkGeneration != oldState.appLinkGeneration) {
214 return false;
215 }
Jeff Sharkey9bc89af2017-01-11 11:25:50 -0700216 if (categoryHint != oldState.categoryHint) {
217 return false;
218 }
Bartosz Fabianowskia34f53f2017-01-11 18:08:47 +0100219 if (installReason != oldState.installReason) {
220 return false;
221 }
Todd Kennedy13715d52016-08-01 13:38:57 -0700222 if ((disabledComponents == null && oldState.disabledComponents != null)
223 || (disabledComponents != null && oldState.disabledComponents == null)) {
224 return false;
225 }
226 if (disabledComponents != null) {
227 if (disabledComponents.size() != oldState.disabledComponents.size()) {
228 return false;
229 }
230 for (int i = disabledComponents.size() - 1; i >=0; --i) {
231 if (!oldState.disabledComponents.contains(disabledComponents.valueAt(i))) {
232 return false;
233 }
234 }
235 }
236 if ((enabledComponents == null && oldState.enabledComponents != null)
237 || (enabledComponents != null && oldState.enabledComponents == null)) {
238 return false;
239 }
240 if (enabledComponents != null) {
241 if (enabledComponents.size() != oldState.enabledComponents.size()) {
242 return false;
243 }
244 for (int i = enabledComponents.size() - 1; i >=0; --i) {
245 if (!oldState.enabledComponents.contains(enabledComponents.valueAt(i))) {
246 return false;
247 }
248 }
249 }
250 return true;
251 }
Jeff Sharkey9f837a92014-10-24 12:07:24 -0700252}