android9 SystemUI startup process

1. Overview of SystemUI

SystemUI is a system application, the apk path is located at /system/priv-app
source code path is located at: /framework/base/packages/SystemUI
is mainly responsible for functions:

  • StatusBar: status bar
  • NavigationBar: Navigation bar (back, home, recent tasks)
  • Notification Panel: notification bar and quick setting panel
  • wallpaper management
  • screenshot function
  • Recents: recent tasks (android9 uses recent tasks in launcher3, but SystemUI9 also retains related codes, which can be set in systemUi)
  • Record screen function
  • screenshot service
  • VolumeBar: volume control
  • Keyguard lock screen
  • RingtonePlayer Ringtone player interface
  • PipUI picture-in-picture interface
  • RingtonePlayer Ringtone player interface
    . . . . .

2. SystemUI startup

The general process of system startup:
uboot boot os startup > load kernel > init process, fork out zygote process > zygote starts SystemServer;
SystemServer is responsible for starting various core services of the system, initializing and loading some applications.
com.android.server.SystemServer.java:
main method:

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

run() method:

private void run() {
    
    
   ...
 // Start services.
 try {
    
    
        traceBeginAndSlog("StartServices");
        startBootstrapServices();  //引导服务
        startCoreServices();    //核心服务
        startOtherServices();  //其他
        SystemServerInitThreadPool.shutdown();
  }
   ...
}

The three start methods can be seen from the naming available to start the boot service, core service and other services respectively. startBootstrapServices():

 private void startBootstrapServices() {
    
    
        ...
  Installer installer = mSystemServiceManager.startService(Installer.class);
  mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
  mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
  mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
  mActivityManagerService.setInstaller(installer);
  mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);   
  mSystemServiceManager.startService(LightsService.class);
  mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer));
        ...
 }

You can see that AMS, PMS, LightsService and other services are enabled here.
The startup of SystemUI is located in startOtherServices():

private void startOtherServices() {
    
    
   ...
   traceBeginAndSlog("StartSystemUI");
   try {
    
    
      startSystemUi(context, windowManagerF);
   } catch (Throwable e) {
    
    
      reportWtf("starting System UI", e);
   }
   ...
}

This method has a lot of code, only the key points are listed, and then look at the startSystemUi method:

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

Create an Intent and start the SystemUIService service with the component name com.android.systemui.SystemUIService. At this point, I finally came to the SystemUI project.

3. Loading of SystemUI

com.android.systemui.SystemUIService.java

public class SystemUIService extends Service {
    
    

    @Override
    public void onCreate() {
    
    
        super.onCreate();
        ((SystemUIApplication) getApplication()).startServicesIfNeeded();
        ...
    }
}

SystemUIService inherits Service, and onCreate calls the startServicesIfNeeded method of SystemUIApplication:

public class SystemUIApplication extends Application...{
    
    
  public void startServicesIfNeeded() {
    
    
    String[] names = getResources().getStringArray(R.array.config_systemUIServiceComponents);
        startServicesIfNeeded(names);
    }
 }

The config_systemUIServiceComponents array contains the full class names of each functional module, as follows

<string-array name="config_systemUIServiceComponents" translatable="false">
     <item>com.android.systemui.Dependency</item>
     <item>com.android.systemui.util.NotificationChannels</item>
     <item>com.android.systemui.statusbar.CommandQueue$CommandQueueStart</item>
     <item>com.android.systemui.keyguard.KeyguardViewMediator</item>
     <item>com.android.systemui.recents.Recents</item>
     <item>com.android.systemui.volume.VolumeUI</item>
     <item>com.android.systemui.stackdivider.Divider</item>
     <item>com.android.systemui.SystemBars</item>
     <item>com.android.systemui.usb.StorageNotification</item>
     <item>com.android.systemui.power.PowerUI</item>
     <item>com.android.systemui.media.RingtonePlayer</item>
     <item>com.android.systemui.keyboard.KeyboardUI</item>
     <item>com.android.systemui.pip.PipUI</item>
     <item>com.android.systemui.shortcut.ShortcutKeyDispatcher</item>
     <item>@string/config_systemUIVendorServiceComponent</item>
     <item>com.android.systemui.util.leak.GarbageMonitor$Service</item>
     <item>com.android.systemui.LatencyTester</item>
     <item>com.android.systemui.globalactions.GlobalActionsComponent</item>
     <item>com.android.systemui.ScreenDecorations</item>
     <item>com.android.systemui.fingerprint.FingerprintDialogImpl</item>
     <item>com.android.systemui.SliceBroadcastRelayHandler</item>
</string-array>

You can see the corresponding functional modules mentioned in 1 above. Next is the real loading method,
startServicesIfNeeded(String[] services)

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

            // Warn if initialization of component takes too long
            ti = System.currentTimeMillis() - ti;
            if (ti > 1000) {
    
    
                Log.w(TAG, "Initialization of " + cls.getName() + " took " + ti + " ms");
            }
            if (mBootCompleted) {
    
    
                mServices[i].onBootCompleted();
            }
        }
       ......
    }

First create a new SystemUI array (mServices), then traverse the incoming services array and assign the SystemUI object to the mServices array through reflection, and finally load each module through mServices[i].start(). Note that mServices[i].start here is not the usual startup service. Take NotificationChannels as an example:
NotificationChannels inherits SystemUI:

 public abstract class SystemUI implements SysUiServiceProvider {
    
    
    public Context mContext;
    public Map<Class<?>, Object> mComponents;

    public abstract void start();
    ....
 }
public class NotificationChannels extends SystemUI{
    
    
  @Override
    public void start() {
    
    
        createAll(mContext);
    }
}

That is to say, each module inherits SystemUI, rewrites the start method, and mServices[i].start() calls the start method of each module to complete the loading.

Guess you like

Origin blog.csdn.net/weixin_40652755/article/details/122670778