blob: 249b6919fc281dad360498e5ec410129250eab71 [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
Mathew Inwood5c0d3542018-08-14 13:54:31 +010030import android.annotation.UnsupportedAppUsage;
Suprabh Shukla021b57a2018-03-08 18:21:50 -080031import android.os.BaseBundle;
Eugene Susla4ab95112018-12-17 14:45:11 -080032import android.os.Debug;
Suprabh Shukla021b57a2018-03-08 18:21:50 -080033import android.os.PersistableBundle;
Jeff Sharkey9f837a92014-10-24 12:07:24 -070034import android.util.ArraySet;
Eugene Susla4ab95112018-12-17 14:45:11 -080035import android.util.DebugUtils;
36import android.util.Slog;
Dianne Hackborn7767eac2012-08-23 18:25:40 -070037
Suprabh Shukla389cb6f2018-10-01 18:20:39 -070038import com.android.internal.annotations.VisibleForTesting;
Jeff Sharkey2bd31db2016-01-09 16:58:14 -070039import com.android.internal.util.ArrayUtils;
40
Mårten Kongstad2e0d0f32016-06-02 09:35:31 +020041import java.util.Arrays;
Suprabh Shukla3c3af142018-03-30 00:28:37 -070042import java.util.Objects;
Mårten Kongstad2e0d0f32016-06-02 09:35:31 +020043
Dianne Hackborn7767eac2012-08-23 18:25:40 -070044/**
45 * Per-user state information about a package.
Dianne Hackborn8832c182012-09-17 17:20:24 -070046 * @hide
Dianne Hackborn7767eac2012-08-23 18:25:40 -070047 */
48public class PackageUserState {
Eugene Susla4ab95112018-12-17 14:45:11 -080049 private static final boolean DEBUG = false;
50 private static final String LOG_TAG = "PackageUserState";
51
Jeff Sharkey42884192016-04-09 16:12:01 -060052 public long ceDataInode;
53 public boolean installed;
Dianne Hackborn7767eac2012-08-23 18:25:40 -070054 public boolean stopped;
55 public boolean notLaunched;
Amith Yamasanie5bcff62014-07-19 15:44:09 -070056 public boolean hidden; // Is the app restricted by owner / admin
Suprabh Shukla79000492018-12-24 17:03:02 -080057 public int distractionFlags;
Andrei Stingaceanu1e283912015-11-26 15:26:28 +000058 public boolean suspended;
Suprabh Shukla021b57a2018-03-08 18:21:50 -080059 public String suspendingPackage;
Suprabh Shukla389cb6f2018-10-01 18:20:39 -070060 public SuspendDialogInfo dialogInfo;
Suprabh Shukla021b57a2018-03-08 18:21:50 -080061 public PersistableBundle suspendedAppExtras;
62 public PersistableBundle suspendedLauncherExtras;
Todd Kennedybe0b8892017-02-15 14:13:52 -080063 public boolean instantApp;
Todd Kennedy5eb5a7d2017-08-01 07:42:47 -070064 public boolean virtualPreload;
Jeff Sharkey42884192016-04-09 16:12:01 -060065 public int enabled;
Dianne Hackborn3fa3c28a2013-03-26 16:15:41 -070066 public String lastDisableAppCaller;
Jeff Sharkey42884192016-04-09 16:12:01 -060067 public int domainVerificationStatus;
68 public int appLinkGeneration;
Jeff Sharkey9bc89af2017-01-11 11:25:50 -070069 public int categoryHint = ApplicationInfo.CATEGORY_UNDEFINED;
Bartosz Fabianowskia34f53f2017-01-11 18:08:47 +010070 public int installReason;
Ben Gruver1ab3d6e2017-12-07 13:45:08 -080071 public String harmfulAppWarning;
Dianne Hackborn3fa3c28a2013-03-26 16:15:41 -070072
Jeff Sharkey9f837a92014-10-24 12:07:24 -070073 public ArraySet<String> disabledComponents;
74 public ArraySet<String> enabledComponents;
Dianne Hackborn7767eac2012-08-23 18:25:40 -070075
Todd Kennedyb2749472017-06-13 08:24:32 -070076 public String[] overlayPaths;
Mårten Kongstad2e0d0f32016-06-02 09:35:31 +020077
Mathew Inwood5c0d3542018-08-14 13:54:31 +010078 @UnsupportedAppUsage
Dianne Hackborn7767eac2012-08-23 18:25:40 -070079 public PackageUserState() {
Dianne Hackborn7767eac2012-08-23 18:25:40 -070080 installed = true;
Amith Yamasanie5bcff62014-07-19 15:44:09 -070081 hidden = false;
Andrei Stingaceanu1e283912015-11-26 15:26:28 +000082 suspended = false;
Dianne Hackborn7767eac2012-08-23 18:25:40 -070083 enabled = COMPONENT_ENABLED_STATE_DEFAULT;
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -080084 domainVerificationStatus =
85 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
Bartosz Fabianowskia34f53f2017-01-11 18:08:47 +010086 installReason = PackageManager.INSTALL_REASON_UNKNOWN;
Dianne Hackborn7767eac2012-08-23 18:25:40 -070087 }
88
Suprabh Shukla389cb6f2018-10-01 18:20:39 -070089 @VisibleForTesting
Dianne Hackborn7767eac2012-08-23 18:25:40 -070090 public PackageUserState(PackageUserState o) {
Jeff Sharkey42884192016-04-09 16:12:01 -060091 ceDataInode = o.ceDataInode;
Dianne Hackborn7767eac2012-08-23 18:25:40 -070092 installed = o.installed;
93 stopped = o.stopped;
94 notLaunched = o.notLaunched;
Amith Yamasanie5bcff62014-07-19 15:44:09 -070095 hidden = o.hidden;
Suprabh Shukla79000492018-12-24 17:03:02 -080096 distractionFlags = o.distractionFlags;
Andrei Stingaceanu1e283912015-11-26 15:26:28 +000097 suspended = o.suspended;
Suprabh Shukla021b57a2018-03-08 18:21:50 -080098 suspendingPackage = o.suspendingPackage;
Suprabh Shukla389cb6f2018-10-01 18:20:39 -070099 dialogInfo = o.dialogInfo;
Suprabh Shukla021b57a2018-03-08 18:21:50 -0800100 suspendedAppExtras = o.suspendedAppExtras;
101 suspendedLauncherExtras = o.suspendedLauncherExtras;
Todd Kennedybe0b8892017-02-15 14:13:52 -0800102 instantApp = o.instantApp;
Todd Kennedy5eb5a7d2017-08-01 07:42:47 -0700103 virtualPreload = o.virtualPreload;
Jeff Sharkey42884192016-04-09 16:12:01 -0600104 enabled = o.enabled;
105 lastDisableAppCaller = o.lastDisableAppCaller;
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -0800106 domainVerificationStatus = o.domainVerificationStatus;
Christopher Tatef0d6cb32015-07-10 17:44:53 -0700107 appLinkGeneration = o.appLinkGeneration;
Jeff Sharkey9bc89af2017-01-11 11:25:50 -0700108 categoryHint = o.categoryHint;
Bartosz Fabianowskia34f53f2017-01-11 18:08:47 +0100109 installReason = o.installReason;
Jeff Sharkey42884192016-04-09 16:12:01 -0600110 disabledComponents = ArrayUtils.cloneOrNull(o.disabledComponents);
111 enabledComponents = ArrayUtils.cloneOrNull(o.enabledComponents);
Todd Kennedyb2749472017-06-13 08:24:32 -0700112 overlayPaths =
113 o.overlayPaths == null ? null : Arrays.copyOf(o.overlayPaths, o.overlayPaths.length);
Ben Gruver1ab3d6e2017-12-07 13:45:08 -0800114 harmfulAppWarning = o.harmfulAppWarning;
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700115 }
Jeff Sharkey2bd31db2016-01-09 16:58:14 -0700116
117 /**
118 * Test if this package is installed.
119 */
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -0700120 public boolean isAvailable(int flags) {
121 // True if it is installed for this user and it is not hidden. If it is hidden,
122 // still return true if the caller requested MATCH_UNINSTALLED_PACKAGES
123 final boolean matchAnyUser = (flags & PackageManager.MATCH_ANY_USER) != 0;
124 final boolean matchUninstalled = (flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0;
125 return matchAnyUser
126 || (this.installed
127 && (!this.hidden || matchUninstalled));
Jeff Sharkey2bd31db2016-01-09 16:58:14 -0700128 }
129
130 /**
131 * Test if the given component is considered installed, enabled and a match
132 * for the given flags.
Bernard Chau186f29b2016-04-13 15:58:38 +0100133 *
134 * <p>
135 * Expects at least one of {@link PackageManager#MATCH_DIRECT_BOOT_AWARE} and
136 * {@link PackageManager#MATCH_DIRECT_BOOT_UNAWARE} are specified in {@code flags}.
137 * </p>
Jeff Sharkey2bd31db2016-01-09 16:58:14 -0700138 */
139 public boolean isMatch(ComponentInfo componentInfo, int flags) {
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -0700140 final boolean isSystemApp = componentInfo.applicationInfo.isSystemApp();
141 final boolean matchUninstalled = (flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0;
142 if (!isAvailable(flags)
Eugene Susla4ab95112018-12-17 14:45:11 -0800143 && !(isSystemApp && matchUninstalled)) return reportIfDebug(false, flags);
144 if (!isEnabled(componentInfo, flags)) return reportIfDebug(false, flags);
Jeff Sharkey2bd31db2016-01-09 16:58:14 -0700145
146 if ((flags & MATCH_SYSTEM_ONLY) != 0) {
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -0700147 if (!isSystemApp) {
Eugene Susla4ab95112018-12-17 14:45:11 -0800148 return reportIfDebug(false, flags);
Jeff Sharkey2bd31db2016-01-09 16:58:14 -0700149 }
150 }
151
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600152 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
153 && !componentInfo.directBootAware;
154 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
155 && componentInfo.directBootAware;
Eugene Susla4ab95112018-12-17 14:45:11 -0800156 return reportIfDebug(matchesUnaware || matchesAware, flags);
157 }
158
159 private boolean reportIfDebug(boolean result, int flags) {
160 if (DEBUG && !result) {
161 Slog.i(LOG_TAG, "No match!; flags: "
162 + DebugUtils.flagsToString(PackageManager.class, "MATCH_", flags) + " "
163 + Debug.getCaller());
164 }
165 return result;
Jeff Sharkey2bd31db2016-01-09 16:58:14 -0700166 }
167
168 /**
169 * Test if the given component is considered enabled.
170 */
171 public boolean isEnabled(ComponentInfo componentInfo, int flags) {
172 if ((flags & MATCH_DISABLED_COMPONENTS) != 0) {
173 return true;
174 }
175
176 // First check if the overall package is disabled; if the package is
177 // enabled then fall through to check specific component
178 switch (this.enabled) {
179 case COMPONENT_ENABLED_STATE_DISABLED:
180 case COMPONENT_ENABLED_STATE_DISABLED_USER:
181 return false;
182 case COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
183 if ((flags & MATCH_DISABLED_UNTIL_USED_COMPONENTS) == 0) {
184 return false;
185 }
186 case COMPONENT_ENABLED_STATE_DEFAULT:
187 if (!componentInfo.applicationInfo.enabled) {
188 return false;
189 }
190 case COMPONENT_ENABLED_STATE_ENABLED:
191 break;
192 }
193
194 // Check if component has explicit state before falling through to
195 // the manifest default
196 if (ArrayUtils.contains(this.enabledComponents, componentInfo.name)) {
197 return true;
198 }
199 if (ArrayUtils.contains(this.disabledComponents, componentInfo.name)) {
200 return false;
201 }
202
203 return componentInfo.enabled;
204 }
Todd Kennedy13715d52016-08-01 13:38:57 -0700205
206 @Override
207 final public boolean equals(Object obj) {
208 if (!(obj instanceof PackageUserState)) {
209 return false;
210 }
211 final PackageUserState oldState = (PackageUserState) obj;
212 if (ceDataInode != oldState.ceDataInode) {
213 return false;
214 }
215 if (installed != oldState.installed) {
216 return false;
217 }
218 if (stopped != oldState.stopped) {
219 return false;
220 }
221 if (notLaunched != oldState.notLaunched) {
222 return false;
223 }
224 if (hidden != oldState.hidden) {
225 return false;
226 }
Suprabh Shukla79000492018-12-24 17:03:02 -0800227 if (distractionFlags != oldState.distractionFlags) {
228 return false;
229 }
Todd Kennedy13715d52016-08-01 13:38:57 -0700230 if (suspended != oldState.suspended) {
231 return false;
232 }
Suprabh Shukla021b57a2018-03-08 18:21:50 -0800233 if (suspended) {
234 if (suspendingPackage == null
235 || !suspendingPackage.equals(oldState.suspendingPackage)) {
236 return false;
237 }
Suprabh Shukla389cb6f2018-10-01 18:20:39 -0700238 if (!Objects.equals(dialogInfo, oldState.dialogInfo)) {
Suprabh Shukla3c3af142018-03-30 00:28:37 -0700239 return false;
240 }
Suprabh Shukla021b57a2018-03-08 18:21:50 -0800241 if (!BaseBundle.kindofEquals(suspendedAppExtras,
242 oldState.suspendedAppExtras)) {
243 return false;
244 }
245 if (!BaseBundle.kindofEquals(suspendedLauncherExtras,
246 oldState.suspendedLauncherExtras)) {
247 return false;
248 }
249 }
Todd Kennedybe0b8892017-02-15 14:13:52 -0800250 if (instantApp != oldState.instantApp) {
251 return false;
252 }
Todd Kennedy5eb5a7d2017-08-01 07:42:47 -0700253 if (virtualPreload != oldState.virtualPreload) {
254 return false;
255 }
Todd Kennedy13715d52016-08-01 13:38:57 -0700256 if (enabled != oldState.enabled) {
257 return false;
258 }
259 if ((lastDisableAppCaller == null && oldState.lastDisableAppCaller != null)
260 || (lastDisableAppCaller != null
261 && !lastDisableAppCaller.equals(oldState.lastDisableAppCaller))) {
262 return false;
263 }
264 if (domainVerificationStatus != oldState.domainVerificationStatus) {
265 return false;
266 }
267 if (appLinkGeneration != oldState.appLinkGeneration) {
268 return false;
269 }
Jeff Sharkey9bc89af2017-01-11 11:25:50 -0700270 if (categoryHint != oldState.categoryHint) {
271 return false;
272 }
Bartosz Fabianowskia34f53f2017-01-11 18:08:47 +0100273 if (installReason != oldState.installReason) {
274 return false;
275 }
Todd Kennedy13715d52016-08-01 13:38:57 -0700276 if ((disabledComponents == null && oldState.disabledComponents != null)
277 || (disabledComponents != null && oldState.disabledComponents == null)) {
278 return false;
279 }
280 if (disabledComponents != null) {
281 if (disabledComponents.size() != oldState.disabledComponents.size()) {
282 return false;
283 }
284 for (int i = disabledComponents.size() - 1; i >=0; --i) {
285 if (!oldState.disabledComponents.contains(disabledComponents.valueAt(i))) {
286 return false;
287 }
288 }
289 }
290 if ((enabledComponents == null && oldState.enabledComponents != null)
291 || (enabledComponents != null && oldState.enabledComponents == null)) {
292 return false;
293 }
294 if (enabledComponents != null) {
295 if (enabledComponents.size() != oldState.enabledComponents.size()) {
296 return false;
297 }
298 for (int i = enabledComponents.size() - 1; i >=0; --i) {
299 if (!oldState.enabledComponents.contains(enabledComponents.valueAt(i))) {
300 return false;
301 }
302 }
303 }
Ben Gruver1ab3d6e2017-12-07 13:45:08 -0800304 if (harmfulAppWarning == null && oldState.harmfulAppWarning != null
305 || (harmfulAppWarning != null
306 && !harmfulAppWarning.equals(oldState.harmfulAppWarning))) {
307 return false;
308 }
Todd Kennedy13715d52016-08-01 13:38:57 -0700309 return true;
310 }
Jeff Sharkey9f837a92014-10-24 12:07:24 -0700311}