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.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 boolean virtualPreload; 49 public int enabled; 50 public String lastDisableAppCaller; 51 public int domainVerificationStatus; 52 public int appLinkGeneration; 53 public int categoryHint = ApplicationInfo.CATEGORY_UNDEFINED; 54 public int installReason; 55 56 public ArraySet<String> disabledComponents; 57 public ArraySet<String> enabledComponents; 58 59 public String[] overlayPaths; 60 PackageUserState()61 public PackageUserState() { 62 installed = true; 63 hidden = false; 64 suspended = false; 65 enabled = COMPONENT_ENABLED_STATE_DEFAULT; 66 domainVerificationStatus = 67 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 68 installReason = PackageManager.INSTALL_REASON_UNKNOWN; 69 } 70 PackageUserState(PackageUserState o)71 public PackageUserState(PackageUserState o) { 72 ceDataInode = o.ceDataInode; 73 installed = o.installed; 74 stopped = o.stopped; 75 notLaunched = o.notLaunched; 76 hidden = o.hidden; 77 suspended = o.suspended; 78 instantApp = o.instantApp; 79 virtualPreload = o.virtualPreload; 80 enabled = o.enabled; 81 lastDisableAppCaller = o.lastDisableAppCaller; 82 domainVerificationStatus = o.domainVerificationStatus; 83 appLinkGeneration = o.appLinkGeneration; 84 categoryHint = o.categoryHint; 85 installReason = o.installReason; 86 disabledComponents = ArrayUtils.cloneOrNull(o.disabledComponents); 87 enabledComponents = ArrayUtils.cloneOrNull(o.enabledComponents); 88 overlayPaths = 89 o.overlayPaths == null ? null : Arrays.copyOf(o.overlayPaths, o.overlayPaths.length); 90 } 91 92 /** 93 * Test if this package is installed. 94 */ isAvailable(int flags)95 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)); 103 } 104 105 /** 106 * Test if the given component is considered installed, enabled and a match 107 * for the given flags. 108 * 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> 113 */ isMatch(ComponentInfo componentInfo, int flags)114 public boolean isMatch(ComponentInfo componentInfo, int flags) { 115 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; 119 if (!isEnabled(componentInfo, flags)) return false; 120 121 if ((flags & MATCH_SYSTEM_ONLY) != 0) { 122 if (!isSystemApp) { 123 return false; 124 } 125 } 126 127 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; 131 return matchesUnaware || matchesAware; 132 } 133 134 /** 135 * Test if the given component is considered enabled. 136 */ isEnabled(ComponentInfo componentInfo, int flags)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 } 171 172 @Override equals(Object obj)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 } 196 if (instantApp != oldState.instantApp) { 197 return false; 198 } 199 if (virtualPreload != oldState.virtualPreload) { 200 return false; 201 } 202 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 } 216 if (categoryHint != oldState.categoryHint) { 217 return false; 218 } 219 if (installReason != oldState.installReason) { 220 return false; 221 } 222 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 } 252 } 253