Android 10.0 ContentProvider 启动过程源码分析

ContentProvider 启动过程

1.概述:

Content Provider 作为四大组件之一,主要用于进程内和进程间的数据共享。

本文主要讲解:应用程序 A 首次跨进程 query 应用程序 B 的 ContentProvider 的流程。

讲解代码为 AOSP Android 10,链接:http://aospxref.com/android-10.0.0_r2/

2.进程间首次访问 Content Provider 时序图:

Android 10.0 ContentProvider 启动过程源码分析

 

3. 详细讲解

以时序图的步骤讲解。

3.1 step 1

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Uri uri = Uri.parse("content://com.sample.b.providers.UserInfoProvider");
        Cursor cursor = getContentResolver().query(uri,null,null,null,null);
    }
}

A 应用调用 query 方法,getContentResolver 方法调用关系如下:

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/core/java/android/content/ContextWrapper.java

59      Context mBase;

......

101      @Override

102      public ContentResolver getContentResolver() {

103          return mBase.getContentResolver();

104      }

mBase 指的是 ContextImpl,其 getContentResolver 方法如下:

aospxref.com/android-10.0.0_r2/xref/frameworks/base/core/java/android/app/ContextImpl.java

199      private final ApplicationContentResolver mContentResolver;

......

309      @Override

310      public ContentResolver getContentResolver() {

311          return mContentResolver;

312      }

......

2516      private ContextImpl(@Nullable ContextImpl container, @NonNull ActivityThread mainThread,

2517              @NonNull LoadedApk packageInfo, @Nullable String splitName,

2518              @Nullable IBinder activityToken, @Nullable UserHandle user, int flags,

2519              @Nullable ClassLoader classLoader, @Nullable String overrideOpPackageName) {

……

2571          mContentResolver = new ApplicationContentResolver(this, mainThread);

2572      }

......

2694      private static final class ApplicationContentResolver extends ContentResolver {

……

2749      }

getContentResolver 返回了 ApplicationContentResolver 类型的 mContentResolver。

ApplicationContentResolver  是 ContextImpl 中的静态内部类,继承自 ContentProvider, 在 ContextImpl 构造方法中被创建。

query 方法在 ApplicationContentResolver 的父类 ContentResolver 中实现,最终会调用:

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/core/java/android/content/ContentResolver.java

914      @Override

915      public final @Nullable Cursor query(final @RequiresPermission.Read @NonNull Uri uri,

916              @Nullable String[] projection, @Nullable Bundle queryArgs,

917              @Nullable CancellationSignal cancellationSignal) {

......

928          IContentProvider unstableProvider = acquireUnstableProvider(uri); // 1

......

934          try {

......

942              }

943              try {

944                  qCursor = unstableProvider.query(mPackageName, uri, projection,

945                          queryArgs, remoteCancellationSignal); // 2

946              } catch (DeadObjectException e) {

......

957              }

......

974          } catch (RemoteException e) {

......

 

977              return null;

978          } finally {

......

991          }

992      }

//1 通过 acquireUnstableProvider 获得一个 IContentProvider 对象 unstableProvider。IContentProvider 是 业务实现类 ContentProvider 的本地代理 。

//2 调用代理对象 unstableProvider 的 query 方法,完成跨进程查询操作。

3.2 step 2

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/core/java/android/content/ContentResolver.java

693      @UnsupportedAppUsage

694      protected abstract IContentProvider acquireUnstableProvider(Context c, String name);

......

2111      public final IContentProvider acquireUnstableProvider(Uri uri) {

2112          if (!SCHEME_CONTENT.equals(uri.getScheme())) {

2113              return null;

2114          }

2115          String auth = uri.getAuthority();

2116          if (auth != null) {

2117              return acquireUnstableProvider(mContext, uri.getAuthority());

2118          }

2119          return null;

2120      }

protected abstract IContentProvider acquireUnstableProvider(Context c, String name); 这个抽象方法是在 ContentResolver 的子类 ApplicationContentResolver 中实现的

3.3 step 3

ApplicationContentResolver  是 ContextImpl 中的静态内部类

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/core/java/android/app/ContextImpl.java

2694      private static final class ApplicationContentResolver extends ContentResolver {

2695          @UnsupportedAppUsage

2696          private final ActivityThread mMainThread;

2697 

2698          public ApplicationContentResolver(Context context, ActivityThread mainThread) {

2699              super(context);

2700              mMainThread = Preconditions.checkNotNull(mainThread);

2701          }

......

2723          @Override

2724          protected IContentProvider acquireUnstableProvider(Context c, String auth) {

2725              return mMainThread.acquireProvider(c,

2726                      ContentProvider.getAuthorityWithoutUserId(auth),

2727                      resolveUserIdFromAuthority(auth), false);

2728          }

......

2749      }

调用了 ActivityThread 的 acquireUnstableProvider 方法

3.4 step 4

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/core/java/android/app/ActivityThread.java

424      final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap

425          = new ArrayMap<ProviderKey, ProviderClientRecord>(); // 1

......

662      final class ProviderClientRecord { // 客户端使用的

663          final String[] mNames;

665          final IContentProvider mProvider;

667          final ContentProvider mLocalProvider;

669          final ContentProviderHolder mHolder;

......

678      }

......

6545      public final IContentProvider acquireProvider(

6546              Context c, String auth, int userId, boolean stable) {

6547          final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable); // 2

......

6558          ContentProviderHolder holder = null; // 3

6559          try {

6560              synchronized (getGetProviderLock(auth, userId)) {

6561                  holder = ActivityManager.getService().getContentProvider(

6562                          getApplicationThread(), c.getOpPackageName(), auth, userId, stable); // 4

6563              }

6564          } catch (RemoteException ex) {

6565              throw ex.rethrowFromSystemServer();

6566          }

......

6574          holder = installProvider(c, holder, holder.info,

6575                  true /*noisy*/, holder.noReleaseNeeded, stable); // 5

6576          return holder.provider;

6577      }

......

6659      @UnsupportedAppUsage

6660      public final IContentProvider acquireExistingProvider(

6661              Context c, String auth, int userId, boolean stable) {

6662          synchronized (mProviderMap) {

6663              final ProviderKey key = new ProviderKey(auth, userId);

6664              final ProviderClientRecord pr = mProviderMap.get(key);

......

6669              IContentProvider provider = pr.mProvider;

6670              IBinder jBinder = provider.asBinder();

6671              if (!jBinder.isBinderAlive()) { // 6

......

6676                  handleUnstableProviderDiedLocked(jBinder, true); // 7

6677                  return null;

6678              }

......

6686              return provider;

6687          }

6688      }

......

6827      final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) {

6828          ProviderRefCount prc = mProviderRefCountMap.get(provider);

6829          if (prc != null) {

......

6832              mProviderRefCountMap.remove(provider);

6833              for (int i=mProviderMap.size()-1; i>=0; i--) {

6834                  ProviderClientRecord pr = mProviderMap.valueAt(i);

6835                  if (pr != null && pr.mProvider.asBinder() == provider) {

6836                      Slog.i(TAG, "Removing dead content provider:" + pr.mProvider.toString());

6837                      mProviderMap.removeAt(i); // 8

6838                  }

6839              }

6840 

6841              if (fromClient) {

......

6847                  try {

6848                      ActivityManager.getService().unstableProviderDied(

6849                              prc.holder.connection); // 9

6850                  } catch (RemoteException e) {

6851                      //do nothing content provider object is dead any way

6852                  }

6853              }

6854          }

6855      }

// 1 ActivityThread 本地用于缓存 ProviderClientRecord(包含 IContentProvider,ContentProvider ,ContentProviderHolder ) 的 ArrayMap 对象 mProviderMap

// 2 调用 acquireExistingProvider 查找缓存 mProviderMap 中是否有目标 ContentProvider,有则返回

// 3 ContentProviderHolder 用于进程间传递 ContentProvider 相关信息(ProviderInfo,IContentProvider,IBinder 等),如用于 AMS 和 应用进程间传递信息

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/core/java/android/app/ContentProviderHolder.java

33  public class ContentProviderHolder implements Parcelable {

35      public final ProviderInfo info;

37      public IContentProvider provider;

38      public IBinder connection;

40      public boolean noReleaseNeeded;

85  }


ProviderInfo:用于存储有关 pm 的 ContentProvider 信息,信息包括权限、进程、用户等

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/core/java/android/content/pm/ProviderInfo.java

30  public final class ProviderInfo extends ComponentInfo

31          implements Parcelable {

38      public String readPermission = null;

42      public String writePermission = null;

49      public boolean grantUriPermissions = false;

55      public boolean forceUriPermissions = false;

65      public PatternMatcher[] uriPermissionPatterns = null;

73      public PathPermission[] pathPermissions = null;

78      public boolean multiprocess = false;

82      public int initOrder = 0;

88      public static final int FLAG_VISIBLE_TO_INSTANT_APP = 0x100000;

95      public static final int FLAG_SINGLE_USER = 0x40000000;

102      public int flags = 0;

190  }


// 4 调用 IActivityManager 的 getContentProvider 方法,最终会调用 AMS 的对应方法

// 5 installProvider 方法:把从 AMS 中返回的 ContentProvider 进行本地安装保存等,step 26 会重点说明

// 6 IBinder 对象挂掉了

// 7 处理善后工作

// 8 从 mProviderMap 中删除

// 9 通知 AMS 做善后工作

3.5 step 5

3.6 step 6

调用 AMS 的 getContentProvider 

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

7221      @Override

7222      public final ContentProviderHolder getContentProvider(

7223              IApplicationThread caller, String callingPackage, String name, int userId,

7224              boolean stable) {

......

7240          return getContentProviderImpl(caller, name, null, callingUid, callingPackage,

7241                  null, stable, userId);

7242      }

3.7 step 7

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

470      static final int CONTENT_PROVIDER_WAIT_TIMEOUT = 20 * 1000; // 连接一个新创建的 ContentProvider 的超时时间为20S

 

6706      private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,

6707              String name, IBinder token, int callingUid, String callingPackage, String callingTag,

6708              boolean stable, int userId) {

6709          ContentProviderRecord cpr; // 1  ContentProviderRecord 只应用在 AMS 中,用来记录 ContentProvider 组件相关信息

6710          ContentProviderConnection conn = null;

6711          ProviderInfo cpi = null; // 用来描述 ContentProvider 组件相关信息

6712          boolean providerRunning = false;

6713 

6714          synchronized(this) {

6717              ProcessRecord r = null; // 记录进程信息

6718              if (caller != null) {

6719                  r = getRecordForAppLocked(caller); // 获取调用方的进程信息,即应用程序 A 的进程信息

6726              }

                       // 检查目标 ContentProvider 组件是否已经发布了

6732              // First check if this content provider has been published...

6733              cpr = mProviderMap.getProviderByName(name, userId);

6752              if (cpr != null && cpr.proc != null) {

6753                  providerRunning = !cpr.proc.killed;

6770              }

6772              if (providerRunning) { // ContentProvider 组件已经发布

6776                  if (r != null && cpr.canRunHere(r)) { // 2 组件发布了并且能够运行在调用方所在的进程

6791                      // This provider has been published or is in the process

6792                      // of being published...  but it is also allowed to run

6793                      // in the caller's process, so don't make a connection

6794                      // and just let the caller instantiate its own instance.

6795                      ContentProviderHolder holder = cpr.newHolder(null);

6796                      // don't give caller the provider object, it needs

6797                      // to make its own.

6798                      holder.provider = null;

6799                      return holder;

6800                  }

6889              if (!providerRunning) { // ContentProvider 组件还没有启动

6890                  try {

6892                      cpi = AppGlobals.getPackageManager().

6893                          resolveContentProvider(name,

6894                              STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);

6896                  } catch (RemoteException ex) {

6897                  }

6898                  if (cpi == null) {

6899                      return null;

6900                  }

6953                  ComponentName comp = new ComponentName(cpi.packageName, cpi.name);

                           // 通过 ContentProvider 组件名获取对应的 ContentProviderRecord 对象

6955                  cpr = mProviderMap.getProviderByClass(comp, userId); // 3

6957                  final boolean firstClass = cpr == null;

6958                  if (firstClass) { // ContentProviderRecord 对象为空,没有找到

6959                      final long ident = Binder.clearCallingIdentity();

6968                      try {

6970                          ApplicationInfo ai =

6971                              AppGlobals.getPackageManager().

6972                                  getApplicationInfo(

6973                                          cpi.applicationInfo.packageName,

6974                                          STOCK_PM_FLAGS, userId);

6981                          ai = getAppInfoForUser(ai, userId);

6982                          cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); // 创建一个新的 ContentProviderRecord 对象

6983                      } catch (RemoteException ex) {

6984                          // pm is in same process, this will never happen.

6985                      } finally {

6986                          Binder.restoreCallingIdentity(ident);

6987                      }

6988                  }

6992                  if (r != null && cpr.canRunHere(r)) { // 能够在此访问进程中启动,即应用程序 A

6993                      // If this is a multiprocess provider, then just return its

6994                      // info and allow the caller to instantiate it.  Only do

6995                      // this if the provider is the same user as the caller's

6996                      // process, or can run as root (so can be in any process).

6997                      return cpr.newHolder(null);

6998                  }

                           // 成员变量 mLaunchingProviders 保存了所有正在启动的 ContentProvider 组件

7004                  // This is single process, and our app is now connecting to it.

7005                  // See if we are already in the process of launching this

7006                  // provider.

7007                  final int N = mLaunchingProviders.size();

7008                  int i;

7009                  for (i = 0; i < N; i++) {

7010                      if (mLaunchingProviders.get(i) == cpr) { // 在正在启动列表中

7011                          break;

7012                      }

7013                  }

7014 

7015                  // If the provider is not already being launched, then get it

7016                  // started.

7017                  if (i >= N) { // 不在正在启动列表中

7018                      final long origId = Binder.clearCallingIdentity();

7020                      try {

7035                          ProcessRecord proc = getProcessRecordLocked( // 获取应用程序进程信息,即目标 ContentProvider 的进程信息

7036                                  cpi.processName, cpr.appInfo.uid, false);

7037                          if (proc != null && proc.thread != null && !proc.killed) { // ContentProvider 所在进程在运行中

7040                              if (!proc.pubProviders.containsKey(cpi.name)) {

7042                                  proc.pubProviders.put(cpi.name, cpr);

7043                                  try {

7044                                      proc.thread.scheduleInstallProvider(cpi); // 调度安装 ContentProvider

7045                                  } catch (RemoteException e) {

7046                                  }

7047                              }

7048                          } else { // ContentProvider 所在进程没有启动

                                       // 创建一个新的进程来启动 ContentProvider

7050                              proc = startProcessLocked(cpi.processName,

7051                                      cpr.appInfo, false, 0,

7052                                      new HostingRecord("content provider",

7053                                      new ComponentName(cpi.applicationInfo.packageName,

7054                                              cpi.name)), false, false, false);

7056                              if (proc == null) {

7061                                  return null;

7062                              }

7063                          }

7064                          cpr.launchingApp = proc;

7065                          mLaunchingProviders.add(cpr); // 添加 ContentProvider 组件到正在启动列表中

7066                      } finally {

7067                          Binder.restoreCallingIdentity(origId);

7068                      }

7069                  }

7073                  // Make sure the provider is published (the same provider class

7074                  // may be published under multiple names).

7075                  if (firstClass) {

7076                      mProviderMap.putProviderByClass(comp, cpr); // 保存到全局变量中

7077                  }

7079                  mProviderMap.putProviderByName(name, cpr); // 保存到全局变量中

7085              }

7091          }

7092 

7093          // Wait for the provider to be published...

7094          final long timeout = SystemClock.uptimeMillis() + CONTENT_PROVIDER_WAIT_TIMEOUT;

7095          boolean timedOut = false;

7096          synchronized (cpr) {

7097              while (cpr.provider == null) {

7109                  try {

7110                      final long wait = Math.max(0L, timeout - SystemClock.uptimeMillis());

7114                      if (conn != null) {

7115                          conn.waiting = true;

7116                      }

7117                      cpr.wait(wait); // 等待 ContentProviderRecord 对象 cpr

7118                      if (cpr.provider == null) {

7119                          timedOut = true;

7120                          break;

7121                      }

7122                  } catch (InterruptedException ex) {

7123                  } finally {

7124                      if (conn != null) {

7125                          conn.waiting = false;

7126                      }

7127                  }

7128              }

7129          }

7130          if (timedOut) { // 超时了,返回 null

7146              return null;

7147          }

7149          return cpr.newHolder(conn); // 创建成功

7150      }

// 1 // 2 ContentProviderRecord 在 AMS 内部使用的,用来记录ContentProvider组件的发布(启动)信息,类型为 IContentProvider 的成员变量  provider 用来来记录ContentProvider 组件。在 ActivityManagerService 中,每一个已经启动的 ContentProvider 组件都使用一个 ContentProviderRecord 对象来描述。这些 ContentProviderRecord 对象保存在 AMS 类的成员变量 mProviderMap 中

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/services/core/java/com/android/server/am/ContentProviderRecord.java

40  final class ContentProviderRecord implements ComponentName.WithComponentName {

41      final ActivityManagerService service;

42      public final ProviderInfo info;

43      final int uid;

44      final ApplicationInfo appInfo;

45      final ComponentName name;

46      final boolean singleton;

47      public IContentProvider provider;

48      public boolean noReleaseNeeded;

49      // All attached clients

50      final ArrayList<ContentProviderConnection> connections

51              = new ArrayList<ContentProviderConnection>();

52      //final HashSet<ProcessRecord> clients = new HashSet<ProcessRecord>();

53      // Handles for non-framework processes supported by this provider

54      ArrayMap<IBinder, ExternalProcessHandle> externalProcessTokenToHandle;

55      // Count for external process for which we have no handles.

56      int externalProcessNoHandleCount;

57      ProcessRecord proc; // if non-null, hosting process.

58      ProcessRecord launchingApp; // if non-null, waiting for this app to be launched.

59      String stringName;

60      String shortStringName;

116      public boolean canRunHere(ProcessRecord app) { // 此方法被 步骤 // 2 所调用

117          return (info.multiprocess || info.processName.equals(app.processName))

118                  && uid == app.info.uid;

119      }

......

335  }

此类的 canRunHere 方法:当 uid 相同时,并且此 ContentProvider 允许在多进程中运行或者进程名称相同时,则判断为可在此进程运行。 

 

// 3 mProviderMap 实质上是一个 HashMap,可通过两种方式进行查找,查找结果是一个 ContentProviderRecord 对象 cpr :

mProviderMap.getProviderByName() 函数,通过参数 name 和参数 userId 进行查找;参数 name 指向了将要启动的 ContentProvider 组件的 android:authorities 属性值,也就是 URI 值对应的权限部分;参数 userId 则是调用方应用程序的 Linux 用户 ID;
mProviderMap.getProviderByClass() 函数,通过 ContentProvider 组件的类名进行查找;

aospxref.com/android-10.0.0_r2/xref/frameworks/base/services/core/java/com/android/server/am/ProviderMap.java

3.8 step 8

AMS 启动应用程序 B 的进程

startProcessLocked:它通过调用 Process 的静态成员函数 start() 创建一个新的应用程序进程,并且把这个新建的应用程序进程的入口设置为 ActivityThread 类的静态成员函数 main(),启动新的应用程序进程不是本文重点,故略。。。

3.9 step 9

执行应用 B 的 ActivityThread  的 main 方法

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/core/java/android/app/ActivityThread.java

7310      public static void main(String[] args) {

……

7329          Looper.prepareMainLooper(); // 1

……

7342          ActivityThread thread = new ActivityThread();

7343          thread.attach(false, startSeq); // 2

7344 

7345          if (sMainThreadHandler == null) {

7346              sMainThreadHandler = thread.getHandler();

7347          }

7348 

7349          if (false) {

7350              Looper.myLooper().setMessageLogging(new

7351                      LogPrinter(Log.DEBUG, "ActivityThread"));

7352          }

……

7356          Looper.loop(); // 3

7357 

7358          throw new RuntimeException("Main thread loop unexpectedly exited");

7359      }

// 1 // 3 Looper.prepareMainLooper() 获取了 Looper,   Looper.loop() 开启消息循环

// 2 创建 ActivityThread 对象,调用 attach 

3.10 step 10

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/core/java/android/app/ActivityThread.java

7071      private void attach(boolean system, long startSeq) {

……

7074          if (!system) {

……

7078              final IActivityManager mgr = ActivityManager.getService(); // 1

7079              try {

7080                  mgr.attachApplication(mAppThread, startSeq); // 2

7081              } catch (RemoteException ex) {

7082                  throw ex.rethrowFromSystemServer();

7083              }

……

7106          }

……

7144      }

// 1 获得 IActivityManager 对象 mgr

// 2 将 ApplicationThread 类型的 mAppThread 对象传给 attachApplication 方法,最终调用的是 AMS 的 attachApplication 方法

3.11 step 11

3.12 step 12

调用到 AMS 的 attachApplication 方法

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

5174      @Override

5175      public final void attachApplication(IApplicationThread thread, long startSeq) {

5176          synchronized (this) {

5177              int callingPid = Binder.getCallingPid();

5178              final int callingUid = Binder.getCallingUid();

5179              final long origId = Binder.clearCallingIdentity();

5180              attachApplicationLocked(thread, callingPid, callingUid, startSeq);

5181              Binder.restoreCallingIdentity(origId);

5182          }

5183      }

3.13 step 13

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

4762      private final boolean attachApplicationLocked(IApplicationThread thread,

4763              int pid, int callingUid, long startSeq) {

......

4891          try {

……

5041              if (app.isolatedEntryPoint != null) {

……

5045              } else if (instr2 != null) {

5046                  thread.bindApplication(processName, appInfo, providers,

5047                          instr2.mClass,

5048                          profilerInfo, instr2.mArguments,

5049                          instr2.mWatcher,

5050                          instr2.mUiAutomationConnection, testMode,

5051                          mBinderTransactionTrackingEnabled, enableTrackAllocation,

5052                          isRestrictedBackupMode || !normalMode, app.isPersistent(),

5053                          new Configuration(app.getWindowProcessController().getConfiguration()),

5054                          app.compat, getCommonServicesLocked(app.isolated),

5055                          mCoreSettingsObserver.getCoreSettingsLocked(),

5056                          buildSerial, autofillOptions, contentCaptureOptions);

5057              }

……

5079          } catch (Exception e) {

……

5089          }

……

5171          return true;

5172      }

thread 是 IApplicationThread 类型的,采用 AIDL 通信,是 ActivityThread 的内部类

3.14 step 14

3.15 step 15

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/core/java/android/app/ActivityThread.java

996          public final void bindApplication(String processName, ApplicationInfo appInfo,

997                  List<ProviderInfo> providers, ComponentName instrumentationName,

998                  ProfilerInfo profilerInfo, Bundle instrumentationArgs,

999                  IInstrumentationWatcher instrumentationWatcher,

1000                  IUiAutomationConnection instrumentationUiConnection, int debugMode,

1001                  boolean enableBinderTracking, boolean trackAllocation,

1002                  boolean isRestrictedBackupMode, boolean persistent, Configuration config,

1003                  CompatibilityInfo compatInfo, Map services, Bundle coreSettings,

1004                  String buildSerial, AutofillOptions autofillOptions,

1005                  ContentCaptureOptions contentCaptureOptions) {

……

1032              setCoreSettings(coreSettings);

1033 

1034              AppBindData data = new AppBindData();

1035              data.processName = processName;

1036              data.appInfo = appInfo;

1037              data.providers = providers;

1038              data.instrumentationName = instrumentationName;

1039              data.instrumentationArgs = instrumentationArgs;

……

1053              sendMessage(H.BIND_APPLICATION, data);

1054          }

3.16 step 16

3.17 step 17

3.18 step 18

最终会由 H 类对象处理消息

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/core/java/android/app/ActivityThread.java

1750      class H extends Handler {

......

1853          public void handleMessage(Message msg) {

1854              if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));

1855              switch (msg.what) {

1856                  case BIND_APPLICATION:

1857                      Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");

1858                      AppBindData data = (AppBindData)msg.obj;

1859                      handleBindApplication(data);

1860                      Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

1861                      break;

......

2031              }

......

2037          }

2038      }

最终由 ActivityThread 的内部类 H 的对象来处理

3.19 step 19

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/core/java/android/app/ActivityThread.java

6122      private void handleBindApplication(AppBindData data) {

……

6312          final InstrumentationInfo ii;

……

6343          final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); // 创建 ContextImpl

……

6366          if (ii != null) {

6367              ApplicationInfo instrApp;

……

6379              final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,

6380                      appContext.getClassLoader(), false, true, false);

6381 

6385              final ContextImpl instrContext = ContextImpl.createAppContext(this, pi,

6386                      appContext.getOpPackageName());

6387 

6388              try {

6389                  final ClassLoader cl = instrContext.getClassLoader();

6390                  mInstrumentation = (Instrumentation)

6391                      cl.loadClass(data.instrumentationName.getClassName()).newInstance(); // 1

6392              } catch (Exception e) {

……

6396              }

6397 

6398              final ComponentName component = new ComponentName(ii.packageName, ii.name);

6399              mInstrumentation.init(this, instrContext, appContext, component,

6400                      data.instrumentationWatcher, data.instrumentationUiAutomationConnection); // 2

……

6409          }

6413 

6425          Application app;

……

6428          try {

……

6431              app = data.info.makeApplication(data.restrictedBackupMode, null); // 3

……

6439              mInitialApplication = app;

……

6443              if (!data.restrictedBackupMode) {

6444                  if (!ArrayUtils.isEmpty(data.providers)) {

6445                      installContentProviders(app, data.providers); // 4 启动目标 ContentProvider

6446                  }

6447              }

……

6451              try {

6452                  mInstrumentation.onCreate(data.instrumentationArgs);

6453              }

6454              catch (Exception e) {

……

6458              }

6459              try {

6460                  mInstrumentation.callApplicationOnCreate(app); // 5

6461              } catch (Exception e) {

……

6467              }

6468          } finally {

……

6475          }

……

6497      }


// 1 // 2 通过反射创建 Instrumentation,并初始化

// 3 // 5 创建 Application,并调用 onCreate 方法, 应用程序启动

// 4  调用 installContentProviders 启动 ContentProvider

3.20 step 20

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/core/java/android/app/ActivityThread.java

6514      @UnsupportedAppUsage

6515      private void installContentProviders(

6516              Context context, List<ProviderInfo> providers) {

6517          final ArrayList<ContentProviderHolder> results = new ArrayList<>();

6518 

6519          for (ProviderInfo cpi : providers) { // 1

6520              if (DEBUG_PROVIDER) {

6521                  StringBuilder buf = new StringBuilder(128);

6522                  buf.append("Pub ");

6523                  buf.append(cpi.authority);

6524                  buf.append(": ");

6525                  buf.append(cpi.name);

6526                  Log.i(TAG, buf.toString());

6527              }

6528              ContentProviderHolder cph = installProvider(context, null, cpi,

6529                      false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/); // 2

6530              if (cph != null) {

6531                  cph.noReleaseNeeded = true;

6532                  results.add(cph);

6533              }

6534          }

6535 

6536          try {

6537              ActivityManager.getService().publishContentProviders(

6538                  getApplicationThread(), results); // 3

6539          } catch (RemoteException ex) {

6540              throw ex.rethrowFromSystemServer();

6541          }

6542      }

// 1 遍历当前应用程序 B 进程的 ProviderInfo 列表

// 2 调用 installProvider 方法安装每个 ContentProvider

// 3 为 step 24, 把安装好的 ContentProvider 发布到 AMS 中

3.21 step 21

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/core/java/android/app/ActivityThread.java

6923      private ContentProviderHolder installProvider(Context context,

6924              ContentProviderHolder holder, ProviderInfo info,

6925              boolean noisy, boolean noReleaseNeeded, boolean stable) {

6926          ContentProvider localProvider = null;

6927          IContentProvider provider;

6928          if (holder == null || holder.provider == null) { // 为空则需要启动 ContentProvider 组件

……

6933              Context c = null;

6934              ApplicationInfo ai = info.applicationInfo;

6935              if (context.getPackageName().equals(ai.packageName)) {

6936                  c = context;

6937              }

……

6963 

6964              try {

6965                  final java.lang.ClassLoader cl = c.getClassLoader();

6966                  LoadedApk packageInfo = peekPackageInfo(ai.packageName, true);

6967                  if (packageInfo == null) {

6968                      // System startup case.

6969                      packageInfo = getSystemContext().mPackageInfo;

6970                  }

6971                  localProvider = packageInfo.getAppFactory()

6972                          .instantiateProvider(cl, info.name); // 1

6973                  provider = localProvider.getIContentProvider();

6974                  if (provider == null) {

……

6978                      return null;

6979                  }

……

6983                  localProvider.attachInfo(c, info); // 2

6984              } catch (java.lang.Exception e) {

……

6990                  return null;

6991              }

6992          } else { // 不为空时,不需启动 ContentProvider, 此 ContentProvider 是从 AMS 返回来的

6993              provider = holder.provider;

……

6996          }

6997 

6998          ContentProviderHolder retHolder;

6999 

7000          synchronized (mProviderMap) {

……

7003              IBinder jBinder = provider.asBinder();

7004              if (localProvider != null) {

7005                  ComponentName cname = new ComponentName(info.packageName, info.name);

7006                  ProviderClientRecord pr = mLocalProvidersByName.get(cname);

7007                  if (pr != null) {

……

7012                      provider = pr.mProvider;

7013                  } else {

7014                      holder = new ContentProviderHolder(info);

7015                      holder.provider = provider;

7016                      holder.noReleaseNeeded = true;

7017                      pr = installProviderAuthoritiesLocked(provider, localProvider, holder);

7018                      mLocalProviders.put(jBinder, pr);

7019                      mLocalProvidersByName.put(cname, pr);

7020                  }

7021                  retHolder = pr.mHolder;

7022              } else {

7023                  ProviderRefCount prc = mProviderRefCountMap.get(jBinder);

7024                  if (prc != null) {

……

7041                  } else {

7042                      ProviderClientRecord client = installProviderAuthoritiesLocked(

7043                              provider, localProvider, holder);

7044                      if (noReleaseNeeded) {

7045                          prc = new ProviderRefCount(holder, client, 1000, 1000);

7046                      } else {

7047                          prc = stable

7048                                  ? new ProviderRefCount(holder, client, 1, 0)

7049                                  : new ProviderRefCount(holder, client, 0, 1);

7050                      }

7051                      mProviderRefCountMap.put(jBinder, prc);

7052                  }

7053                  retHolder = prc.holder;

7054              }

7055          }

7056          return retHolder;

7057      }

// 1 通过反射创建 ContentProvider 类型的 localProvider 对象

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/core/java/android/app/AppComponentFactory.java

144      public @NonNull ContentProvider instantiateProvider(@NonNull ClassLoader cl,

145              @NonNull String className)

146              throws InstantiationException, IllegalAccessException, ClassNotFoundException {

147          return (ContentProvider) cl.loadClass(className).newInstance();

148      }

// 2 调用 attachInfo 方法

3.22 step 22

3.23 step 23

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/core/java/android/content/ContentProvider.java

2069      private void attachInfo(Context context, ProviderInfo info, boolean testing) {

2070          mNoPerms = testing;

2071          mCallingPackage = new ThreadLocal<>();

2072 

2073          /*

2074           * Only allow it to be set once, so after the content service gives

2075           * this to us clients can't change it.

2076           */

2077          if (mContext == null) {

2078              mContext = context;

2079              if (context != null && mTransport != null) {

2080                  mTransport.mAppOpsManager = (AppOpsManager) context.getSystemService(

2081                          Context.APP_OPS_SERVICE);

2082              }

2083              mMyUid = Process.myUid();

2084              if (info != null) {

2085                  setReadPermission(info.readPermission); // 设置权限

2086                  setWritePermission(info.writePermission); // 设置权限

2087                  setPathPermissions(info.pathPermissions); // 设置权限

2088                  mExported = info.exported;

2089                  mSingleUser = (info.flags & ProviderInfo.FLAG_SINGLE_USER) != 0;

2090                  setAuthorities(info.authority);

2091              }

2092              ContentProvider.this.onCreate(); // 1

2093          }

2094      }

// 1 调用应用 B 中目标 XXContentProvider 的 onCreate 方法

3.24 step 24

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/core/java/android/app/ActivityThread.java

6515      private void installContentProviders(

6516              Context context, List<ProviderInfo> providers) {

……

6536          try {

6537              ActivityManager.getService().publishContentProviders(

6538                  getApplicationThread(), results); // 1

6539          } catch (RemoteException ex) {

6540              throw ex.rethrowFromSystemServer();

6541          }

6542      }

// 1 向 AMS 发布已安装的 ContentProvider

3.25 step 25

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

7335      public final void publishContentProviders(IApplicationThread caller,

7336              List<ContentProviderHolder> providers) {

7337          if (providers == null) {

7338              return;

7339          }

……

7342          synchronized (this) {

7343              final ProcessRecord r = getRecordForAppLocked(caller);

……

7354              final int N = providers.size();

7355              for (int i = 0; i < N; i++) {

7356                  ContentProviderHolder src = providers.get(i);

……

7360                  ContentProviderRecord dst = r.pubProviders.get(src.info.name);

……

7362                  if (dst != null) {

7363                      ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);

7364                      mProviderMap.putProviderByClass(comp, dst);

7365                      String names[] = dst.info.authority.split(";");

7366                      for (int j = 0; j < names.length; j++) {

7367                          mProviderMap.putProviderByName(names[j], dst); // 放入到 mProviderMap 中

7368                      }

7369 

7370                      int launchingCount = mLaunchingProviders.size();

7371                      int j;

7372                      boolean wasInLaunchingProviders = false;

7373                      for (j = 0; j < launchingCount; j++) {

7374                          if (mLaunchingProviders.get(j) == dst) {

7375                              mLaunchingProviders.remove(j); // 从 mLaunchingProviders 删除

7376                              wasInLaunchingProviders = true;

7377                              j--;

7378                              launchingCount--;

7379                          }

7380                      }

……

7391                      synchronized (dst) {

7392                          dst.provider = src.provider; // 1

7393                          dst.setProcess(r); // 1

7394                          dst.notifyAll(); // 2

7395                      }

……

7399                  }

7400              }

……

7403          }

7404      }

// 1 把 ContentProvider 存储在 ContentProviderRecord 对象中,之后保存到全局变量 mProviderMap 中

// 2 把等待这个 ContentProvider 的地方唤醒, 即 step 7 中的 getContentProviderImpl

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

6706      private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,

6707              String name, IBinder token, int callingUid, String callingPackage, String callingTag,

6708              boolean stable, int userId) {

……

7096          synchronized (cpr) {

7097              while (cpr.provider == null) {

……

7109                  try {

……

7117                      cpr.wait(wait);

……

7122                  } catch (InterruptedException ex) {

7123                  } finally {

……

7127                  }

7128              }

7129          }

……

7150      }

3.26 step 26

应用程序 A 等待的 ContentProviderHolder 终于返回了,执行的是 installProvider 方法, 在 step 21 中提及过

http://aospxref.com/android-10.0.0_r2/xref/frameworks/base/core/java/android/app/ActivityThread.java

6923      private ContentProviderHolder installProvider(Context context,

6924              ContentProviderHolder holder, ProviderInfo info,

6925              boolean noisy, boolean noReleaseNeeded, boolean stable) {

6926          ContentProvider localProvider = null;

6927          IContentProvider provider;

6928          if (holder == null || holder.provider == null) { // 应用程序 B 执行的流程

…… 

6992          } else { // 应用程序 A 执行的流程

6993              provider = holder.provider;

……

6996          }

6997 

6998          ContentProviderHolder retHolder;

6999 

7000          synchronized (mProviderMap) {

……

 

7003              IBinder jBinder = provider.asBinder();

7004              if (localProvider != null) {

7005                  ComponentName cname = new ComponentName(info.packageName, info.name);

7006                  ProviderClientRecord pr = mLocalProvidersByName.get(cname);

7007                  if (pr != null) {

……

7013                  } else {

7014                      holder = new ContentProviderHolder(info);

7015                      holder.provider = provider;

7016                      holder.noReleaseNeeded = true;

7017                      pr = installProviderAuthoritiesLocked(provider, localProvider, holder);

7018                      mLocalProviders.put(jBinder, pr); // 缓存到本地

7019                      mLocalProvidersByName.put(cname, pr); // 缓存到本地

7020                  }

7021                  retHolder = pr.mHolder;

7022              }

……

7055          }

7056          return retHolder;

7057      }

3.27 step 27

应用程序 A 拿到应用程序 B 目标 ContentProvider 的 IContentProvider 对象,调用 IContentProvider 对象的 query 方法进行查询,并给应用程序 A 返回结果 Cursor 对象

4.参考文档:

  1. 《Android 进阶解密》  作者:刘望舒
  2. https://www.jianshu.com/p/74014e1b18b0  作者:umbrella1
  3. https://www.jianshu.com/p/b23e47cbe581  作者:wondertwo1
  4. https://www.jianshu.com/p/7455bc417362  作者:wondertwo1
  5. https://www.jianshu.com/p/e58a9a25673f  作者:wondertwo1