Android 7.0 SystemUI(1)--启动过程

本文基于Android 7.0,记录SystemUI学习过程,如有错误之处 请谅解。

涉及到的代码

frameworks/base/services/java/com/android/server/SystemServer.java
frameworks/base/core/java/android/app/ContextImpl.java
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java 
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java 
frameworks/base/core/java/android/app/ActivityThread.java
frameworks/base/packages/SystemUI/


SystemUI是系统app,源码位于framework/base/package/SystemUI。

SystemUI启动是从frameworks/base/services/java/com/android/server/SystemServer.java main()开始的。


 /**
     * The main entry point from zygote.
     */
    public static void main(String[] args) {
        new SystemServer().run();
    }
进入到run()中

private void run() {
        
	...

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

       ...
	   
    }
所有的系统服务都是在这里启动的,其中在startBootstrapServices()中启动了ActivityManagerService、PowerManagerService、PackageManagerService等一系列核心服务,SystemUI是在startOtherServices()中。

/**
     * Starts a miscellaneous grab bag of stuff that has yet to be refactored
     * and organized.
     */
    private void startOtherServices(){

		...

        WindowManagerService wm = null;

       
		...
     
        try {
           
         ...
          
            wm = WindowManagerService.main(context, inputManager,
                    mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
                    !mFirstBoot, mOnlyCore);
            ServiceManager.addService(Context.WINDOW_SERVICE, wm);
            ...
        } catch (RuntimeException e) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting core service", e);
        }

		...
		
        StatusBarManagerService statusBar = null;
        INotificationManager notification = null;
       
	   ...

        if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
           ...

            if (!disableSystemUI) {
                traceBeginAndSlog("StartStatusBarManagerService");
                try {
                    statusBar = new StatusBarManagerService(context, wm);
                    ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
                } catch (Throwable e) {
                    reportWtf("starting StatusBarManagerService", e);
                }
                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
            }

           ...
		   
            mSystemServiceManager.startService(NotificationManagerService.class);
            notification = INotificationManager.Stub.asInterface(
                    ServiceManager.getService(Context.NOTIFICATION_SERVICE));
           ...
          
        }
		...
        // 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.
        mActivityManagerService.systemReady(new Runnable() {
            @Override
            public void run() {
                ...

                Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartSystemUI");
                try {
                    startSystemUi(context);
                } catch (Throwable e) {
                    reportWtf("starting System UI", e);
                }
				
                ...
            }
        });
       
    }

startOtherServices()还启动了大名鼎鼎的WindowManagerService。然后启动StatusBarManagerService,该服务是用来和SystemUI交互的。所有的系统服务启动完成之后,ams会调用systemReady去真正开始启动SystemUI。

frameworks/base/services/java/com/android/server/SystemServer.java

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

可以看到这里是通过context的startServiceAsUser去启动SystemUIService。该方法的真正实现是在ContextImpl.java

frameworks/base/core/java/android/app/ContextImpl.java

    @Override
    public ComponentName startServiceAsUser(Intent service, UserHandle user) {
        return startServiceCommon(service, user);
    }

    private ComponentName startServiceCommon(Intent service, UserHandle user) {
        try {
            validateServiceIntent(service);
            service.prepareToLeaveProcess(this);
            ComponentName cn = ActivityManagerNative.getDefault().startService(
                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                            getContentResolver()), getOpPackageName(), user.getIdentifier());
            if (cn != null) {
                if (cn.getPackageName().equals("!")) {
                    throw new SecurityException(
                            "Not allowed to start service " + service
                            + " without permission " + cn.getClassName());
                } else if (cn.getPackageName().equals("!!")) {
                    throw new SecurityException(
                            "Unable to start service " + service
                            + ": " + cn.getClassName());
                }
            }
            return cn;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
ContextImpl最终会通过binder通信调用到ActivityManagerService的startService方法。

先看一下这里面的参数

 ComponentName cn = ActivityManagerNative.getDefault().startService(
                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                            getContentResolver()), getOpPackageName(), user.getIdentifier());
其中mMainThread是ActivityThread类型对象,即进程里的主线程(UI线程), 在Android应用程序中,每一个进程对应一个ActivityThread实例。mMainThread.getApplicationThread()得到的是ApplicationThread类型对象,ApplicationThread是 ActivityThread的一个对象,ApplicationThread不直接和AMS交互,ApplicationThread对象通过接收一系列指令(scheduleLaunchActivity、scheduleDestroyActivity等)是应用程序进程和AMS真正进行交互的地方。

上述流程都是跑在system_server进程中(DDMS中对应"system_process"进程)。

这里省略了binder通信的过程,直接进入到ActivityManagerService的startService方法

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java 

    @Override
    public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, String callingPackage, int userId)
            throws TransactionTooLargeException {
        enforceNotIsolatedCaller("startService");
        // Refuse possible leaked file descriptors
        if (service != null && service.hasFileDescriptors() == true) {
            throw new IllegalArgumentException("File descriptors passed in Intent");
        }

        if (callingPackage == null) {
            throw new IllegalArgumentException("callingPackage cannot be null");
        }

        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
                "startService: " + service + " type=" + resolvedType);
        synchronized(this) {
	    //获取调用者信息
            final int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            ComponentName res = mServices.startServiceLocked(caller, service,
                    resolvedType, callingPid, callingUid, callingPackage, userId);
            Binder.restoreCallingIdentity(origId);
            return res;
        }
    }
mServices是ActiveServices类型对象,调用该对象的startServiceLocked方法。

frameworks/base/services/core/java/com/android/server/am/ActiveServices.java 
   ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
            int callingPid, int callingUid, String callingPackage, final int userId)
            throws TransactionTooLargeException {
        ...
		//先解析要启动的service信息
        ServiceLookupResult res =
            retrieveServiceLocked(service, resolvedType, callingPackage,
                    callingPid, callingUid, userId, true, callerFg, false);
        ...

        return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
    }
首先通过retrieveServiceLocked去获取service具体信息

frameworks/base/services/core/java/com/android/server/am/ActiveServices.java 
private ServiceLookupResult retrieveServiceLocked(Intent service,
            String resolvedType, String callingPackage, int callingPid, int callingUid, int userId,
            boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal) {
		//每一个启动的service在ams中都有一个对应的ServiceRecord信息
        ServiceRecord r = null;
        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "retrieveServiceLocked: " + service
                + " type=" + resolvedType + " callingUid=" + callingUid);

        userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
                ActivityManagerService.ALLOW_NON_FULL_IN_PROFILE, "service", null);

		//ServiceMap是ActiveServices的内部类,其中final ArrayMap mServicesByName保存了已启动的所有service信息
        ServiceMap smap = getServiceMap(userId);
        final ComponentName comp = service.getComponent();

        if (comp != null) {
			//查询已启动的service列表中是否有我们要启动的服务,这里SystemuiService还没有启动过,获取到的值为null
            r = smap.mServicesByName.get(comp);
        }
       ...
	   //r == null 为true,会执行如下if
        if (r == null) {
            try {
                // TODO: come back and remove this assumption to triage all services
				//开机的时候PackageManagerService会去解析安装每一个apk,并保存相应的信息,从PackageManagerService中获取到service信息
                ResolveInfo rInfo = AppGlobals.getPackageManager().resolveService(service,
                        resolvedType, ActivityManagerService.STOCK_PM_FLAGS
                                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
                        userId);
                ServiceInfo sInfo =
                    rInfo != null ? rInfo.serviceInfo : null;
                ...
				r = smap.mServicesByName.get(name);
                if (r == null && createIfNeeded) {
                    Intent.FilterComparison filter
                            = new Intent.FilterComparison(service.cloneFilter());
                    ServiceRestarter res = new ServiceRestarter();
                    BatteryStatsImpl.Uid.Pkg.Serv ss = null;
                    BatteryStatsImpl stats = mAm.mBatteryStatsService.getActiveStatistics();
                    synchronized (stats) {
                        ss = stats.getServiceStatsLocked(
                                sInfo.applicationInfo.uid, sInfo.packageName,
                                sInfo.name);
                    }
					//创建ServiceRecord,并且保存信息到ServiceMap中
                    r = new ServiceRecord(mAm, ss, name, filter, sInfo, callingFromFg, res);
                    res.setService(r);
                    smap.mServicesByName.put(name, r);
                    smap.mServicesByIntent.put(filter, r);

                    // Make sure this component isn't in the pending list.
					//mPendingServices中保存了要启动的service列表
                    for (int i=mPendingServices.size()-1; i>=0; i--) {
                        ServiceRecord pr = mPendingServices.get(i);
                        if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
                                && pr.name.equals(name)) {
                            mPendingServices.remove(i);
                        }
                    }
            } catch (RemoteException ex) {
                // pm is in same process, this will never happen.
            }
        }
        if (r != null) {
            ...
            return new ServiceLookupResult(r, null);
        }
        return null;
    }
处理好ServiceRecord之后,回到ActiveServices的startServiceLocked方法继续执行startServiceInnerLocked

frameworks/base/services/core/java/com/android/server/am/ActiveServices.java 
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
            boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
        ...
        String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
        ...

        return r.name;
    }

进入到bringUpServiceLocked中

frameworks/base/services/core/java/com/android/server/am/ActiveServices.java 
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
            boolean whileRestarting, boolean permissionsReviewRequired)
            throws TransactionTooLargeException {
        ...

		//processName,可以在AndroidManifest.xml通过android:process去指定进程名称,如果不指定默认是应用包名
        final String procName = r.processName;
		//每一个process在ams都对应一个ProcessRecord
        ProcessRecord app;
		...

        // Not running -- get it started, and enqueue this service record
        // to be executed when the app comes up.
        if (app == null && !permissionsReviewRequired) {
		//开始创建一个新的进程去启动服务
            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                    "service", r.name, false, isolated, false)) == null) {
                String msg = "Unable to launch app "
                        + r.appInfo.packageName + "/"
                        + r.appInfo.uid + " for service "
                        + r.intent.getIntent() + ": process is bad";
                Slog.w(TAG, msg);
                bringDownServiceLocked(r);
                return msg;
            }
            if (isolated) {
                r.isolatedProc = app;
            }
        }

		//将ServiceRecord加入mPendingServices列表,后面会用到
        if (!mPendingServices.contains(r)) {
            mPendingServices.add(r);
        }

        ...

        return null;
    }

下面开始创建com.android.systemui进程
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java 

final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
            boolean isolated, boolean keepIfLarge) {
        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
                null /* crashHandler */);
    }

    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
        ...
        ProcessRecord app;
        ...

        startProcessLocked(
                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
        ...
        return (app.pid != 0) ? app : null;
    }
startProcessLocked中调用Process.start去创建进程

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java 

    private final void startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
       ...

        try {
            
        
            // Start the process.  It will either succeed and return a result containing
            // the PID of the new process, or else throw a RuntimeException.
            boolean isActivityProcess = (entryPoint == null);
            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
            ...
            Process.ProcessStartResult startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, debugFlags, mountExternal,
                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
                    app.info.dataDir, entryPointArgs);
            ...
        } catch (RuntimeException e) {
            ...
        }
    }

Process.start中通过Zygote去fork一个进程,这里省略该过程。从Process.start可以看出一个process的入口是在android.app.ActivityThread,com.android.systemui进程创建之后首先会执行ActivityThread的main方法,接下来的步骤在com.android.systemui进程中执行。

frameworks/base/core/java/android/app/ActivityThread.java

       public static void main(String[] args) {
        ...
		//创建looper
        Looper.prepareMainLooper();

		//创建一个ActivityThread
        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        ...
		//进入looper消息循环
        Looper.loop();

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

首先要创建主线程的looper,用于处理各类消息。调用ActivityThread的attach方法执行后续处理。

frameworks/base/core/java/android/app/ActivityThread.java
private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
		//非system进程,这里system进程是指system_server,其他为非system进程
           ...
            final IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
          ...
        } else {
           ...
        }

       ...
        });
    }
IActivityManager的attachApplication中使用mAppThread参数是ApplicationThread类型的,在new ActivityThread()的时候自动创建。前面所述,该变量是用来真正和ams进行交互的。接下来通过binder通信进入到ams的attachApplication中

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java 
  @Override
    public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid);
            Binder.restoreCallingIdentity(origId);
        }
    }
	
	private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {

        // Find the application record that is being attached...  either via
        // the pid if we are running in multiple processes, or just pull the
        // next app record if we are emulating process with anonymous threads.
		//首先根据进程pid去ams中找出进程的ProcessRecord
        ProcessRecord app;
        if (pid != MY_PID && pid >= 0) {
            synchronized (mPidsSelfLocked) {
                app = mPidsSelfLocked.get(pid);
            }
        } else {
            app = null;
        }

        ...

        boolean badApp = false;
        boolean didSomething = false;

        // See if the top visible activity is waiting to run in this process...
		//systemui中不需要启动activity
        if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }

        // Find any services that should be running in this process...
        if (!badApp) {
            try {
                didSomething |= mServices.attachApplicationLocked(app, processName);
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
                badApp = true;
            }
        }

        ...

        return true;
    }
调用了ActiveServices的attachApplicationLocked方法
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java 
boolean attachApplicationLocked(ProcessRecord proc, String processName)
            throws RemoteException {
        boolean didSomething = false;
        // Collect any services that are waiting for this process to come up.
		//service第一次start走这里
		//前面我们将要启动的systemuiservice放入到了mPendingServices中,现在取出来
        if (mPendingServices.size() > 0) {
            ServiceRecord sr = null;
            try {
                for (int i=0; i 0) {
            ServiceRecord sr;
            for (int i=0; i
前面把systemuiservice保存到了mPendingServices中,将其取出来开始真正启动systemuiservice
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java 
private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
        ...
        try {
           ...
            app.thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                    app.repProcState);
            ...
        } catch (DeadObjectException e) {
            ...
        } finally {
           ...
        }
		...
    }
这里我们可以再次看到,ActivityThread是不直接和ams交互的,而是通过其内部类ApplicationThread去交互,即ActivityThread通过ApplicationThread和ams交互。进入到ApplicationThread的scheduleCreateService

frameworks/base/core/java/android/app/ActivityThread.java
      public final void scheduleCreateService(IBinder token,
                ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
            updateProcessState(processState, false);
            CreateServiceData s = new CreateServiceData();
            s.token = token;
            s.info = info;
            s.compatInfo = compatInfo;

            sendMessage(H.CREATE_SERVICE, s);
        }
ApplicationThread简单的发送了一个CREATE_SERVICE的消息到主线程ActivityThread

frameworks/base/core/java/android/app/ActivityThread.java
public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
			
                case LAUNCH_ACTIVITY: {
				//启动activity走这里
                 ...
                } break;
                ...
                case PAUSE_ACTIVITY: {
				//pause activity走这里
                    ...
                } break;
                ...
                case RESUME_ACTIVITY:
                    //resume activity走这里
					...
                    break;
                ...
                case DESTROY_ACTIVITY:
				//destroy activity走这里
                   ...
                    break;
                ...
                case RECEIVER:
				//广播走这里
                  ...
                    break;
                case CREATE_SERVICE:
				//启动服务走这里
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
                    handleCreateService((CreateServiceData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case BIND_SERVICE:
                   //bindservice走这里
                    break;
				...
		}
	}

主线程接到CREATE_SERVICE的消息之后开始创建service。从这里看到,默认情况下一个process只有一个ActivityThread主线程,并且广播reciver、activity、service组件都是跑在同一个主线程。

frameworks/base/core/java/android/app/ActivityThread.java
    private void handleCreateService(CreateServiceData data) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();

        LoadedApk packageInfo = getPackageInfoNoCheck(
                data.info.applicationInfo, data.compatInfo);
        Service service = null;
        try {
		//通过ClassLoader去加载创建要启动的服务对象
            java.lang.ClassLoader cl = packageInfo.getClassLoader();
            service = (Service) cl.loadClass(data.info.name).newInstance();
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to instantiate service " + data.info.name
                    + ": " + e.toString(), e);
            }
        }

        try {
            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);

			//创建service运行环境
            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);

            Application app = packageInfo.makeApplication(false, mInstrumentation);
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManagerNative.getDefault());
			//最后直接调用service对象的onCreate方法
            service.onCreate();
            mServices.put(data.token, service);
            try {
                ActivityManagerNative.getDefault().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to create service " + data.info.name
                    + ": " + e.toString(), e);
            }
        }
    }
handleCreateService中创建了服务对象,并且调用该服务的onCreate方法,进入到SystemUiService的onCreate方法
frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIService.java
    @Override
    public void onCreate() {
        super.onCreate();
        ((SystemUIApplication) getApplication()).startServicesIfNeeded();
    }
这样SystemUI就被启动起来了。

你可能感兴趣的:(systemui)