Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2019 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 com.android.server.pm; |
| 18 | |
Ram Muthiah | 637138d | 2019-12-11 17:37:37 -0800 | [diff] [blame] | 19 | import static android.content.pm.PackageParser.Component; |
| 20 | import static android.content.pm.PackageParser.IntentInfo; |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 21 | import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; |
Patrick Baumann | dfb121d | 2019-08-05 14:36:19 -0700 | [diff] [blame] | 22 | import static android.provider.DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE; |
| 23 | |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 24 | import android.Manifest; |
| 25 | import android.annotation.Nullable; |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 26 | import android.content.Intent; |
Patrick Baumann | 0c9257b | 2019-08-20 12:50:37 -0700 | [diff] [blame] | 27 | import android.content.IntentFilter; |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 28 | import android.content.pm.PackageManager; |
Ram Muthiah | 637138d | 2019-12-11 17:37:37 -0800 | [diff] [blame] | 29 | import android.content.pm.PackageParser; |
Winson | 14ff717 | 2019-10-23 10:42:27 -0700 | [diff] [blame] | 30 | import android.content.pm.parsing.AndroidPackage; |
| 31 | import android.content.pm.parsing.ComponentParseUtils; |
Winson | 655a5b9 | 2019-10-23 10:49:32 -0700 | [diff] [blame] | 32 | import android.content.pm.parsing.ComponentParseUtils.ParsedActivity; |
Winson | 14ff717 | 2019-10-23 10:42:27 -0700 | [diff] [blame] | 33 | import android.content.pm.parsing.ComponentParseUtils.ParsedComponent; |
| 34 | import android.content.pm.parsing.ComponentParseUtils.ParsedIntentInfo; |
| 35 | import android.content.pm.parsing.ComponentParseUtils.ParsedProvider; |
Winson | 655a5b9 | 2019-10-23 10:49:32 -0700 | [diff] [blame] | 36 | import android.content.pm.parsing.ComponentParseUtils.ParsedService; |
Patrick Baumann | 0c9257b | 2019-08-20 12:50:37 -0700 | [diff] [blame] | 37 | import android.net.Uri; |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 38 | import android.os.Process; |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 39 | import android.os.Trace; |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 40 | import android.os.UserHandle; |
Patrick Baumann | dfb121d | 2019-08-05 14:36:19 -0700 | [diff] [blame] | 41 | import android.provider.DeviceConfig; |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 42 | import android.text.TextUtils; |
| 43 | import android.util.ArrayMap; |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 44 | import android.util.ArraySet; |
| 45 | import android.util.Slog; |
| 46 | import android.util.SparseArray; |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 47 | import android.util.SparseSetArray; |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 48 | |
| 49 | import com.android.internal.R; |
Patrick Baumann | a94cbc1 | 2019-09-17 08:08:10 -0700 | [diff] [blame] | 50 | import com.android.internal.annotations.VisibleForTesting; |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 51 | import com.android.internal.util.ArrayUtils; |
Patrick Baumann | dfb121d | 2019-08-05 14:36:19 -0700 | [diff] [blame] | 52 | import com.android.server.FgThread; |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 53 | |
Patrick Baumann | a7ad66d | 2019-08-12 11:11:08 -0700 | [diff] [blame] | 54 | import java.io.PrintWriter; |
Ram Muthiah | 637138d | 2019-12-11 17:37:37 -0800 | [diff] [blame] | 55 | import java.util.ArrayList; |
Winson | 655a5b9 | 2019-10-23 10:49:32 -0700 | [diff] [blame] | 56 | import java.util.List; |
Patrick Baumann | a7ad66d | 2019-08-12 11:11:08 -0700 | [diff] [blame] | 57 | import java.util.Objects; |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 58 | import java.util.Set; |
| 59 | |
| 60 | /** |
| 61 | * The entity responsible for filtering visibility between apps based on declarations in their |
| 62 | * manifests. |
| 63 | */ |
Patrick Baumann | a94cbc1 | 2019-09-17 08:08:10 -0700 | [diff] [blame] | 64 | @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) |
| 65 | public class AppsFilter { |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 66 | |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 67 | private static final String TAG = "AppsFilter"; |
Patrick Baumann | af9c3fe | 2019-08-12 08:13:32 -0700 | [diff] [blame] | 68 | |
Patrick Baumann | 40ed99a | 2019-08-12 09:43:10 -0700 | [diff] [blame] | 69 | // Logs all filtering instead of enforcing |
| 70 | private static final boolean DEBUG_ALLOW_ALL = false; |
| 71 | |
| 72 | @SuppressWarnings("ConstantExpression") |
Patrick Baumann | 0c9257b | 2019-08-20 12:50:37 -0700 | [diff] [blame] | 73 | private static final boolean DEBUG_LOGGING = false | DEBUG_ALLOW_ALL; |
Patrick Baumann | 40ed99a | 2019-08-12 09:43:10 -0700 | [diff] [blame] | 74 | |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 75 | /** |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 76 | * This contains a list of app UIDs that are implicitly queryable because another app explicitly |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 77 | * interacted with it. For example, if application A starts a service in application B, |
| 78 | * application B is implicitly allowed to query for application A; regardless of any manifest |
| 79 | * entries. |
| 80 | */ |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 81 | private final SparseSetArray<Integer> mImplicitlyQueryable = new SparseSetArray<>(); |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 82 | |
| 83 | /** |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 84 | * A mapping from the set of App IDs that query other App IDs via package name to the |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 85 | * list of packages that they can see. |
| 86 | */ |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 87 | private final SparseSetArray<Integer> mQueriesViaPackage = new SparseSetArray<>(); |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 88 | |
| 89 | /** |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 90 | * A mapping from the set of App IDs that query others via intent to the list |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 91 | * of packages that the intents resolve to. |
| 92 | */ |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 93 | private final SparseSetArray<Integer> mQueriesViaIntent = new SparseSetArray<>(); |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 94 | |
| 95 | /** |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 96 | * A set of App IDs that are always queryable by any package, regardless of their manifest |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 97 | * content. |
| 98 | */ |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 99 | private final ArraySet<Integer> mForceQueryable = new ArraySet<>(); |
| 100 | |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 101 | /** |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 102 | * The set of package names provided by the device that should be force queryable regardless of |
| 103 | * their manifest contents. |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 104 | */ |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 105 | private final String[] mForceQueryableByDevicePackageNames; |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 106 | |
| 107 | /** True if all system apps should be made queryable by default. */ |
| 108 | private final boolean mSystemAppsQueryable; |
| 109 | |
Patrick Baumann | dfb121d | 2019-08-05 14:36:19 -0700 | [diff] [blame] | 110 | private final FeatureConfig mFeatureConfig; |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 111 | |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 112 | AppsFilter(FeatureConfig featureConfig, String[] forceQueryableWhitelist, |
Ram Muthiah | 637138d | 2019-12-11 17:37:37 -0800 | [diff] [blame] | 113 | boolean systemAppsQueryable) { |
Patrick Baumann | dfb121d | 2019-08-05 14:36:19 -0700 | [diff] [blame] | 114 | mFeatureConfig = featureConfig; |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 115 | mForceQueryableByDevicePackageNames = forceQueryableWhitelist; |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 116 | mSystemAppsQueryable = systemAppsQueryable; |
| 117 | } |
| 118 | |
Patrick Baumann | dfb121d | 2019-08-05 14:36:19 -0700 | [diff] [blame] | 119 | public interface FeatureConfig { |
| 120 | /** Called when the system is ready and components can be queried. */ |
| 121 | void onSystemReady(); |
Patrick Baumann | af9c3fe | 2019-08-12 08:13:32 -0700 | [diff] [blame] | 122 | |
Patrick Baumann | dfb121d | 2019-08-05 14:36:19 -0700 | [diff] [blame] | 123 | /** @return true if we should filter apps at all. */ |
| 124 | boolean isGloballyEnabled(); |
| 125 | |
| 126 | /** @return true if the feature is enabled for the given package. */ |
Winson | 655a5b9 | 2019-10-23 10:49:32 -0700 | [diff] [blame] | 127 | boolean packageIsEnabled(AndroidPackage pkg); |
Patrick Baumann | dfb121d | 2019-08-05 14:36:19 -0700 | [diff] [blame] | 128 | } |
| 129 | |
| 130 | private static class FeatureConfigImpl implements FeatureConfig { |
| 131 | private static final String FILTERING_ENABLED_NAME = "package_query_filtering_enabled"; |
Anna Trostanetski | 66bb166 | 2019-10-29 16:44:25 +0000 | [diff] [blame] | 132 | private final PackageManagerService.Injector mInjector; |
Patrick Baumann | 9f463ad | 2019-10-15 10:11:10 -0700 | [diff] [blame] | 133 | private volatile boolean mFeatureEnabled = false; |
Patrick Baumann | dfb121d | 2019-08-05 14:36:19 -0700 | [diff] [blame] | 134 | |
| 135 | private FeatureConfigImpl(PackageManagerService.Injector injector) { |
Anna Trostanetski | 66bb166 | 2019-10-29 16:44:25 +0000 | [diff] [blame] | 136 | mInjector = injector; |
Patrick Baumann | dfb121d | 2019-08-05 14:36:19 -0700 | [diff] [blame] | 137 | } |
| 138 | |
| 139 | @Override |
| 140 | public void onSystemReady() { |
| 141 | mFeatureEnabled = DeviceConfig.getBoolean( |
Patrick Baumann | 9f463ad | 2019-10-15 10:11:10 -0700 | [diff] [blame] | 142 | NAMESPACE_PACKAGE_MANAGER_SERVICE, FILTERING_ENABLED_NAME, false); |
Patrick Baumann | dfb121d | 2019-08-05 14:36:19 -0700 | [diff] [blame] | 143 | DeviceConfig.addOnPropertiesChangedListener( |
| 144 | NAMESPACE_PACKAGE_MANAGER_SERVICE, FgThread.getExecutor(), |
| 145 | properties -> { |
Linus Tufvesson | 87776d6 | 2019-12-05 16:15:10 +0000 | [diff] [blame] | 146 | if (properties.getKeyset().contains(FILTERING_ENABLED_NAME)) { |
| 147 | synchronized (FeatureConfigImpl.this) { |
| 148 | mFeatureEnabled = properties.getBoolean(FILTERING_ENABLED_NAME, |
| 149 | false); |
| 150 | } |
Patrick Baumann | dfb121d | 2019-08-05 14:36:19 -0700 | [diff] [blame] | 151 | } |
| 152 | }); |
| 153 | } |
| 154 | |
| 155 | @Override |
| 156 | public boolean isGloballyEnabled() { |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 157 | Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "isGloballyEnabled"); |
| 158 | try { |
| 159 | return mFeatureEnabled; |
| 160 | } finally { |
| 161 | Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); |
| 162 | } |
Patrick Baumann | dfb121d | 2019-08-05 14:36:19 -0700 | [diff] [blame] | 163 | } |
| 164 | |
| 165 | @Override |
Winson | 655a5b9 | 2019-10-23 10:49:32 -0700 | [diff] [blame] | 166 | public boolean packageIsEnabled(AndroidPackage pkg) { |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 167 | Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "packageIsEnabled"); |
| 168 | try { |
Winson | 655a5b9 | 2019-10-23 10:49:32 -0700 | [diff] [blame] | 169 | // TODO(b/135203078): Do not use toAppInfo |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 170 | return mInjector.getCompatibility().isChangeEnabled( |
Winson | 6571c8a | 2019-10-23 17:00:42 -0700 | [diff] [blame] | 171 | PackageManager.FILTER_APPLICATION_QUERY, pkg.toAppInfoWithoutState()); |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 172 | } finally { |
| 173 | Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); |
| 174 | } |
Patrick Baumann | dfb121d | 2019-08-05 14:36:19 -0700 | [diff] [blame] | 175 | } |
| 176 | } |
| 177 | |
Patrick Baumann | dfb121d | 2019-08-05 14:36:19 -0700 | [diff] [blame] | 178 | public static AppsFilter create(PackageManagerService.Injector injector) { |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 179 | final boolean forceSystemAppsQueryable = |
Patrick Baumann | dfb121d | 2019-08-05 14:36:19 -0700 | [diff] [blame] | 180 | injector.getContext().getResources() |
| 181 | .getBoolean(R.bool.config_forceSystemPackagesQueryable); |
| 182 | final FeatureConfig featureConfig = new FeatureConfigImpl(injector); |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 183 | final String[] forcedQueryablePackageNames; |
| 184 | if (forceSystemAppsQueryable) { |
| 185 | // all system apps already queryable, no need to read and parse individual exceptions |
| 186 | forcedQueryablePackageNames = new String[]{}; |
| 187 | } else { |
| 188 | forcedQueryablePackageNames = |
Patrick Baumann | dfb121d | 2019-08-05 14:36:19 -0700 | [diff] [blame] | 189 | injector.getContext().getResources() |
| 190 | .getStringArray(R.array.config_forceQueryablePackages); |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 191 | for (int i = 0; i < forcedQueryablePackageNames.length; i++) { |
| 192 | forcedQueryablePackageNames[i] = forcedQueryablePackageNames[i].intern(); |
| 193 | } |
| 194 | } |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 195 | return new AppsFilter(featureConfig, forcedQueryablePackageNames, |
Ram Muthiah | 637138d | 2019-12-11 17:37:37 -0800 | [diff] [blame] | 196 | forceSystemAppsQueryable); |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 197 | } |
| 198 | |
| 199 | /** Returns true if the querying package may query for the potential target package */ |
Winson | 655a5b9 | 2019-10-23 10:49:32 -0700 | [diff] [blame] | 200 | private static boolean canQueryViaIntent(AndroidPackage querying, |
| 201 | AndroidPackage potentialTarget) { |
| 202 | if (querying.getQueriesIntents() == null) { |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 203 | return false; |
| 204 | } |
Winson | 655a5b9 | 2019-10-23 10:49:32 -0700 | [diff] [blame] | 205 | for (Intent intent : querying.getQueriesIntents()) { |
Patrick Baumann | 5863233 | 2019-10-09 10:12:10 -0700 | [diff] [blame] | 206 | if (matches(intent, potentialTarget)) { |
Patrick Baumann | 0c9257b | 2019-08-20 12:50:37 -0700 | [diff] [blame] | 207 | return true; |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 208 | } |
| 209 | } |
| 210 | return false; |
| 211 | } |
| 212 | |
Winson | 655a5b9 | 2019-10-23 10:49:32 -0700 | [diff] [blame] | 213 | private static boolean matches(Intent intent, AndroidPackage potentialTarget) { |
| 214 | for (int p = ArrayUtils.size(potentialTarget.getProviders()) - 1; p >= 0; p--) { |
| 215 | ParsedProvider provider = potentialTarget.getProviders().get(p); |
| 216 | if (!provider.isExported()) { |
Patrick Baumann | 5863233 | 2019-10-09 10:12:10 -0700 | [diff] [blame] | 217 | continue; |
| 218 | } |
Patrick Baumann | 0c9257b | 2019-08-20 12:50:37 -0700 | [diff] [blame] | 219 | final Uri data = intent.getData(); |
| 220 | if ("content".equalsIgnoreCase(intent.getScheme()) |
| 221 | && data != null |
Winson | 655a5b9 | 2019-10-23 10:49:32 -0700 | [diff] [blame] | 222 | && Objects.equals(provider.getAuthority(), data.getAuthority())) { |
Patrick Baumann | 0c9257b | 2019-08-20 12:50:37 -0700 | [diff] [blame] | 223 | return true; |
| 224 | } |
| 225 | } |
Winson | 655a5b9 | 2019-10-23 10:49:32 -0700 | [diff] [blame] | 226 | for (int s = ArrayUtils.size(potentialTarget.getServices()) - 1; s >= 0; s--) { |
| 227 | ParsedService service = potentialTarget.getServices().get(s); |
| 228 | if (!service.exported) { |
Patrick Baumann | 5863233 | 2019-10-09 10:12:10 -0700 | [diff] [blame] | 229 | continue; |
| 230 | } |
| 231 | if (matchesAnyFilter(intent, service)) { |
| 232 | return true; |
| 233 | } |
| 234 | } |
Winson | 655a5b9 | 2019-10-23 10:49:32 -0700 | [diff] [blame] | 235 | for (int a = ArrayUtils.size(potentialTarget.getActivities()) - 1; a >= 0; a--) { |
| 236 | ParsedActivity activity = potentialTarget.getActivities().get(a); |
| 237 | if (!activity.exported) { |
Patrick Baumann | 5863233 | 2019-10-09 10:12:10 -0700 | [diff] [blame] | 238 | continue; |
| 239 | } |
| 240 | if (matchesAnyFilter(intent, activity)) { |
| 241 | return true; |
| 242 | } |
| 243 | } |
Winson | 655a5b9 | 2019-10-23 10:49:32 -0700 | [diff] [blame] | 244 | for (int r = ArrayUtils.size(potentialTarget.getReceivers()) - 1; r >= 0; r--) { |
| 245 | ParsedActivity receiver = potentialTarget.getReceivers().get(r); |
| 246 | if (!receiver.exported) { |
Patrick Baumann | 5863233 | 2019-10-09 10:12:10 -0700 | [diff] [blame] | 247 | continue; |
| 248 | } |
| 249 | if (matchesAnyFilter(intent, receiver)) { |
| 250 | return true; |
| 251 | } |
| 252 | } |
| 253 | return false; |
| 254 | } |
Patrick Baumann | 0c9257b | 2019-08-20 12:50:37 -0700 | [diff] [blame] | 255 | |
Patrick Baumann | 5863233 | 2019-10-09 10:12:10 -0700 | [diff] [blame] | 256 | private static boolean matchesAnyFilter( |
Winson | 655a5b9 | 2019-10-23 10:49:32 -0700 | [diff] [blame] | 257 | Intent intent, ParsedComponent<? extends ParsedIntentInfo> component) { |
| 258 | List<? extends ParsedIntentInfo> intents = component.intents; |
| 259 | for (int i = ArrayUtils.size(intents) - 1; i >= 0; i--) { |
Patrick Baumann | 5863233 | 2019-10-09 10:12:10 -0700 | [diff] [blame] | 260 | IntentFilter intentFilter = intents.get(i); |
| 261 | if (intentFilter.match(intent.getAction(), intent.getType(), intent.getScheme(), |
| 262 | intent.getData(), intent.getCategories(), "AppsFilter") > 0) { |
| 263 | return true; |
Patrick Baumann | 0c9257b | 2019-08-20 12:50:37 -0700 | [diff] [blame] | 264 | } |
| 265 | } |
| 266 | return false; |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 267 | } |
| 268 | |
| 269 | /** |
Patrick Baumann | de37e43 | 2019-08-28 09:51:29 -0700 | [diff] [blame] | 270 | * Grants access based on an interaction between a calling and target package, granting |
| 271 | * visibility of the caller from the target. |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 272 | * |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 273 | * @param callingUid the uid initiating the interaction |
| 274 | * @param targetUid the uid being interacted with and thus gaining visibility of the |
| 275 | * initiating uid. |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 276 | */ |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 277 | public void grantImplicitAccess(int callingUid, int targetUid) { |
| 278 | if (mImplicitlyQueryable.add(targetUid, callingUid) && DEBUG_LOGGING) { |
| 279 | Slog.wtf(TAG, "implicit access granted: " + callingUid + " -> " + targetUid); |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 280 | } |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 281 | } |
| 282 | |
Patrick Baumann | dfb121d | 2019-08-05 14:36:19 -0700 | [diff] [blame] | 283 | public void onSystemReady() { |
| 284 | mFeatureConfig.onSystemReady(); |
| 285 | } |
| 286 | |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 287 | /** |
| 288 | * Adds a package that should be considered when filtering visibility between apps. |
| 289 | * |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 290 | * @param newPkgSetting the new setting being added |
| 291 | * @param existingSettings all other settings currently on the device. |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 292 | */ |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 293 | public void addPackage(PackageSetting newPkgSetting, |
| 294 | ArrayMap<String, PackageSetting> existingSettings) { |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 295 | Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "filter.addPackage"); |
| 296 | try { |
Winson | 655a5b9 | 2019-10-23 10:49:32 -0700 | [diff] [blame] | 297 | final AndroidPackage newPkg = newPkgSetting.pkg; |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 298 | if (newPkg == null) { |
| 299 | // nothing to add |
| 300 | return; |
| 301 | } |
| 302 | |
| 303 | final boolean newIsForceQueryable = |
| 304 | mForceQueryable.contains(newPkgSetting.appId) |
| 305 | /* shared user that is already force queryable */ |
Winson | 655a5b9 | 2019-10-23 10:49:32 -0700 | [diff] [blame] | 306 | || newPkg.isForceQueryable() |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 307 | || (newPkgSetting.isSystem() && (mSystemAppsQueryable |
| 308 | || ArrayUtils.contains(mForceQueryableByDevicePackageNames, |
Winson | 655a5b9 | 2019-10-23 10:49:32 -0700 | [diff] [blame] | 309 | newPkg.getPackageName()))); |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 310 | if (newIsForceQueryable) { |
| 311 | mForceQueryable.add(newPkgSetting.appId); |
| 312 | } |
| 313 | |
| 314 | for (int i = existingSettings.size() - 1; i >= 0; i--) { |
| 315 | final PackageSetting existingSetting = existingSettings.valueAt(i); |
| 316 | if (existingSetting.appId == newPkgSetting.appId || existingSetting.pkg == null) { |
| 317 | continue; |
| 318 | } |
Winson | 655a5b9 | 2019-10-23 10:49:32 -0700 | [diff] [blame] | 319 | final AndroidPackage existingPkg = existingSetting.pkg; |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 320 | // let's evaluate the ability of already added packages to see this new package |
| 321 | if (!newIsForceQueryable) { |
| 322 | if (canQueryViaIntent(existingPkg, newPkg)) { |
| 323 | mQueriesViaIntent.add(existingSetting.appId, newPkgSetting.appId); |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 324 | } |
Winson | 655a5b9 | 2019-10-23 10:49:32 -0700 | [diff] [blame] | 325 | if (existingPkg.getQueriesPackages() != null |
| 326 | && existingPkg.getQueriesPackages().contains(newPkg.getPackageName())) { |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 327 | mQueriesViaPackage.add(existingSetting.appId, newPkgSetting.appId); |
| 328 | } |
| 329 | } |
| 330 | // now we'll evaluate our new package's ability to see existing packages |
| 331 | if (!mForceQueryable.contains(existingSetting.appId)) { |
| 332 | if (canQueryViaIntent(newPkg, existingPkg)) { |
| 333 | mQueriesViaIntent.add(newPkgSetting.appId, existingSetting.appId); |
| 334 | } |
Winson | 655a5b9 | 2019-10-23 10:49:32 -0700 | [diff] [blame] | 335 | if (newPkg.getQueriesPackages() != null |
| 336 | && newPkg.getQueriesPackages().contains(existingPkg.getPackageName())) { |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 337 | mQueriesViaPackage.add(newPkgSetting.appId, existingSetting.appId); |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 338 | } |
| 339 | } |
| 340 | } |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 341 | } finally { |
| 342 | Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 343 | } |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 344 | } |
| 345 | |
| 346 | /** |
| 347 | * Removes a package for consideration when filtering visibility between apps. |
| 348 | * |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 349 | * @param setting the setting of the package being removed. |
| 350 | * @param allUsers array of all current users on device. |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 351 | */ |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 352 | public void removePackage(PackageSetting setting, int[] allUsers, |
| 353 | ArrayMap<String, PackageSetting> existingSettings) { |
| 354 | mForceQueryable.remove(setting.appId); |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 355 | |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 356 | for (int u = 0; u < allUsers.length; u++) { |
| 357 | final int userId = allUsers[u]; |
| 358 | final int removingUid = UserHandle.getUid(userId, setting.appId); |
| 359 | mImplicitlyQueryable.remove(removingUid); |
| 360 | for (int i = mImplicitlyQueryable.size() - 1; i >= 0; i--) { |
| 361 | mImplicitlyQueryable.remove(mImplicitlyQueryable.keyAt(i), removingUid); |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 362 | } |
| 363 | } |
| 364 | |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 365 | mQueriesViaIntent.remove(setting.appId); |
| 366 | for (int i = mQueriesViaIntent.size() - 1; i >= 0; i--) { |
| 367 | mQueriesViaIntent.remove(mQueriesViaIntent.keyAt(i), setting.appId); |
| 368 | } |
| 369 | mQueriesViaPackage.remove(setting.appId); |
| 370 | for (int i = mQueriesViaPackage.size() - 1; i >= 0; i--) { |
| 371 | mQueriesViaPackage.remove(mQueriesViaPackage.keyAt(i), setting.appId); |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 372 | } |
| 373 | |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 374 | // re-add other shared user members to re-establish visibility between them and other |
| 375 | // packages |
| 376 | if (setting.sharedUser != null) { |
| 377 | for (int i = setting.sharedUser.packages.size() - 1; i >= 0; i--) { |
| 378 | if (setting.sharedUser.packages.valueAt(i) == setting) { |
| 379 | continue; |
| 380 | } |
| 381 | addPackage(setting.sharedUser.packages.valueAt(i), existingSettings); |
| 382 | } |
| 383 | } |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 384 | } |
| 385 | |
| 386 | /** |
| 387 | * Returns true if the calling package should not be able to see the target package, false if no |
| 388 | * filtering should be done. |
| 389 | * |
| 390 | * @param callingUid the uid of the caller attempting to access a package |
| 391 | * @param callingSetting the setting attempting to access a package or null if it could not be |
| 392 | * found |
| 393 | * @param targetPkgSetting the package being accessed |
| 394 | * @param userId the user in which this access is being attempted |
| 395 | */ |
| 396 | public boolean shouldFilterApplication(int callingUid, @Nullable SettingBase callingSetting, |
| 397 | PackageSetting targetPkgSetting, int userId) { |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 398 | Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "shouldFilterApplication"); |
| 399 | try { |
Ram Muthiah | 637138d | 2019-12-11 17:37:37 -0800 | [diff] [blame] | 400 | if (!shouldFilterApplicationInternal(callingUid, callingSetting, |
| 401 | targetPkgSetting, |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 402 | userId)) { |
| 403 | return false; |
| 404 | } |
| 405 | if (DEBUG_LOGGING) { |
| 406 | log(callingSetting, targetPkgSetting, |
| 407 | DEBUG_ALLOW_ALL ? "ALLOWED" : "BLOCKED", new RuntimeException()); |
| 408 | } |
| 409 | return !DEBUG_ALLOW_ALL; |
| 410 | } finally { |
| 411 | Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); |
| 412 | } |
| 413 | } |
| 414 | |
Ram Muthiah | 637138d | 2019-12-11 17:37:37 -0800 | [diff] [blame] | 415 | private boolean shouldFilterApplicationInternal(int callingUid, |
| 416 | SettingBase callingSetting, PackageSetting targetPkgSetting, int userId) { |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 417 | Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "shouldFilterApplicationInternal"); |
| 418 | try { |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 419 | final boolean featureEnabled = mFeatureConfig.isGloballyEnabled(); |
| 420 | if (!featureEnabled) { |
| 421 | if (DEBUG_LOGGING) { |
| 422 | Slog.d(TAG, "filtering disabled; skipped"); |
| 423 | } |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 424 | return false; |
| 425 | } |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 426 | if (callingUid < Process.FIRST_APPLICATION_UID) { |
| 427 | if (DEBUG_LOGGING) { |
| 428 | Slog.d(TAG, "filtering skipped; " + callingUid + " is system"); |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 429 | } |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 430 | return false; |
| 431 | } |
| 432 | if (callingSetting == null) { |
| 433 | Slog.wtf(TAG, "No setting found for non system uid " + callingUid); |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 434 | return true; |
| 435 | } |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 436 | final PackageSetting callingPkgSetting; |
| 437 | final ArraySet<PackageSetting> callingSharedPkgSettings; |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 438 | if (callingSetting instanceof PackageSetting) { |
| 439 | callingPkgSetting = (PackageSetting) callingSetting; |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 440 | callingSharedPkgSettings = null; |
| 441 | } else { |
| 442 | callingPkgSetting = null; |
| 443 | callingSharedPkgSettings = ((SharedUserSetting) callingSetting).packages; |
| 444 | } |
| 445 | |
| 446 | if (callingPkgSetting != null) { |
| 447 | if (!mFeatureConfig.packageIsEnabled(callingPkgSetting.pkg)) { |
| 448 | if (DEBUG_LOGGING) { |
| 449 | log(callingSetting, targetPkgSetting, "DISABLED"); |
| 450 | } |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 451 | return false; |
| 452 | } |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 453 | } else { |
| 454 | for (int i = callingSharedPkgSettings.size() - 1; i >= 0; i--) { |
| 455 | if (!mFeatureConfig.packageIsEnabled(callingSharedPkgSettings.valueAt(i).pkg)) { |
| 456 | if (DEBUG_LOGGING) { |
| 457 | log(callingSetting, targetPkgSetting, "DISABLED"); |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 458 | } |
Patrick Baumann | a72e674 | 2019-11-06 08:26:56 -0800 | [diff] [blame] | 459 | return false; |
| 460 | } |
| 461 | } |
Patrick Baumann | a72e674 | 2019-11-06 08:26:56 -0800 | [diff] [blame] | 462 | } |
| 463 | |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 464 | // This package isn't technically installed and won't be written to settings, so we can |
| 465 | // treat it as filtered until it's available again. |
Winson | 655a5b9 | 2019-10-23 10:49:32 -0700 | [diff] [blame] | 466 | final AndroidPackage targetPkg = targetPkgSetting.pkg; |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 467 | if (targetPkg == null) { |
| 468 | if (DEBUG_LOGGING) { |
| 469 | Slog.wtf(TAG, "shouldFilterApplication: " + "targetPkg is null"); |
| 470 | } |
| 471 | return true; |
| 472 | } |
Winson | 655a5b9 | 2019-10-23 10:49:32 -0700 | [diff] [blame] | 473 | final String targetName = targetPkg.getPackageName(); |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 474 | final int callingAppId; |
| 475 | if (callingPkgSetting != null) { |
| 476 | callingAppId = callingPkgSetting.appId; |
| 477 | } else { |
| 478 | callingAppId = callingSharedPkgSettings.valueAt(0).appId; // all should be the same |
| 479 | } |
| 480 | final int targetAppId = targetPkgSetting.appId; |
| 481 | if (callingAppId == targetAppId) { |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 482 | if (DEBUG_LOGGING) { |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 483 | log(callingSetting, targetPkgSetting, "same app id"); |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 484 | } |
| 485 | return false; |
| 486 | } |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 487 | |
| 488 | if (callingSetting.getPermissionsState().hasPermission( |
| 489 | Manifest.permission.QUERY_ALL_PACKAGES, UserHandle.getUserId(callingUid))) { |
Patrick Baumann | a72e674 | 2019-11-06 08:26:56 -0800 | [diff] [blame] | 490 | if (DEBUG_LOGGING) { |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 491 | log(callingSetting, targetPkgSetting, "has query-all permission"); |
Patrick Baumann | a72e674 | 2019-11-06 08:26:56 -0800 | [diff] [blame] | 492 | } |
| 493 | return false; |
| 494 | } |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 495 | if (mForceQueryable.contains(targetAppId)) { |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 496 | if (DEBUG_LOGGING) { |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 497 | log(callingSetting, targetPkgSetting, "force queryable"); |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 498 | } |
| 499 | return false; |
| 500 | } |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 501 | if (mQueriesViaPackage.contains(callingAppId, targetAppId)) { |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 502 | // the calling package has explicitly declared the target package; allow |
| 503 | if (DEBUG_LOGGING) { |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 504 | log(callingSetting, targetPkgSetting, "queries package"); |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 505 | } |
| 506 | return false; |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 507 | } else if (mQueriesViaIntent.contains(callingAppId, targetAppId)) { |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 508 | if (DEBUG_LOGGING) { |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 509 | log(callingSetting, targetPkgSetting, "queries intent"); |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 510 | } |
| 511 | return false; |
| 512 | } |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 513 | |
| 514 | final int targetUid = UserHandle.getUid(userId, targetAppId); |
| 515 | if (mImplicitlyQueryable.contains(callingUid, targetUid)) { |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 516 | if (DEBUG_LOGGING) { |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 517 | log(callingSetting, targetPkgSetting, "implicitly queryable for user"); |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 518 | } |
| 519 | return false; |
| 520 | } |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 521 | if (callingPkgSetting != null) { |
| 522 | if (callingPkgInstruments(callingPkgSetting, targetPkgSetting, targetName)) { |
| 523 | return false; |
| 524 | } |
| 525 | } else { |
| 526 | for (int i = callingSharedPkgSettings.size() - 1; i >= 0; i--) { |
| 527 | if (callingPkgInstruments(callingSharedPkgSettings.valueAt(i), |
| 528 | targetPkgSetting, targetName)) { |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 529 | return false; |
| 530 | } |
| 531 | } |
| 532 | } |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 533 | return true; |
Patrick Baumann | 88318e0 | 2019-11-04 14:22:25 -0800 | [diff] [blame] | 534 | } finally { |
| 535 | Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 536 | } |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 537 | } |
| 538 | |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 539 | private static boolean callingPkgInstruments(PackageSetting callingPkgSetting, |
| 540 | PackageSetting targetPkgSetting, |
| 541 | String targetName) { |
Winson | 655a5b9 | 2019-10-23 10:49:32 -0700 | [diff] [blame] | 542 | final List<ComponentParseUtils.ParsedInstrumentation> inst = |
| 543 | callingPkgSetting.pkg.getInstrumentations(); |
| 544 | for (int i = ArrayUtils.size(inst) - 1; i >= 0; i--) { |
| 545 | if (Objects.equals(inst.get(i).getTargetPackage(), targetName)) { |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 546 | if (DEBUG_LOGGING) { |
| 547 | log(callingPkgSetting, targetPkgSetting, "instrumentation"); |
| 548 | } |
| 549 | return true; |
| 550 | } |
| 551 | } |
| 552 | return false; |
Patrick Baumann | 0c9257b | 2019-08-20 12:50:37 -0700 | [diff] [blame] | 553 | } |
| 554 | |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 555 | private static void log(SettingBase callingPkgSetting, PackageSetting targetPkgSetting, |
| 556 | String description) { |
| 557 | log(callingPkgSetting, targetPkgSetting, description, null); |
| 558 | } |
| 559 | |
| 560 | private static void log(SettingBase callingPkgSetting, PackageSetting targetPkgSetting, |
| 561 | String description, Throwable throwable) { |
| 562 | Slog.wtf(TAG, |
| 563 | "interaction: " + callingPkgSetting.toString() |
| 564 | + " -> " + targetPkgSetting.name + " " |
| 565 | + description, throwable); |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 566 | } |
| 567 | |
Patrick Baumann | a7ad66d | 2019-08-12 11:11:08 -0700 | [diff] [blame] | 568 | public void dumpQueries( |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 569 | PrintWriter pw, PackageManagerService pms, @Nullable Integer filteringAppId, |
| 570 | DumpState dumpState, |
Patrick Baumann | a7ad66d | 2019-08-12 11:11:08 -0700 | [diff] [blame] | 571 | int[] users) { |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 572 | final SparseArray<String> cache = new SparseArray<>(); |
| 573 | ToString<Integer> expandPackages = input -> { |
| 574 | String cachedValue = cache.get(input); |
| 575 | if (cachedValue == null) { |
| 576 | final String[] packagesForUid = pms.getPackagesForUid(input); |
| 577 | if (packagesForUid == null) { |
| 578 | cachedValue = "[unknown app id " + input + "]"; |
| 579 | } else { |
| 580 | cachedValue = packagesForUid.length == 1 ? packagesForUid[0] |
| 581 | : "[" + TextUtils.join(",", packagesForUid) + "]"; |
| 582 | } |
| 583 | cache.put(input, cachedValue); |
| 584 | } |
| 585 | return cachedValue; |
| 586 | }; |
Patrick Baumann | a7ad66d | 2019-08-12 11:11:08 -0700 | [diff] [blame] | 587 | pw.println(); |
| 588 | pw.println("Queries:"); |
| 589 | dumpState.onTitlePrinted(); |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 590 | if (!mFeatureConfig.isGloballyEnabled()) { |
| 591 | pw.println(" DISABLED"); |
| 592 | if (!DEBUG_LOGGING) { |
| 593 | return; |
| 594 | } |
| 595 | } |
Patrick Baumann | a7ad66d | 2019-08-12 11:11:08 -0700 | [diff] [blame] | 596 | pw.println(" system apps queryable: " + mSystemAppsQueryable); |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 597 | dumpPackageSet(pw, filteringAppId, mForceQueryable, "forceQueryable", " ", expandPackages); |
Patrick Baumann | a7ad66d | 2019-08-12 11:11:08 -0700 | [diff] [blame] | 598 | pw.println(" queries via package name:"); |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 599 | dumpQueriesMap(pw, filteringAppId, mQueriesViaPackage, " ", expandPackages); |
Patrick Baumann | a7ad66d | 2019-08-12 11:11:08 -0700 | [diff] [blame] | 600 | pw.println(" queries via intent:"); |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 601 | dumpQueriesMap(pw, filteringAppId, mQueriesViaIntent, " ", expandPackages); |
Patrick Baumann | a7ad66d | 2019-08-12 11:11:08 -0700 | [diff] [blame] | 602 | pw.println(" queryable via interaction:"); |
| 603 | for (int user : users) { |
| 604 | pw.append(" User ").append(Integer.toString(user)).println(":"); |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 605 | dumpQueriesMap(pw, |
| 606 | filteringAppId == null ? null : UserHandle.getUid(user, filteringAppId), |
| 607 | mImplicitlyQueryable, " ", expandPackages); |
Patrick Baumann | a7ad66d | 2019-08-12 11:11:08 -0700 | [diff] [blame] | 608 | } |
| 609 | } |
| 610 | |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 611 | private static void dumpQueriesMap(PrintWriter pw, @Nullable Integer filteringId, |
| 612 | SparseSetArray<Integer> queriesMap, String spacing, |
| 613 | @Nullable ToString<Integer> toString) { |
| 614 | for (int i = 0; i < queriesMap.size(); i++) { |
| 615 | Integer callingId = queriesMap.keyAt(i); |
| 616 | if (Objects.equals(callingId, filteringId)) { |
| 617 | // don't filter target package names if the calling is filteringId |
| 618 | dumpPackageSet( |
| 619 | pw, null /*filteringId*/, queriesMap.get(callingId), |
| 620 | toString == null |
| 621 | ? callingId.toString() |
| 622 | : toString.toString(callingId), |
| 623 | spacing, toString); |
Patrick Baumann | a7ad66d | 2019-08-12 11:11:08 -0700 | [diff] [blame] | 624 | } else { |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 625 | dumpPackageSet( |
| 626 | pw, filteringId, queriesMap.get(callingId), |
| 627 | toString == null |
| 628 | ? callingId.toString() |
| 629 | : toString.toString(callingId), |
| 630 | spacing, toString); |
Patrick Baumann | a7ad66d | 2019-08-12 11:11:08 -0700 | [diff] [blame] | 631 | } |
| 632 | } |
| 633 | } |
| 634 | |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 635 | private interface ToString<T> { |
| 636 | String toString(T input); |
| 637 | } |
| 638 | |
| 639 | private static <T> void dumpPackageSet(PrintWriter pw, @Nullable T filteringId, |
| 640 | Set<T> targetPkgSet, String subTitle, String spacing, |
| 641 | @Nullable ToString<T> toString) { |
Patrick Baumann | a7ad66d | 2019-08-12 11:11:08 -0700 | [diff] [blame] | 642 | if (targetPkgSet != null && targetPkgSet.size() > 0 |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 643 | && (filteringId == null || targetPkgSet.contains(filteringId))) { |
Patrick Baumann | a7ad66d | 2019-08-12 11:11:08 -0700 | [diff] [blame] | 644 | pw.append(spacing).append(subTitle).println(":"); |
Patrick Baumann | b9a49f4 | 2019-11-13 16:42:18 -0800 | [diff] [blame] | 645 | for (T item : targetPkgSet) { |
| 646 | if (filteringId == null || Objects.equals(filteringId, item)) { |
| 647 | pw.append(spacing).append(" ") |
| 648 | .println(toString == null ? item : toString.toString(item)); |
Patrick Baumann | a7ad66d | 2019-08-12 11:11:08 -0700 | [diff] [blame] | 649 | } |
| 650 | } |
| 651 | } |
| 652 | } |
Patrick Baumann | 6c1c809 | 2019-06-27 14:55:44 -0700 | [diff] [blame] | 653 | } |