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.compat.annotation.UnsupportedAppUsage; 31 import android.os.BaseBundle; 32 import android.os.Debug; 33 import android.os.PersistableBundle; 34 import android.util.ArraySet; 35 import android.util.DebugUtils; 36 import android.util.Slog; 37 38 import com.android.internal.annotations.VisibleForTesting; 39 import com.android.internal.util.ArrayUtils; 40 41 import java.util.Arrays; 42 import java.util.Objects; 43 44 /** 45 * Per-user state information about a package. 46 * @hide 47 */ 48 public class PackageUserState { 49 private static final boolean DEBUG = false; 50 private static final String LOG_TAG = "PackageUserState"; 51 52 public long ceDataInode; 53 public boolean installed; 54 public boolean stopped; 55 public boolean notLaunched; 56 public boolean hidden; // Is the app restricted by owner / admin 57 public int distractionFlags; 58 public boolean suspended; 59 public String suspendingPackage; 60 public SuspendDialogInfo dialogInfo; 61 public PersistableBundle suspendedAppExtras; 62 public PersistableBundle suspendedLauncherExtras; 63 public boolean instantApp; 64 public boolean virtualPreload; 65 public int enabled; 66 public String lastDisableAppCaller; 67 public int domainVerificationStatus; 68 public int appLinkGeneration; 69 public int categoryHint = ApplicationInfo.CATEGORY_UNDEFINED; 70 public int installReason; 71 public String harmfulAppWarning; 72 73 public ArraySet<String> disabledComponents; 74 public ArraySet<String> enabledComponents; 75 76 public String[] overlayPaths; 77 78 @UnsupportedAppUsage PackageUserState()79 public PackageUserState() { 80 installed = true; 81 hidden = false; 82 suspended = false; 83 enabled = COMPONENT_ENABLED_STATE_DEFAULT; 84 domainVerificationStatus = 85 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 86 installReason = PackageManager.INSTALL_REASON_UNKNOWN; 87 } 88 89 @VisibleForTesting PackageUserState(PackageUserState o)90 public PackageUserState(PackageUserState o) { 91 ceDataInode = o.ceDataInode; 92 installed = o.installed; 93 stopped = o.stopped; 94 notLaunched = o.notLaunched; 95 hidden = o.hidden; 96 distractionFlags = o.distractionFlags; 97 suspended = o.suspended; 98 suspendingPackage = o.suspendingPackage; 99 dialogInfo = o.dialogInfo; 100 suspendedAppExtras = o.suspendedAppExtras; 101 suspendedLauncherExtras = o.suspendedLauncherExtras; 102 instantApp = o.instantApp; 103 virtualPreload = o.virtualPreload; 104 enabled = o.enabled; 105 lastDisableAppCaller = o.lastDisableAppCaller; 106 domainVerificationStatus = o.domainVerificationStatus; 107 appLinkGeneration = o.appLinkGeneration; 108 categoryHint = o.categoryHint; 109 installReason = o.installReason; 110 disabledComponents = ArrayUtils.cloneOrNull(o.disabledComponents); 111 enabledComponents = ArrayUtils.cloneOrNull(o.enabledComponents); 112 overlayPaths = 113 o.overlayPaths == null ? null : Arrays.copyOf(o.overlayPaths, o.overlayPaths.length); 114 harmfulAppWarning = o.harmfulAppWarning; 115 } 116 117 /** 118 * Test if this package is installed. 119 */ isAvailable(int flags)120 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)); 128 } 129 130 /** 131 * Test if the given component is considered installed, enabled and a match 132 * for the given flags. 133 * 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> 138 */ isMatch(ComponentInfo componentInfo, int flags)139 public boolean isMatch(ComponentInfo componentInfo, int flags) { 140 final boolean isSystemApp = componentInfo.applicationInfo.isSystemApp(); 141 final boolean matchUninstalled = (flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0; 142 if (!isAvailable(flags) 143 && !(isSystemApp && matchUninstalled)) return reportIfDebug(false, flags); 144 if (!isEnabled(componentInfo, flags)) return reportIfDebug(false, flags); 145 146 if ((flags & MATCH_SYSTEM_ONLY) != 0) { 147 if (!isSystemApp) { 148 return reportIfDebug(false, flags); 149 } 150 } 151 152 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; 156 return reportIfDebug(matchesUnaware || matchesAware, flags); 157 } 158 reportIfDebug(boolean result, int flags)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; 166 } 167 168 /** 169 * Test if the given component is considered enabled. 170 */ isEnabled(ComponentInfo componentInfo, int flags)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 } 205 206 @Override equals(Object obj)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 } 227 if (distractionFlags != oldState.distractionFlags) { 228 return false; 229 } 230 if (suspended != oldState.suspended) { 231 return false; 232 } 233 if (suspended) { 234 if (suspendingPackage == null 235 || !suspendingPackage.equals(oldState.suspendingPackage)) { 236 return false; 237 } 238 if (!Objects.equals(dialogInfo, oldState.dialogInfo)) { 239 return false; 240 } 241 if (!BaseBundle.kindofEquals(suspendedAppExtras, 242 oldState.suspendedAppExtras)) { 243 return false; 244 } 245 if (!BaseBundle.kindofEquals(suspendedLauncherExtras, 246 oldState.suspendedLauncherExtras)) { 247 return false; 248 } 249 } 250 if (instantApp != oldState.instantApp) { 251 return false; 252 } 253 if (virtualPreload != oldState.virtualPreload) { 254 return false; 255 } 256 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 } 270 if (categoryHint != oldState.categoryHint) { 271 return false; 272 } 273 if (installReason != oldState.installReason) { 274 return false; 275 } 276 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 } 304 if (harmfulAppWarning == null && oldState.harmfulAppWarning != null 305 || (harmfulAppWarning != null 306 && !harmfulAppWarning.equals(oldState.harmfulAppWarning))) { 307 return false; 308 } 309 return true; 310 } 311 } 312