1 /* 2 * Copyright (C) 2022 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.resolution; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.UserIdInt; 22 import android.content.ComponentName; 23 import android.content.Intent; 24 import android.content.pm.ApplicationInfo; 25 import android.content.pm.ProviderInfo; 26 import android.content.pm.ResolveInfo; 27 import android.os.UserHandle; 28 import android.util.ArrayMap; 29 import android.util.Pair; 30 31 import com.android.internal.pm.pkg.component.ParsedActivity; 32 import com.android.internal.pm.pkg.component.ParsedIntentInfo; 33 import com.android.internal.pm.pkg.component.ParsedMainComponent; 34 import com.android.internal.pm.pkg.component.ParsedProvider; 35 import com.android.internal.pm.pkg.component.ParsedService; 36 import com.android.server.pm.Computer; 37 import com.android.server.pm.DumpState; 38 import com.android.server.pm.UserManagerService; 39 import com.android.server.pm.parsing.PackageInfoUtils; 40 import com.android.server.pm.parsing.pkg.AndroidPackageUtils; 41 import com.android.server.pm.pkg.AndroidPackage; 42 import com.android.server.pm.pkg.PackageStateInternal; 43 import com.android.server.pm.pkg.PackageUserStateInternal; 44 import com.android.server.utils.WatchableImpl; 45 46 import java.io.PrintWriter; 47 import java.util.ArrayList; 48 import java.util.Iterator; 49 import java.util.List; 50 import java.util.Map; 51 52 public abstract class ComponentResolverBase extends WatchableImpl implements ComponentResolverApi { 53 54 @NonNull 55 protected ComponentResolver.ActivityIntentResolver mActivities; 56 57 @NonNull 58 protected ComponentResolver.ProviderIntentResolver mProviders; 59 60 @NonNull 61 protected ComponentResolver.ReceiverIntentResolver mReceivers; 62 63 @NonNull 64 protected ComponentResolver.ServiceIntentResolver mServices; 65 66 /** Mapping from provider authority [first directory in content URI codePath) to provider. */ 67 @NonNull 68 protected ArrayMap<String, ParsedProvider> mProvidersByAuthority; 69 70 @NonNull 71 protected final UserManagerService mUserManager; 72 ComponentResolverBase(@onNull UserManagerService userManager)73 protected ComponentResolverBase(@NonNull UserManagerService userManager) { 74 mUserManager = userManager; 75 } 76 77 @Override componentExists(@onNull ComponentName componentName)78 public boolean componentExists(@NonNull ComponentName componentName) { 79 ParsedMainComponent component = mActivities.mActivities.get(componentName); 80 if (component != null) { 81 return true; 82 } 83 component = mReceivers.mActivities.get(componentName); 84 if (component != null) { 85 return true; 86 } 87 component = mServices.mServices.get(componentName); 88 if (component != null) { 89 return true; 90 } 91 return mProviders.mProviders.get(componentName) != null; 92 } 93 94 @Nullable 95 @Override getActivity(@onNull ComponentName component)96 public ParsedActivity getActivity(@NonNull ComponentName component) { 97 return mActivities.mActivities.get(component); 98 } 99 100 @Nullable 101 @Override getProvider(@onNull ComponentName component)102 public ParsedProvider getProvider(@NonNull ComponentName component) { 103 return mProviders.mProviders.get(component); 104 } 105 106 @Nullable 107 @Override getReceiver(@onNull ComponentName component)108 public ParsedActivity getReceiver(@NonNull ComponentName component) { 109 return mReceivers.mActivities.get(component); 110 } 111 112 @Nullable 113 @Override getService(@onNull ComponentName component)114 public ParsedService getService(@NonNull ComponentName component) { 115 return mServices.mServices.get(component); 116 } 117 118 /** 119 * Returns {@code true} if the given activity is defined by some package 120 */ 121 @Override isActivityDefined(@onNull ComponentName component)122 public boolean isActivityDefined(@NonNull ComponentName component) { 123 return mActivities.mActivities.get(component) != null; 124 } 125 126 @Nullable 127 @Override queryActivities(@onNull Computer computer, @NonNull Intent intent, @Nullable String resolvedType, long flags, int userId)128 public List<ResolveInfo> queryActivities(@NonNull Computer computer, @NonNull Intent intent, 129 @Nullable String resolvedType, long flags, int userId) { 130 return mActivities.queryIntent(computer, intent, resolvedType, flags, userId); 131 } 132 133 @Nullable 134 @Override queryActivities(@onNull Computer computer, @NonNull Intent intent, @Nullable String resolvedType, long flags, @NonNull List<ParsedActivity> activities, int userId)135 public List<ResolveInfo> queryActivities(@NonNull Computer computer, @NonNull Intent intent, 136 @Nullable String resolvedType, long flags, @NonNull List<ParsedActivity> activities, 137 int userId) { 138 return mActivities.queryIntentForPackage(computer, intent, resolvedType, flags, activities, 139 userId); 140 } 141 142 @Nullable 143 @Override queryProvider(@onNull Computer computer, @NonNull String authority, long flags, int userId)144 public ProviderInfo queryProvider(@NonNull Computer computer, @NonNull String authority, 145 long flags, int userId) { 146 final ParsedProvider p = mProvidersByAuthority.get(authority); 147 if (p == null) { 148 return null; 149 } 150 PackageStateInternal packageState = computer.getPackageStateInternal(p.getPackageName()); 151 if (packageState == null) { 152 return null; 153 } 154 final AndroidPackage pkg = packageState.getPkg(); 155 if (pkg == null) { 156 return null; 157 } 158 final PackageUserStateInternal state = packageState.getUserStateOrDefault(userId); 159 ApplicationInfo appInfo = PackageInfoUtils.generateApplicationInfo( 160 pkg, flags, state, userId, packageState); 161 if (appInfo == null) { 162 return null; 163 } 164 return PackageInfoUtils.generateProviderInfo(pkg, p, flags, state, appInfo, userId, 165 packageState); 166 } 167 168 @Nullable 169 @Override queryProviders(@onNull Computer computer, @NonNull Intent intent, @Nullable String resolvedType, long flags, int userId)170 public List<ResolveInfo> queryProviders(@NonNull Computer computer, @NonNull Intent intent, 171 @Nullable String resolvedType, long flags, int userId) { 172 return mProviders.queryIntent(computer, intent, resolvedType, flags, userId); 173 } 174 175 @Nullable 176 @Override queryProviders(@onNull Computer computer, @NonNull Intent intent, @Nullable String resolvedType, long flags, @NonNull List<ParsedProvider> providers, @UserIdInt int userId)177 public List<ResolveInfo> queryProviders(@NonNull Computer computer, @NonNull Intent intent, 178 @Nullable String resolvedType, long flags, @NonNull List<ParsedProvider> providers, 179 @UserIdInt int userId) { 180 return mProviders.queryIntentForPackage(computer, intent, resolvedType, flags, providers, 181 userId); 182 } 183 184 @Nullable 185 @Override queryProviders(@onNull Computer computer, @Nullable String processName, @Nullable String metaDataKey, int uid, long flags, int userId)186 public List<ProviderInfo> queryProviders(@NonNull Computer computer, 187 @Nullable String processName, @Nullable String metaDataKey, int uid, long flags, 188 int userId) { 189 if (!mUserManager.exists(userId)) { 190 return null; 191 } 192 List<ProviderInfo> providerList = null; 193 PackageInfoUtils.CachedApplicationInfoGenerator appInfoGenerator = null; 194 for (int i = mProviders.mProviders.size() - 1; i >= 0; --i) { 195 final ParsedProvider p = mProviders.mProviders.valueAt(i); 196 if (p.getAuthority() == null) { 197 continue; 198 } 199 200 final PackageStateInternal ps = computer.getPackageStateInternal(p.getPackageName()); 201 if (ps == null) { 202 continue; 203 } 204 205 AndroidPackage pkg = ps.getPkg(); 206 if (pkg == null) { 207 continue; 208 } 209 210 if (processName != null && (!p.getProcessName().equals(processName) 211 || !UserHandle.isSameApp(pkg.getUid(), uid))) { 212 continue; 213 } 214 // See PM.queryContentProviders()'s javadoc for why we have the metaData parameter. 215 if (metaDataKey != null && !p.getMetaData().containsKey(metaDataKey)) { 216 continue; 217 } 218 if (appInfoGenerator == null) { 219 appInfoGenerator = new PackageInfoUtils.CachedApplicationInfoGenerator(); 220 } 221 final PackageUserStateInternal state = ps.getUserStateOrDefault(userId); 222 final ApplicationInfo appInfo = 223 appInfoGenerator.generate(pkg, flags, state, userId, ps); 224 if (appInfo == null) { 225 continue; 226 } 227 228 final ProviderInfo info = PackageInfoUtils.generateProviderInfo( 229 pkg, p, flags, state, appInfo, userId, ps); 230 if (info == null) { 231 continue; 232 } 233 if (providerList == null) { 234 providerList = new ArrayList<>(i + 1); 235 } 236 providerList.add(info); 237 } 238 return providerList; 239 } 240 241 @Nullable 242 @Override queryReceivers(@onNull Computer computer, @NonNull Intent intent, @Nullable String resolvedType, long flags, int userId)243 public List<ResolveInfo> queryReceivers(@NonNull Computer computer, @NonNull Intent intent, 244 @Nullable String resolvedType, long flags, int userId) { 245 return mReceivers.queryIntent(computer, intent, resolvedType, flags, userId); 246 } 247 248 @Nullable 249 @Override queryReceivers(@onNull Computer computer, @NonNull Intent intent, @Nullable String resolvedType, long flags, @NonNull List<ParsedActivity> receivers, @UserIdInt int userId)250 public List<ResolveInfo> queryReceivers(@NonNull Computer computer, @NonNull Intent intent, 251 @Nullable String resolvedType, long flags, @NonNull List<ParsedActivity> receivers, 252 @UserIdInt int userId) { 253 return mReceivers.queryIntentForPackage(computer, intent, resolvedType, flags, receivers, 254 userId); 255 } 256 257 @Nullable 258 @Override queryServices(@onNull Computer computer, @NonNull Intent intent, @Nullable String resolvedType, long flags, @UserIdInt int userId)259 public List<ResolveInfo> queryServices(@NonNull Computer computer, @NonNull Intent intent, 260 @Nullable String resolvedType, long flags, @UserIdInt int userId) { 261 return mServices.queryIntent(computer, intent, resolvedType, flags, userId); 262 } 263 264 @Nullable 265 @Override queryServices(@onNull Computer computer, @NonNull Intent intent, @Nullable String resolvedType, long flags, @NonNull List<ParsedService> services, @UserIdInt int userId)266 public List<ResolveInfo> queryServices(@NonNull Computer computer, @NonNull Intent intent, 267 @Nullable String resolvedType, long flags, @NonNull List<ParsedService> services, 268 @UserIdInt int userId) { 269 return mServices.queryIntentForPackage(computer, intent, resolvedType, flags, services, 270 userId); 271 } 272 273 @Override querySyncProviders(@onNull Computer computer, @NonNull List<String> outNames, @NonNull List<ProviderInfo> outInfo, boolean safeMode, int userId)274 public void querySyncProviders(@NonNull Computer computer, @NonNull List<String> outNames, 275 @NonNull List<ProviderInfo> outInfo, boolean safeMode, int userId) { 276 PackageInfoUtils.CachedApplicationInfoGenerator appInfoGenerator = null; 277 for (int i = mProvidersByAuthority.size() - 1; i >= 0; --i) { 278 final ParsedProvider p = mProvidersByAuthority.valueAt(i); 279 if (!p.isSyncable()) { 280 continue; 281 } 282 283 final PackageStateInternal ps = computer.getPackageStateInternal(p.getPackageName()); 284 if (ps == null) { 285 continue; 286 } 287 288 final AndroidPackage pkg = ps.getPkg(); 289 if (pkg == null) { 290 continue; 291 } 292 293 if (safeMode && !ps.isSystem()) { 294 continue; 295 } 296 if (appInfoGenerator == null) { 297 appInfoGenerator = new PackageInfoUtils.CachedApplicationInfoGenerator(); 298 } 299 final PackageUserStateInternal state = ps.getUserStateOrDefault(userId); 300 final ApplicationInfo appInfo = 301 appInfoGenerator.generate(pkg, 0, state, userId, ps); 302 if (appInfo == null) { 303 continue; 304 } 305 306 final ProviderInfo info = PackageInfoUtils.generateProviderInfo( 307 pkg, p, 0, state, appInfo, userId, ps); 308 if (info == null) { 309 continue; 310 } 311 outNames.add(mProvidersByAuthority.keyAt(i)); 312 outInfo.add(info); 313 } 314 } 315 316 @Override dumpActivityResolvers(@onNull PrintWriter pw, @NonNull DumpState dumpState, @NonNull String packageName)317 public void dumpActivityResolvers(@NonNull PrintWriter pw, @NonNull DumpState dumpState, 318 @NonNull String packageName) { 319 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 320 : "Activity Resolver Table:", " ", packageName, 321 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 322 dumpState.setTitlePrinted(true); 323 } 324 } 325 326 @Override dumpProviderResolvers(@onNull PrintWriter pw, @NonNull DumpState dumpState, @NonNull String packageName)327 public void dumpProviderResolvers(@NonNull PrintWriter pw, @NonNull DumpState dumpState, 328 @NonNull String packageName) { 329 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 330 : "Provider Resolver Table:", " ", packageName, 331 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 332 dumpState.setTitlePrinted(true); 333 } 334 } 335 336 @Override dumpReceiverResolvers(@onNull PrintWriter pw, @NonNull DumpState dumpState, @NonNull String packageName)337 public void dumpReceiverResolvers(@NonNull PrintWriter pw, @NonNull DumpState dumpState, 338 @NonNull String packageName) { 339 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 340 : "Receiver Resolver Table:", " ", packageName, 341 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 342 dumpState.setTitlePrinted(true); 343 } 344 } 345 346 @Override dumpServiceResolvers(@onNull PrintWriter pw, @NonNull DumpState dumpState, @NonNull String packageName)347 public void dumpServiceResolvers(@NonNull PrintWriter pw, @NonNull DumpState dumpState, 348 @NonNull String packageName) { 349 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 350 : "Service Resolver Table:", " ", packageName, 351 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 352 dumpState.setTitlePrinted(true); 353 } 354 } 355 356 @Override dumpContentProviders(@onNull Computer computer, @NonNull PrintWriter pw, @NonNull DumpState dumpState, @NonNull String packageName)357 public void dumpContentProviders(@NonNull Computer computer, @NonNull PrintWriter pw, 358 @NonNull DumpState dumpState, @NonNull String packageName) { 359 boolean printedSomething = false; 360 for (ParsedProvider p : mProviders.mProviders.values()) { 361 if (packageName != null && !packageName.equals(p.getPackageName())) { 362 continue; 363 } 364 if (!printedSomething) { 365 if (dumpState.onTitlePrinted()) { 366 pw.println(); 367 } 368 pw.println("Registered ContentProviders:"); 369 printedSomething = true; 370 } 371 pw.print(" "); 372 ComponentName.printShortString(pw, p.getPackageName(), p.getName()); 373 pw.println(":"); 374 pw.print(" "); 375 pw.println(p.toString()); 376 } 377 printedSomething = false; 378 for (Map.Entry<String, ParsedProvider> entry : 379 mProvidersByAuthority.entrySet()) { 380 ParsedProvider p = entry.getValue(); 381 if (packageName != null && !packageName.equals(p.getPackageName())) { 382 continue; 383 } 384 if (!printedSomething) { 385 if (dumpState.onTitlePrinted()) { 386 pw.println(); 387 } 388 pw.println("ContentProvider Authorities:"); 389 printedSomething = true; 390 } 391 pw.print(" ["); 392 pw.print(entry.getKey()); 393 pw.println("]:"); 394 pw.print(" "); 395 pw.println(p.toString()); 396 397 AndroidPackage pkg = computer.getPackage(p.getPackageName()); 398 399 if (pkg != null) { 400 pw.print(" applicationInfo="); 401 pw.println(AndroidPackageUtils.generateAppInfoWithoutState(pkg)); 402 } 403 } 404 } 405 406 @Override dumpServicePermissions(@onNull PrintWriter pw, @NonNull DumpState dumpState)407 public void dumpServicePermissions(@NonNull PrintWriter pw, @NonNull DumpState dumpState) { 408 if (dumpState.onTitlePrinted()) pw.println(); 409 pw.println("Service permissions:"); 410 411 final Iterator<Pair<ParsedService, ParsedIntentInfo>> filterIterator = 412 mServices.filterIterator(); 413 while (filterIterator.hasNext()) { 414 final Pair<ParsedService, ParsedIntentInfo> pair = filterIterator.next(); 415 ParsedService service = pair.first; 416 417 final String permission = service.getPermission(); 418 if (permission != null) { 419 pw.print(" "); 420 pw.print(service.getComponentName().flattenToShortString()); 421 pw.print(": "); 422 pw.println(permission); 423 } 424 } 425 } 426 427 } 428