前言
Android系统应用开发与四大组件之间交互最多了,而四大组件都是通过ActivityManagerService管理,而Activity是Android系统实现各种各样的载体。本文从ActivityManagerService初始化开始,来分析ActivityManager这个服务是怎么启动的。Android中很多系统级别的服务是在framework中的systemServer中负责启动的。
AMS启动我们可以分为以下几个部分:
1、 创建系统上下文Context
2、 实例化AMS
3、 setSystemProcess
4、 安装System级别的ContentProvider
5、 AMS系统准备完成之后systemReady
一、创建系统上下文Context
这边为什么要创建Context,本人觉得是因为AMS中不仅仅是一个服务,而且在服务中是要加载framework-res.apk和ContentProvider.apk这两个APK,而我们知道应用开发中一个应用会有一个Context与之关联,所以AMS中也需要创建Context来加载APK。
进入SystemServer中run中看下
private void run() { try { 。。。。。。。。。 // Initialize the system context. /* *创建系统上下文 */ createSystemContext(); // Create the system service manager. mSystemServiceManager = new SystemServiceManager(mSystemContext); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); } finally { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } // Start services. try { Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices"); startBootstrapServices();//后面会介绍 startCoreServices(); startOtherServices();//后面会介绍 } catch (Throwable ex) { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting system services", ex); throw ex; } finally { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } // Loop forever. Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
我们进入createSystemContext代码如下:
private void createSystemContext() { ActivityThread activityThread = ActivityThread.systemMain(); mSystemContext = activityThread.getSystemContext(); mSystemContext.setTheme(DEFAULT_SYSTEM_THEME); }
这函数里面比较简单创建ActivityThread主线程,然后从ActivityThread中获取context,最后设置主题,我们进入ActivityThread.systemMain看下做了什么。代码如下:
public static ActivityThread systemMain() { // The system process on low-memory devices do not get to use hardware // accelerated drawing, since this can add too much overhead to the // process. if (!ActivityManager.isHighEndGfx()) { ThreadedRenderer.disable(true); } else { ThreadedRenderer.enableForegroundTrimming(); } /* *创建ActivityThread实例,这个表示的是系统主线程 */ ActivityThread thread = new ActivityThread(); /*注意此时传入的参数为true,*/ thread.attach(true); return thread; }
接着看下ActivityThread中的attach中做了什么。代码如下:
private void attach(boolean system) { /*保存在自己的单例变量当中*/ sCurrentActivityThread = this; /*这个只在systemServer中为true,如果是其它应用中为false*/ mSystemThread = system; if (!system) { //这个流程在ActivityManagerService启动Activity中会涉及到这儿就 //不分析了 。。。。。。。 } else { // Don't set application object here -- if the system crashes, // we can't display an alert, we just want to die die die. android.ddm.DdmHandleAppName.setAppName("system_process", UserHandle.myUserId()); try { /*创建出Instrumenttation*/ mInstrumentation = new Instrumentation(); /*这个我们先看参数中调用的getSystemContext() */ ContextImpl context = ContextImpl.createAppContext( this, getSystemContext().mPackageInfo/*这个即是getSystemContext中创建的LoadedApk*/ ); /*创建Application*/ mInitialApplication = context.mPackageInfo.makeApplication(true, null); mInitialApplication.onCreate(); } catch (Exception e) { throw new RuntimeException( "Unable to instantiate Application():" + e.toString(), e); } } // add dropbox logging to libcore DropBox.setReporter(new DropBoxReporter()); ViewRootImpl.addConfigCallback(new ComponentCallbacks2() { @Override public void onConfigurationChanged(Configuration newConfig) { synchronized (mResourcesManager) { // We need to apply this change to the resources // immediately, because upon returning the view // hierarchy will be informed about it. if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) { updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(), mResourcesManager.getConfiguration().getLocales()); // This actually changed the resources! Tell // everyone about it. if (mPendingConfiguration == null || mPendingConfiguration.isOtherSeqNewer(newConfig)) { mPendingConfiguration = newConfig; sendMessage(H.CONFIGURATION_CHANGED, newConfig); } } } } @Override public void onLowMemory() { } @Override public void onTrimMemory(int level) { } }); }
我们看看getSystemContext 这创建了什么,代码如下:
public ContextImpl getSystemContext() { synchronized (this) { if (mSystemContext == null) { mSystemContext = ContextImpl.createSystemContext(this); } return mSystemContext; } }
进入ContextImpl的createSystemContext代码如下:
static ContextImpl createSystemContext(ActivityThread mainThread) { /*创建出了LoadedAPk *这个是加载APK相关资源的类,为什么systemServer也要加载这个? *这是因为systemServer进程中也有加载初始化一些APK,比如framework-res.apk、SettingsProvider.apk *看下构造函数 */ LoadedApk packageInfo = new LoadedApk(mainThread); ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY); context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(), context.mResourcesManager.getDisplayMetrics()); return context; }
我们看下LoadApk的构造函数,代码如下:
LoadedApk(ActivityThread activityThread) { mActivityThread = activityThread; /* *注意这时候描述 应用中ApplicationInfo还没有具体指定给 *哪个应用,这边只是先指定下包名,它会在AMS中的setSystemProcess函数 *中把包名为android(即frameworkd-res.apk)赋值给它 */ mApplicationInfo = new ApplicationInfo(); mApplicationInfo.packageName = "android"; mPackageName = "android"; mAppDir = null; mResDir = null; mSplitAppDirs = null; mSplitResDirs = null; mOverlayDirs = null; mSharedLibraries = null; mDataDir = null; mDataDirFile = null; mDeviceProtectedDataDirFile = null; mCredentialProtectedDataDirFile = null; mLibDir = null; mBaseClassLoader = null; mSecurityViolation = false; mIncludeCode = true; mRegisterPackage = false; mClassLoader = ClassLoader.getSystemClassLoader(); mResources = Resources.getSystem(); }
我们总结下创建系统上下文,系统做了什么?我们分别创建了Instrument、Application、LoadedApk、Context,这些是对于一个应用APK是必须的类,这也为AMS启动中下面加载framework-res.apk和ContentProvider.apk做好了准备。
二、实例化AMS
前面第一步创建出了AMS中需要用到的Instrument、Application、LoadedApk、Context,接着我们继续看下AMS中如何进行实例化。这时候接着SystemServer中的run函数,进入startBootstrapServices,代码如下:
private void startBootstrapServices() { // Wait for installd to finish starting up so that it has a chance to // create critical directories such as /data/user with the appropriate // permissions. We need this to complete before we initialize other services. Installer installer = mSystemServiceManager.startService(Installer.class); // Activity manager runs the show. /* *这儿创建AMS的实例,创建完之后调用AMS中的start函数 *这儿只是创建AMS实例,他还没有向ServiceManager中注册 */ mActivityManagerService = mSystemServiceManager.startService( ActivityManagerService.Lifecycle.class).getService(); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); 。。。。。。。 mActivityManagerService.initPowerManagement(); 。。。。。。。 mPackageManagerService = PackageManagerService.main(mSystemContext, installer, 。。。。。。。。 // Set up the Application instance for the system process and get started. /* *这儿把相关的一些服务注册到ServiceManager中,包括AMS自己 *并且还为包名为android的framework-res.apk创建了描述进程信息的 *ProcessRecord */ mActivityManagerService.setSystemProcess(); }
我们分别看下AMS中的构造函数和start()函数。
public ActivityManagerService(Context systemContext) { /*mContext、mSystemThread即为在systemServer中createSystemContext *创建的*/ mContext = systemContext; mFactoryTest = FactoryTest.getMode(); mSystemThread = ActivityThread.currentActivityThread(); Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); mHandlerThread = new ServiceThread(TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); mHandlerThread.start(); mHandler = new MainHandler(mHandlerThread.getLooper()); mUiHandler = new UiHandler(); /* static; one-time init here */ if (sKillHandler == null) { sKillThread = new ServiceThread(TAG + ":kill", android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */); sKillThread.start(); sKillHandler = new KillHandler(sKillThread.getLooper()); } mFgBroadcastQueue = new BroadcastQueue(this, mHandler, "foreground", BROADCAST_FG_TIMEOUT, false); mBgBroadcastQueue = new BroadcastQueue(this, mHandler, "background", BROADCAST_BG_TIMEOUT, true); mBroadcastQueues[0] = mFgBroadcastQueue; mBroadcastQueues[1] = mBgBroadcastQueue; mServices = new ActiveServices(this); mProviderMap = new ProviderMap(this); mAppErrors = new AppErrors(mContext, this); // TODO: Move creation of battery stats service outside of activity manager service. /*创建目录/data/system/ */ File dataDir = Environment.getDataDirectory(); File systemDir = new File(dataDir, "system"); systemDir.mkdirs(); mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); mBatteryStatsService.getActiveStatistics().readLocked(); mBatteryStatsService.scheduleWriteToDisk(); mOnBattery = DEBUG_POWER ? true : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); mBatteryStatsService.getActiveStatistics().setCallback(this); mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null, new IAppOpsCallback.Stub() { @Override public void opChanged(int op, int uid, String packageName) { if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) { if (mAppOpsService.checkOperation(op, uid, packageName) != AppOpsManager.MODE_ALLOWED) { runInBackgroundDisabled(uid); } } } }); mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); mUserController = new UserController(this); GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", ConfigurationInfo.GL_ES_VERSION_UNDEFINED); if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) { mUseFifoUiScheduling = true; } mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations")); mConfiguration.setToDefaults(); mConfiguration.setLocales(LocaleList.getDefault()); mConfigurationSeq = mConfiguration.seq = 1; mProcessCpuTracker.init(); mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); /*mStackSupervisor、mActivityStarter这两个是在启动activity中会使用到 */ mStackSupervisor = new ActivityStackSupervisor(this); mActivityStarter = new ActivityStarter(this, mStackSupervisor); mRecentTasks = new RecentTasks(this, mStackSupervisor); mProcessCpuThread = new Thread("CpuTracker") { @Override public void run() { while (true) { try { try { synchronized(this) { final long now = SystemClock.uptimeMillis(); long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; //Slog.i(TAG, "Cpu delay=" + nextCpuDelay // + ", write delay=" + nextWriteDelay); if (nextWriteDelay < nextCpuDelay) { nextCpuDelay = nextWriteDelay; } if (nextCpuDelay > 0) { mProcessCpuMutexFree.set(true); this.wait(nextCpuDelay); } } } catch (InterruptedException e) { } updateCpuStatsNow(); } catch (Exception e) { Slog.e(TAG, "Unexpected exception collecting process stats", e); } } } }; Watchdog.getInstance().addMonitor(this); Watchdog.getInstance().addThread(mHandler); }
这里面创建了一堆类的实例,具体的不作分析,读者可以看下。接着看下start函数,代码如下:
private void start() { Process.removeAllProcessGroups(); /**启动cpus使用线程*/ mProcessCpuThread.start(); /**向ServiceManager注册服务*/ mBatteryStatsService.publish(mContext); mAppOpsService.publish(mContext); Slog.d("AppOps", "AppOpsService published"); LocalServices.addService(ActivityManagerInternal.class, new LocalService()); }
三、setSystemProcess
这边我们先看下包名为android应用的AndroidManifest.xml,路径在frameworks\base\core\res\ AndroidManifest.xml。图一中红色框框的注意一下,下面会讲解到。
图一
我们接着startBootstrapServices中调用AMS中的setSystemProcess,代码如下:
public void setSystemProcess() { try { /*向ServiceManager注射服务包括AMS自己*/ ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); ServiceManager.addService("meminfo", new MemBinder(this)); ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); ServiceManager.addService("dbinfo", new DbBinder(this)); if (MONITOR_CPU_USAGE) { ServiceManager.addService("cpuinfo", new CpuBinder(this)); } ServiceManager.addService("permission", new PermissionController(this)); ServiceManager.addService("processinfo", new ProcessInfoService(this)); /*通过PackageManagerService查询包名为android的应用(即为framework-res.apk) *列下AndroidManifest.xml */ ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( "android", STOCK_PM_FLAGS | PackageManager.MATCH_SYSTEM_ONLY); /*这边把包名为andorid的应用的ApplicationInfo赋值给了在创建系统上下文 *创建的LoadedApk中 */ mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); synchronized (this) { /*为framework-res.apk创建描述进程的ProcessRecord *processName对应AndroidManifest.xml中的android:process *framework-res.apk中android:process="system"*/ ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); app.persistent = true; app.pid = MY_PID; app.maxAdj = ProcessList.SYSTEM_ADJ; /*进程绑定ActivityThread*/ app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); synchronized (mPidsSelfLocked) { /*描述framework-res.apk进程的ProcessRecord *保存到mPidsSelfLocked, */ mPidsSelfLocked.put(app.pid, app); } updateLruProcessLocked(app, false, null); updateOomAdjLocked(); } } catch (PackageManager.NameNotFoundException e) { throw new RuntimeException( "Unable to find android system package", e); } }
我们跟进ActivityThread中的installSystemApplicationInfo看下这里面做什么操作,代码如下:
public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) { synchronized (this) { /*进入ContextImpl这个在第一步创建系统上下文中创建*/ getSystemContext().installSystemApplicationInfo(info, classLoader); // give ourselves a default profiler mProfiler = new Profiler(); } }
继续进入LoadedApk中的installSystemApplicationInfo,代码如下:
/** * Sets application info about the system package. */ void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) { assert info.packageName.equals("android"); mApplicationInfo = info; mClassLoader = classLoader; }
接着我们继续分析setSystemProcess还未分析的newProcessRecordLocked,代码如下:
final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, boolean isolated, int isolatedUid) { String proc = customProcess != null ? customProcess : info.processName; BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); final int userId = UserHandle.getUserId(info.uid); int uid = info.uid; if (isolated) { if (isolatedUid == 0) { int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; while (true) { if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; } uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); mNextIsolatedProcessUid++; if (mIsolatedProcesses.indexOfKey(uid) < 0) { // No process for this uid, use it. break; } stepsLeft--; if (stepsLeft <= 0) { return null; } } } else { // Special case for startIsolatedProcess (internal only), where // the uid of the isolated process is specified by the caller. uid = isolatedUid; } // Register the isolated UID with this application so BatteryStats knows to // attribute resource usage to the application. // // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats // about the process state of the isolated UID *before* it is registered with the // owning application. mBatteryStatsService.addIsolatedUid(uid, info.uid); } /*为framewor-res.apk创建ProcessRecord信息*/ final ProcessRecord r = new ProcessRecord(stats, info, proc, uid); if (!mBooted && !mBooting && userId == UserHandle.USER_SYSTEM && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) { r.persistent = true; } /* *把表示framewok-res.apk的ProcessRecord以processName为关键字记录在mProcessNames */ addProcessNameLocked(r); return r; }
到这儿setSystemProcess分析完了,他向ServiceManager注册了一些服务,然后是把包名
为android的framework-res.apk的Applicationinfo赋值给第一步创建系统上下文创建的LoadApk中,并且为
该应用创建描述它的进程的ProcessRecord。
四、安装System级别的ContentProvider
进行这部分之前我们先看下SettingsProvider中的AndroidManifest.xml,请看图二,注意红框标的。
图二
这一部分是在SystemServer中的startOtherServices完成,代码如下:
/** * Starts a miscellaneous grab bag of stuff that has yet to be refactored * and organized. */ private void startOtherServices() { 。。。。。。。 try { 。。。。。。。。 /**这儿是安装进程为system(即Androidmanifest.xml中*android:process="system")的ContentProvider */ mActivityManagerService.installSystemProviders(); 。。。。。。。。 /*设置WindowManagerService*/ mActivityManagerService.setWindowManager(wm); // We now tell the activity manager it is okay to run third party // code. It will call back into us once it has gotten to the state // where third party code can really run (but before it has actually // started launching the initial applications), for us to complete our // initialization. /*AMS启动正常之后的操作*/ mActivityManagerService.systemReady(new Runnable() { @Override public void run() { Slog.i(TAG, "Making services ready"); mSystemServiceManager.startBootPhase( SystemService.PHASE_ACTIVITY_MANAGER_READY); 。。。。。。。。 try { mActivityManagerService.startObservingNativeCrashes(); } catch (Throwable e) { reportWtf("observing native crashes", e); } 。。。。。。。。 try { /*启动SystemUi*/ startSystemUi(context); } catch (Throwable e) { reportWtf("starting System UI", e); } 。。。。。。。 } }); }
我们进入AMS中看下installSystemProviders,代码如下:
public final void installSystemProviders() { List<ProviderInfo> providers; synchronized (this) { /**我们之前一步setSystemProcess中知道了创建framework-res.apk进程的processName为system *并且保存到mProcessNames *所以此时这边查看的ProcessRecord不为空,且即为framework-res所处进程 * */ ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); /*这边是查询出所有和framework-res.apk有相同进程的APK,即Androidmanifest.xml中有设置 *android:process="system"的应用,比如像SettingsProvider(列下Androidmanifext.xml */ providers = generateApplicationProvidersLocked(app); if (providers != null) { for (int i=providers.size()-1; i>=0; i--) { ProviderInfo pi = (ProviderInfo)providers.get(i); /**过滤掉不是system的Provider*/ if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { Slog.w(TAG, "Not installing system proc provider " + pi.name + ": not system .apk"); providers.remove(i); } } } } if (providers != null) { /*调用ActivityThread */ mSystemThread.installSystemProviders(providers); } mCoreSettingsObserver = new CoreSettingsObserver(this); mFontScaleSettingObserver = new FontScaleSettingObserver(); //mUsageStatsService.monitorPackages(); }
我们进入generateApplicationProvidersLocked看下,代码:
private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { List<ProviderInfo> providers = null; try { providers = AppGlobals.getPackageManager() .queryContentProviders(app.processName, app.uid, STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS | PackageManager.MATCH_DEBUG_TRIAGED_MISSING) .getList(); } catch (RemoteException ex) { } if (DEBUG_MU) Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); int userId = app.userId; if (providers != null) { int N = providers.size(); app.pubProviders.ensureCapacity(N + app.pubProviders.size()); for (int i=0; i<N; i++) { // TODO: keep logic in sync with installEncryptionUnawareProviders ProviderInfo cpi = (ProviderInfo)providers.get(i); boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, cpi.name, cpi.flags); if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) { // This is a singleton provider, but a user besides the // default user is asking to initialize a process it runs // in... well, no, it doesn't actually run in this process, // it runs in the process of the default user. Get rid of it. providers.remove(i); N--; i--; continue; } ComponentName comp = new ComponentName(cpi.packageName, cpi.name); ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); if (cpr == null) { cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); mProviderMap.putProviderByClass(comp, cpr); } if (DEBUG_MU) Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); /**查询出来的ContentProvider暂时先记录在pubProviders中 *这时只是记录查询出的ContentProvider,并还没有进行实例化,AMS还不能够使用,实例化在ActivityThread, *实例化完之后ActivityThread会调用AMS中publishContentProvider把实例化的ContentProvider中的进程通信 *ContentProvider中的IContentProvider赋值之后才正式可以使用 */ app.pubProviders.put(cpi.name, cpr); if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { // Don't add this if it is a platform component that is marked // to run in multiple processes, because this is actually // part of the framework so doesn't make sense to track as a // separate apk in the process. app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, mProcessStats); } notifyPackageUse(cpi.applicationInfo.packageName, PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER); } } return providers; }
这一步查询系统中android:processName=”system”的ContentProvider。接着进入
ActivityThread的installSystemProviders,代码如下:
public final void installSystemProviders(List<ProviderInfo> providers) { if (providers != null) { /*mInitialApplication即为第一步创建系统上下文时候创建的*/ installContentProviders(mInitialApplication, providers); } }
进入installContentProviders,代码如下:
private void installContentProviders( Context context, List<ProviderInfo> providers) { final ArrayList<IActivityManager.ContentProviderHolder> results = new ArrayList<IActivityManager.ContentProviderHolder>(); for (ProviderInfo cpi : providers) { if (DEBUG_PROVIDER) { StringBuilder buf = new StringBuilder(128); buf.append("Pub "); buf.append(cpi.authority); buf.append(": "); buf.append(cpi.name); Log.i(TAG, buf.toString()); } /**这边开始初始化Provider *这这还只是实例化ContentProvider,在AMS并还没有有注册*/ IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi, false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/); if (cph != null) { cph.noReleaseNeeded = true; results.add(cph); } } try { /*调用AMS注册ContentProvider*/ ActivityManagerNative.getDefault().publishContentProviders( getApplicationThread(), results); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } }
进入installProvider,代码如下:
/** * Installs the provider. * * Providers that are local to the process or that come from the system server * may be installed permanently which is indicated by setting noReleaseNeeded to true. * Other remote providers are reference counted. The initial reference count * for all reference counted providers is one. Providers that are not reference * counted do not have a reference count (at all). * * This method detects when a provider has already been installed. When this happens, * it increments the reference count of the existing provider (if appropriate) * and returns the existing provider. This can happen due to concurrent * attempts to acquire the same provider. */ private IActivityManager.ContentProviderHolder installProvider(Context context, IActivityManager.ContentProviderHolder holder, ProviderInfo info, boolean noisy, boolean noReleaseNeeded, boolean stable) { ContentProvider localProvider = null; IContentProvider provider; if (holder == null || holder.provider == null) { if (DEBUG_PROVIDER || noisy) { Slog.d(TAG, "Loading provider " + info.authority + ": " + info.name); } Context c = null; ApplicationInfo ai = info.applicationInfo; /**这时候context.getPackageName值为android *在attach中指定的,大伙可以回头看下 */ if (context.getPackageName().equals(ai.packageName)) { c = context; } else if (mInitialApplication != null && mInitialApplication.getPackageName().equals(ai.packageName)) { c = mInitialApplication; } else { try { /**对于其它包名不是为android的ContextProvider进程这个分支 */ c = context.createPackageContext(ai.packageName, Context.CONTEXT_INCLUDE_CODE); } catch (PackageManager.NameNotFoundException e) { // Ignore } } if (c == null) { Slog.w(TAG, "Unable to get context for package " + ai.packageName + " while loading content provider " + info.name); return null; } try { final java.lang.ClassLoader cl = c.getClassLoader(); /**这边就正式开始实例化ContentProvider*/ localProvider = (ContentProvider)cl. loadClass(info.name).newInstance(); provider = localProvider.getIContentProvider(); if (provider == null) { Slog.e(TAG, "Failed to instantiate class " + info.name + " from sourceDir " + info.applicationInfo.sourceDir); return null; } if (DEBUG_PROVIDER) Slog.v( TAG, "Instantiating local provider " + info.name); // XXX Need to create the correct context for this provider. /*为创建ContentProvider赋值context*/ localProvider.attachInfo(c, info); } catch (java.lang.Exception e) { if (!mInstrumentation.onException(null, e)) { throw new RuntimeException( "Unable to get provider " + info.name + ": " + e.toString(), e); } return null; } } else { provider = holder.provider; if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": " + info.name); } IActivityManager.ContentProviderHolder retHolder; synchronized (mProviderMap) { if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider + " / " + info.name); IBinder jBinder = provider.asBinder(); if (localProvider != null) { ComponentName cname = new ComponentName(info.packageName, info.name); ProviderClientRecord pr = mLocalProvidersByName.get(cname); if (pr != null) { if (DEBUG_PROVIDER) { Slog.v(TAG, "installProvider: lost the race, " + "using existing local provider"); } provider = pr.mProvider; } else { holder = new IActivityManager.ContentProviderHolder(info); holder.provider = provider; holder.noReleaseNeeded = true; pr = installProviderAuthoritiesLocked(provider, localProvider, holder); mLocalProviders.put(jBinder, pr); mLocalProvidersByName.put(cname, pr); } retHolder = pr.mHolder; } else { ProviderRefCount prc = mProviderRefCountMap.get(jBinder); if (prc != null) { if (DEBUG_PROVIDER) { Slog.v(TAG, "installProvider: lost the race, updating ref count"); } // We need to transfer our new reference to the existing // ref count, releasing the old one... but only if // release is needed (that is, it is not running in the // system process). if (!noReleaseNeeded) { incProviderRefLocked(prc, stable); try { ActivityManagerNative.getDefault().removeContentProvider( holder.connection, stable); } catch (RemoteException e) { //do nothing content provider object is dead any way } } } else { ProviderClientRecord client = installProviderAuthoritiesLocked( provider, localProvider, holder); if (noReleaseNeeded) { prc = new ProviderRefCount(holder, client, 1000, 1000); } else { prc = stable ? new ProviderRefCount(holder, client, 1, 0) : new ProviderRefCount(holder, client, 0, 1); } mProviderRefCountMap.put(jBinder, prc); } retHolder = prc.holder; } } return retHolder; }
installContentProviders最后会进入AMS中的publishContentProviders注册实例化的ContentProvider,代码如下:
public final void publishContentProviders(IApplicationThread caller, List<ContentProviderHolder> providers) { if (providers == null) { return; } enforceNotIsolatedCaller("publishContentProviders"); synchronized (this) { final ProcessRecord r = getRecordForAppLocked(caller); if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); if (r == null) { throw new SecurityException( "Unable to find app for caller " + caller + " (pid=" + Binder.getCallingPid() + ") when publishing content providers"); } final long origId = Binder.clearCallingIdentity(); final int N = providers.size(); for (int i = 0; i < N; i++) { ContentProviderHolder src = providers.get(i); if (src == null || src.info == null || src.provider == null) { continue; } ContentProviderRecord dst = r.pubProviders.get(src.info.name); if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); if (dst != null) { ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); mProviderMap.putProviderByClass(comp, dst); String names[] = dst.info.authority.split(";"); /* *以Androidmanifest.xml中定义的android:authorities进行保存 */ for (int j = 0; j < names.length; j++) { mProviderMap.putProviderByName(names[j], dst); } int launchingCount = mLaunchingProviders.size(); int j; boolean wasInLaunchingProviders = false; for (j = 0; j < launchingCount; j++) { if (mLaunchingProviders.get(j) == dst) { mLaunchingProviders.remove(j); wasInLaunchingProviders = true; j--; launchingCount--; } } if (wasInLaunchingProviders) { mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r); } synchronized (dst) { /**在这儿正式保存到AMS当中*/ dst.provider = src.provider; dst.proc = r; dst.notifyAll(); } updateOomAdjLocked(r); maybeUpdateProviderUsageStatsLocked(r, src.info.packageName, src.info.authority); } } Binder.restoreCallingIdentity(origId); } }
在这儿ContentProvider正式实例完成,并且在AMS也正式注册了,应用中就可以通过AMS正式访问该Provider了。
五、 AMS系统准备完成之后systemReady
我们继续SystemServer中startOtherServices 中的函数看下systemReady。systemReady它会启动launcher,
在callback中会启动systemUI,我们先进入AMS中的systemReady看下,代码如下:
public void systemReady(final Runnable goingCallback) { synchronized(this) { if (mSystemReady) { // If we're done calling all the receivers, run the next "boot phase" passed in // by the SystemServer if (goingCallback != null) { goingCallback.run(); } return; } mLocalDeviceIdleController = LocalServices.getService(DeviceIdleController.LocalService.class); // Make sure we have the current profile info, since it is needed for security checks. mUserController.onSystemReady(); mRecentTasks.onSystemReadyLocked(); mAppOpsService.systemReady(); mSystemReady = true; } ArrayList<ProcessRecord> procsToKill = null; synchronized(mPidsSelfLocked) { for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { ProcessRecord proc = mPidsSelfLocked.valueAt(i); if (!isAllowedWhileBooting(proc.info)){ if (procsToKill == null) { procsToKill = new ArrayList<ProcessRecord>(); } procsToKill.add(proc); } } } synchronized(this) { if (procsToKill != null) { for (int i=procsToKill.size()-1; i>=0; i--) { ProcessRecord proc = procsToKill.get(i); Slog.i(TAG, "Removing system update proc: " + proc); removeProcessLocked(proc, true, false, "system update done"); } } // Now that we have cleaned up any update processes, we // are ready to start launching real processes and know that // we won't trample on them any more. mProcessesReady = true; } Slog.i(TAG, "System now ready"); EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, SystemClock.uptimeMillis()); synchronized(this) { // Make sure we have no pre-ready processes sitting around. if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 。。。。。。。。 } } retrieveSettings(); final int currentUserId; synchronized (this) { currentUserId = mUserController.getCurrentUserIdLocked(); readGrantedUriPermissionsLocked(); } if (goingCallback != null) goingCallback.run(); mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, Integer.toString(currentUserId), currentUserId); mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, Integer.toString(currentUserId), currentUserId); mSystemServiceManager.startUser(currentUserId); synchronized (this) { // Only start up encryption-aware persistent apps; once user is // unlocked we'll come back around and start unaware apps startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE); // Start up initial activity. mBooting = true; // Enable home activity for system user, so that the system can always boot if (UserManager.isSplitSystemUser()) { ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class); try { AppGlobals.getPackageManager().setComponentEnabledSetting(cName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0, UserHandle.USER_SYSTEM); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } } /*启动Launcher*/ startHomeActivityLocked(currentUserId, "systemReady"); try { if (AppGlobals.getPackageManager().hasSystemUidErrors()) { Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" + " data partition or your device will be unstable."); mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget(); } } catch (RemoteException e) { } if (!Build.isBuildConsistent()) { Slog.e(TAG, "Build fingerprint is not consistent, warning user"); mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget(); } long ident = Binder.clearCallingIdentity(); try { Intent intent = new Intent(Intent.ACTION_USER_STARTED); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId); broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID, currentUserId); intent = new Intent(Intent.ACTION_USER_STARTING); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId); broadcastIntentLocked(null, null, intent, null, new IIntentReceiver.Stub() { @Override public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) throws RemoteException { } }, 0, null, null, new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE, null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); } catch (Throwable t) { Slog.wtf(TAG, "Failed sending first user broadcasts", t); } finally { Binder.restoreCallingIdentity(ident); } /*准备开始显示Launcher*/ mStackSupervisor.resumeFocusedStackTopActivityLocked(); mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId); } }
到此AMS启动流程就分析完毕了,有错误的地方请指出。