SystemUI分析(Android9.0)

Posted by Haiden on June 9, 2019

一、SystemUI组成

SystemUI是Android的系统界面,包括状态栏statusbar、锁屏keyboard、任务列表recents等等,都继承于SystemUI这个类,如锁屏KeyguardViewMediator。

二、SystemUI启动流程

SystemUI的启动由SystemServer开始。SystemServer由Zygote fork生成的,进程名为system_server,该进程承载着framework的核心服务。Zygote启动过程中会调用startSystemServer()。SystemUI的分析从SystemServer的main方法开始。SystemUI启动的大致流程如下:

2.1 SystemServer

SystemServer在run方法中负责启动系统的各种服务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
   ..........
    // Start services.
        try {
            traceBeginAndSlog("StartServices");
            startBootstrapServices();
            startCoreServices();
            startOtherServices();
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            traceEnd();
        }

在startOtherServices方法中先是创建并添加WindowManagerService、InputManagerService等service,并且调用startSystemUi方法,跳转SystemUIService。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 private void startOtherServices() {
 		//创建,注册服务	
 		...
        WindowManagerService wm = null;
        SerialService serial = null;
        NetworkTimeUpdateService networkTimeUpdater = null;
        CommonTimeManagementService commonTimeMgmtService = null;
        InputManagerService inputManager = null;
		...
        traceBeginAndSlog("IpConnectivityMetrics");
        mSystemServiceManager.startService(IpConnectivityMetrics.class);
        traceEnd();

        traceBeginAndSlog("NetworkWatchlistService");
        mSystemServiceManager.startService(NetworkWatchlistService.Lifecycle.class);
        traceEnd();
	...
	
	 			traceBeginAndSlog("StartSystemUI");
            try {
                startSystemUi(context, windowManagerF);
            } catch (Throwable e) {
                reportWtf("starting System UI", e);
            }
	

启动跳转SystemUIService。

1
2
3
4
5
6
7
8
9
    static final void startSystemUi(Context context, WindowManagerService windowManager) {
        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);
        windowManager.onSystemUiStarted();
    }
2.2 SystemUIService

SystemUIService在onCreate中调用SystemUIApplication的startServicesIfNeeded方法。

1
2
3
4
5
6
7
8
9
10
11
12
    @Override
    public void onCreate() {
        super.onCreate();
        ((SystemUIApplication) getApplication()).startServicesIfNeeded();

        // For debugging RescueParty
        if (Build.IS_DEBUGGABLE && SystemProperties.getBoolean("debug.crash_sysui", false)) {
            throw new RuntimeException();
        }
        ...
}
2.3 SystemUIApplication

SystemUIApplication先获取配置的systemUI组件。

1
2
3
4
    public void startServicesIfNeeded() {
        String[] names = getResources().getStringArray(R.array.config_systemUIServiceComponents);
        startServicesIfNeeded(names);
    }

配置文件在/frameworks/base/packages/SystemUI/res/values/config.xml中,配置的systemui组件如图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
     <string-array name="config_systemUIServiceComponents" translatable="false">
332        <item>com.android.systemui.Dependency</item>
333        <item>com.android.systemui.util.NotificationChannels</item>
334        <item>com.android.systemui.statusbar.CommandQueue$CommandQueueStart</item>
335        <item>com.android.systemui.keyguard.KeyguardViewMediator</item>
336        <item>com.android.systemui.recents.Recents</item>
337        <item>com.android.systemui.volume.VolumeUI</item>
338        <item>com.android.systemui.stackdivider.Divider</item>
339        <item>com.android.systemui.SystemBars</item>
340        <item>com.android.systemui.usb.StorageNotification</item>
341        <item>com.android.systemui.power.PowerUI</item>
342        <item>com.android.systemui.media.RingtonePlayer</item>
343        <item>com.android.systemui.keyboard.KeyboardUI</item>
344        <item>com.android.systemui.pip.PipUI</item>
345        <item>com.android.systemui.shortcut.ShortcutKeyDispatcher</item>
346        <item>@string/config_systemUIVendorServiceComponent</item>
347        <item>com.android.systemui.util.leak.GarbageMonitor$Service</item>
348        <item>com.android.systemui.LatencyTester</item>
349        <item>com.android.systemui.globalactions.GlobalActionsComponent</item>
350        <item>com.android.systemui.ScreenDecorations</item>
351        <item>com.android.systemui.fingerprint.FingerprintDialogImpl</item>
352        <item>com.android.systemui.SliceBroadcastRelayHandler</item>
353    </string-array>

在startServicesIfNeeded方法中,根据config配置创建SystemUI,并调用SystemUI的start方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 private void startServicesIfNeeded(String[] services) {
        if (mServicesStarted) {
            return;
        }
        mServices = new SystemUI[services.length];

        final int N = services.length;
        for (int i = 0; i < N; i++) {
            String clsName = services[i];
            if (DEBUG) Log.d(TAG, "loading: " + clsName);
            log.traceBegin("StartServices" + clsName);
            long ti = System.currentTimeMillis();
            Class cls;
            try {
                cls = Class.forName(clsName);
                mServices[i] = (SystemUI) cls.newInstance();
            } catch(ClassNotFoundException ex){
                throw new RuntimeException(ex);
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InstantiationException ex) {
                throw new RuntimeException(ex);
            }

            mServices[i].mContext = this;
            mServices[i].mComponents = mComponents;
            if (DEBUG) Log.d(TAG, "running: " + mServices[i]);
            mServices[i].start();
            log.traceEnd();
     ...       
 }
2.4 SystemUI

SystemUI是一个抽象类,start()是抽象方法,具体实现在子类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public abstract class SystemUI implements SysUiServiceProvider {
    public Context mContext;
    public Map<Class<?>, Object> mComponents;

    public abstract void start();

    protected void onConfigurationChanged(Configuration newConfig) {
    }

    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
    }

    protected void onBootCompleted() {
    }
    ...
 }