AMS-启动AMS(AMS在SystemServer中的调用轨迹)

SystemServer#run()

private void run() {
        // If a device's clock is before 1970 (before 0), a lot of
        // APIs crash dealing with negative numbers, notably
        // java.io.File#setLastModified, so instead we fake it and
        // hope that time from cell towers or NTP fixes it shortly.
        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
            Slog.w(TAG, "System clock is before 1970; setting to 1970.");
            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
        }

        // If the system has "persist.sys.language" and friends set, replace them with
        // "persist.sys.locale". Note that the default locale at this point is calculated
        // using the "-Duser.locale" command line flag. That flag is usually populated by
        // AndroidRuntime using the same set of system properties, but only the system_server
        // and system apps are allowed to set them.
        //
        // NOTE: Most changes made here will need an equivalent change to
        // core/jni/AndroidRuntime.cpp
        if (!SystemProperties.get("persist.sys.language").isEmpty()) {
            final String languageTag = Locale.getDefault().toLanguageTag();

            SystemProperties.set("persist.sys.locale", languageTag);
            SystemProperties.set("persist.sys.language", "");
            SystemProperties.set("persist.sys.country", "");
            SystemProperties.set("persist.sys.localevar", "");
        }

        // Here we go!
        Slog.i(TAG, "Entered the Android system server!");
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());

        // In case the runtime switched since last boot (such as when
        // the old runtime was removed in an OTA), set the system
        // property so that it is in sync. We can't do this in
        // libnativehelper's JniInvocation::Init code where we already
        // had to fallback to a different runtime because it is
        // running as root and we need to be the system user to set
        // the property. http://b/11463182
        SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

        // Enable the sampling profiler.
        if (SamplingProfilerIntegration.isEnabled()) {
            SamplingProfilerIntegration.start();
            mProfilerSnapshotTimer = new Timer();
            mProfilerSnapshotTimer.schedule(new TimerTask() {
                @Override
                public void run() {
                    SamplingProfilerIntegration.writeSnapshot("system_server", null);
                }
            }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
        }

        // Mmmmmm... more memory!
        VMRuntime.getRuntime().clearGrowthLimit();

        // The system server has to run all of the time, so it needs to be
        // as efficient as possible with its memory usage.
        VMRuntime.getRuntime().setActvityManagerService.LifecycleTargetHeapUtilization(0.8f);

        // Some devices rely on runtime fingerprint generation, so make sure
        // we've defined it before booting further.
        Build.ensureFingerprintProperty();

        // Within the system server, it is an error to access Environment paths without
        // explicitly specifying a user.
        Environment.setUserRequired(true);

        // Ensure binder calls into the system always run at foreground priority.
        BinderInternal.disableBackgroundScheduling(true);

        // Prepare the main looper thread (this thread).
        android.os.Process.setThreadPriority(
                android.os.Process.THREAD_PRIORITY_FOREGROUND);
        android.os.Process.setCanSelfBackground(false);
        Looper.prepareMainLooper();

        // Initialize native services.
        System.loadLibrary("android_servers");

        // Check whether we failed to shut down last time we tried.
        // This call may not return.
        performPendingShutdown();

        // Initialize the system context.
        createSystemContext();//重点分析1

        // Create the system service manager.
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

        // Start services.
        try {
            startBootstrapServices();//重点分析2
            startCoreServices();
            startOtherServices();//重点分析3
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        }

        // For debug builds, log event loop stalls to dropbox for analysis.
        if (StrictMode.conditionallyEnableDebugLogging()) {
            Slog.i(TAG, "Enabled StrictMode for system server main thread.");
        }

        // Loop forever.
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

SystemServer#createSystemContext()

private void createSystemContext() {
        ActivityThread activityThread = ActivityThread.systemMain();
        mSystemContext = activityThread.getSystemContext();
        mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
    }

ContextImpl#createSystemContext()

static ContextImpl createSystemContext(ActivityThread mainThread) {
        LoadedApk packageInfo = new LoadedApk(mainThread);
        ContextImpl context = new ContextImpl(null, mainThread,
                packageInfo, null, null, false, null, null, Display.INVALID_DISPLAY);
        context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
                context.mResourcesManager.getDisplayMetricsLocked());
        return context;
    }

为什么这个context是叫systemContext?因为在初始化ContextImpl时使用了一个LoadedAPK对象。

LoadedAPK用于保存一些和APK相关的信息(如资源文件和JNI库的位置等)。LoadedApk(ActivityThread)

mApplicationInfo.packageName = "android";
        mPackageName = "android";

该packageName对应的是framework-res.apk,由于APK仅供system_server进程使用,所以称

该context为systemContextcreateSystemContext()中还创建了ActivityThread,这是代表了应

用进程的主线程,这说明system_server进程是一个特殊

的应用进程。

SystemServer#createSystemContext()总结

* 得到一个ActivityThread对象,它代表应用进程的主线程

* 得到一个Context对象,它指向的Application环境与framework-res.apk有关

* Android运行环境:在这个环境中,进程概念被模糊化,组件的运行及他们之间的交互均在该环

  境中实现(或者说依赖该环境,即依赖Context和ActivityThread)

创建AMS对象:

systemServer#run() -> 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.
        mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);
        //...
        mActivityManagerService.setSystemProcess()


ActvityManagerService.Lifecycle

public Lifecycle(Context context) {
            super(context);
            mService = new ActivityManagerService(context);
        }

ActivityManagerService#setSystemProcess()

public void setSystemProcess() {
        try {
            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));

            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
                    "android", STOCK_PM_FLAGS);//查询对应PackageName的ApplicationInfo
            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());//重点分析

            synchronized (this) {//AMS对应用进程的纳入管理
                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
                app.persistent = true;
                app.pid = MY_PID;
                app.maxAdj = ProcessList.SYSTEM_ADJ;
                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
                synchronized (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);
        }
    }

* 向ServiceManagerService注册几个服务,注册了AMS,meminfo,gfxinfo等服务

* 向PackageManagerService查询package名为android的Application。PMKS与AMS同属一个进程

  但二者仍然借助Context(可用于跨进程通信)。因PMKS和AMS处于同一个进程,此处完全可以直接

  调用PKMS的函数。原因是Android希望system_server中的服务也通过Android运行环境来交互。

* 调用ActivityThread#installSystemApplicationInfo,用于将Context和ApplicationInfo绑定。

* 因为有些APK运行在system_server进程中,所以system_server作为一个特殊的应用进程,

   也需要被AMS管理,而AMS中的进程管理结构是ProcessRecord。创建一个代表system_server

  进程的ProcessRecord

SystemServer#startOtherServices()

 mActivityManagerService.installSystemProviders();

这个Provider就是SettingsProviders.apk里的那个SettingsProvider。由于该apk的manifest中声明

的uid为android.uid.system,process name为system,所以可以确定SettingsProvider.apk是运行在

system_server进程中,和framework-res.apk在同一进程。因为ContentProvider是运行在定义它的

那个应用的进程中(如果contentProvider没有声明在单独线程的话),所以此时不用去创建进程再去

安装provider。关于更详细的ContentProvider的安装过程看《深入理解Android2》第七章,给个

ContentProvider从客户端调用getContentProvider到返回这个过程的流程图:

《AMS-启动AMS(AMS在SystemServer中的调用轨迹)》

SystemServer#startOtherServices() -> ActivityManagerService#systemReady(final Runnable goingCallback)

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);
                }

                Slog.i(TAG, "WebViewFactory preparation");
                WebViewFactory.prepareWebViewInSystemServer();

                try {
                    startSystemUi(context);
                } catch (Throwable e) {
                    reportWtf("starting System UI", e);
                }
                try {
                    if (networkScoreF != null) networkScoreF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Network Score Service ready", e);
                }
                try {
                    if (networkManagementF != null) networkManagementF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Network Managment Service ready", e);
                }
                try {
                    if (networkStatsF != null) networkStatsF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Network Stats Service ready", e);
                }
                try {
                    if (networkPolicyF != null) networkPolicyF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Network Policy Service ready", e);
                }
                try {
                    if (connectivityF != null) connectivityF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Connectivity Service ready", e);
                }
                try {
                    if (audioServiceF != null) audioServiceF.systemReady();
                } catch (Throwable e) {
                    reportWtf("Notifying AudioService running", e);
                }
                Watchdog.getInstance().start();

                // It is now okay to let the various system services start their
                // third party code...
                mSystemServiceManager.startBootPhase(
                        SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);

可将ActivityManagerService#systemReady()的工作分为三个阶段:

第一阶段:

发送PRE_BOOT_COMPLETED广播,该广播接收者的工作好像和系统升级有关

第二阶段:

* 杀死那些在AMS注册了的,还未启动完毕就先启动的应用进程。这些应用进程一定是APK

  所在的java进程,因为只有应用进程才会向AMS注册,而一般的Native(例如mediaserver)进程是不会向AMS注册的。

* 从Settings数据库中获取配置信息。

第三阶段:

* 调用systemReady设置的回调对象goingCallback的run函数。

* 启动那些声明了persistent的APK(persistent应用在意外挂掉后,AMS会自动重启该APK)

* 启动桌面

startHomeActivityLocked(mCurrentUserId, "systemReady");

goingCallback的run函数

* 执行startSystemUi,在该函数内部启动SystemUIService,该Service和状态栏有关。

static final void startSystemUi(Context context) {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.android.systemui",
                    "com.android.systemui.SystemUIService"));
        //Slog.d(TAG, "Starting service: " + intent);
        context.startServiceAsUser(intent, UserHandle.OWNER);
    }

* 调用一些服务的systemReady 

AMS中的Service都启动完毕,Home也靓丽登场,整个系统准备完毕,。最后发送

ACTION_BOOT_COMPLETED广播

ActivityStackSupervisor#activityIdleInternalLocked(…) ->

ActivityManagerService#postfinishBooting() -> …-> ActivityManagerService#finishBooting()

ActivityManagerService#finishBooting()

Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
                        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) {
                                        synchronized (ActivityManagerService.this) {
                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
                                                    true, false);
                                        }
                                    }
                                },
                                0, null, null,
                                new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
                                AppOpsManager.OP_NONE, null, true, false,
                                MY_PID, Process.SYSTEM_UID, userId);


AMS-启动Activity之二 这篇文章可知,activityIdleInternalLocked是在目标Activityresume后才调用的,

就是说ACTION_BOOT_COMPLETED广播是在Home Activity启动后才发出的。

最后是一些补充的知识点和总结:

* 一个进程可以运行多个Application,system_server进程就是一个典型例子。(运行了framework-res.apk和SettingsProvider.apk)

* AMS通过IApplicationThread与应用进程通信

  《AMS-启动AMS(AMS在SystemServer中的调用轨迹)》

* Binder系统支持客户端监听服务端的死亡消息。

* 从运行效率角度看,多个服务和系统核心Application放在同一个进程(system_server进程)是合理的,

  因为很多Service都依赖Settings的数据库,把它们放在同一进程中,可以降低由于进程间通信带来的

  效率损失。

*




    原文作者:淡淡的宁静
    原文地址: https://blog.csdn.net/b1480521874/article/details/76269441
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞