1.frameworks\base\services\java\com\android\server\SystemServer.java startOtherServices
// 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(); }
2.startOtherServices 在 mActivityManagerService.systemReady里startSystemUi
mActivityManagerService.systemReady(() -> { Slog.i(TAG, "Making services ready"); traceBeginAndSlog("StartActivityManagerReadyPhase"); mSystemServiceManager.startBootPhase( SystemService.PHASE_ACTIVITY_MANAGER_READY); traceEnd(); traceBeginAndSlog("StartObservingNativeCrashes"); try { mActivityManagerService.startObservingNativeCrashes(); } catch (Throwable e) { reportWtf("observing native crashes", e); } traceEnd(); // No dependency on Webview preparation in system server. But this should // be completed before allowring 3rd party final String WEBVIEW_PREPARATION = "WebViewFactoryPreparation"; Future<?> webviewPrep = null; if (!mOnlyCore) { webviewPrep = SystemServerInitThreadPool.get().submit(() -> { Slog.i(TAG, WEBVIEW_PREPARATION); TimingsTraceLog traceLog = new TimingsTraceLog( SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER); traceLog.traceBegin(WEBVIEW_PREPARATION); ConcurrentUtils.waitForFutureNoInterrupt(mZygotePreload, "Zygote preload"); mZygotePreload = null; mWebViewUpdateService.prepareWebViewInSystemServer(); traceLog.traceEnd(); }, WEBVIEW_PREPARATION); } if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { traceBeginAndSlog("StartCarServiceHelperService"); mSystemServiceManager.startService(CarServiceHelperService.class); traceEnd(); } traceBeginAndSlog("StartSystemUI"); try { startSystemUi(context, windowManagerF); } catch (Throwable e) { reportWtf("starting System UI", e); } traceEnd(); traceBeginAndSlog("MakeNetworkScoreReady"); try { if (networkScoreF != null) networkScoreF.systemReady(); } catch (Throwable e) { reportWtf("making Network Score Service ready", e); } traceEnd(); traceBeginAndSlog("MakeNetworkManagementServiceReady"); try { if (networkManagementF != null) networkManagementF.systemReady(); } catch (Throwable e) { reportWtf("making Network Managment Service ready", e); } CountDownLatch networkPolicyInitReadySignal = null; if (networkPolicyF != null) { networkPolicyInitReadySignal = networkPolicyF .networkScoreAndNetworkManagementServiceReady(); } traceEnd(); traceBeginAndSlog("MakeNetworkStatsServiceReady"); try { if (networkStatsF != null) networkStatsF.systemReady(); } catch (Throwable e) { reportWtf("making Network Stats Service ready", e); } traceEnd(); traceBeginAndSlog("MakeConnectivityServiceReady"); try { if (connectivityF != null) connectivityF.systemReady(); } catch (Throwable e) { reportWtf("making Connectivity Service ready", e); } traceEnd(); traceBeginAndSlog("MakeNetworkPolicyServiceReady"); try { if (networkPolicyF != null) { networkPolicyF.systemReady(networkPolicyInitReadySignal); } } catch (Throwable e) { reportWtf("making Network Policy Service ready", e); } traceEnd(); traceBeginAndSlog("StartWatchdog"); Watchdog.getInstance().start(); traceEnd(); // Wait for all packages to be prepared mPackageManagerService.waitForAppDataPrepared(); // It is now okay to let the various system services start their // third party code... traceBeginAndSlog("PhaseThirdPartyAppsCanStart"); // confirm webview completion before starting 3rd party if (webviewPrep != null) { ConcurrentUtils.waitForFutureNoInterrupt(webviewPrep, WEBVIEW_PREPARATION); } mSystemServiceManager.startBootPhase( SystemService.PHASE_THIRD_PARTY_APPS_CAN_START); traceEnd(); traceBeginAndSlog("MakeLocationServiceReady"); try { if (locationF != null) locationF.systemRunning(); } catch (Throwable e) { reportWtf("Notifying Location Service running", e); } traceEnd(); traceBeginAndSlog("MakeCountryDetectionServiceReady"); try { if (countryDetectorF != null) countryDetectorF.systemRunning(); } catch (Throwable e) { reportWtf("Notifying CountryDetectorService running", e); } traceEnd(); traceBeginAndSlog("MakeNetworkTimeUpdateReady"); try { if (networkTimeUpdaterF != null) networkTimeUpdaterF.systemRunning(); } catch (Throwable e) { reportWtf("Notifying NetworkTimeService running", e); } traceEnd(); traceBeginAndSlog("MakeCommonTimeManagementServiceReady"); try { if (commonTimeMgmtServiceF != null) { commonTimeMgmtServiceF.systemRunning(); } } catch (Throwable e) { reportWtf("Notifying CommonTimeManagementService running", e); } traceEnd(); traceBeginAndSlog("MakeInputManagerServiceReady"); try { // TODO(BT) Pass parameter to input manager if (inputManagerF != null) inputManagerF.systemRunning(); } catch (Throwable e) { reportWtf("Notifying InputManagerService running", e); } traceEnd(); traceBeginAndSlog("MakeTelephonyRegistryReady"); try { if (telephonyRegistryF != null) telephonyRegistryF.systemRunning(); } catch (Throwable e) { reportWtf("Notifying TelephonyRegistry running", e); } traceEnd(); traceBeginAndSlog("MakeMediaRouterServiceReady"); try { if (mediaRouterF != null) mediaRouterF.systemRunning(); } catch (Throwable e) { reportWtf("Notifying MediaRouterService running", e); } traceEnd(); traceBeginAndSlog("MakeMmsServiceReady"); try { if (mmsServiceF != null) mmsServiceF.systemRunning(); } catch (Throwable e) { reportWtf("Notifying MmsService running", e); } traceEnd(); traceBeginAndSlog("MakeNetworkScoreServiceReady"); try { if (networkScoreF != null) networkScoreF.systemRunning(); } catch (Throwable e) { reportWtf("Notifying NetworkScoreService running", e); } traceEnd(); traceBeginAndSlog("IncidentDaemonReady"); try { // TODO: Switch from checkService to getService once it's always // in the build and should reliably be there. final IIncidentManager incident = IIncidentManager.Stub.asInterface( ServiceManager.checkService("incident")); if (incident != null) incident.systemRunning(); } catch (Throwable e) { reportWtf("Notifying incident daemon running", e); } traceEnd(); }, BOOT_TIMINGS_TRACE_LOG);
3. startSystemUi
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(); }
通过startServiceAsUser,SystemUIService就启动了,即SystemUI进程开机启动
frameworks\base\packages\SystemUI\src\com\android\systemui\SystemUIService.java
public class SystemUIService extends Service { @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(); } } @Override public IBinder onBind(Intent intent) { return null; }
frameworks\base\packages\SystemUI\src\com\android\systemui\SystemUIApplication.java
在SystemUIService的onCreate方法中会调用SystemUIApplication的startServicesIfNeeded方法,这个方法会调用 startServicesIfNeeded(SERVICES)方法启动一系列服务(并不是真正的service,都继承自SystemUI)。
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() { } @SuppressWarnings("unchecked") public <T> T getComponent(Class<T> interfaceType) { return (T) (mComponents != null ? mComponents.get(interfaceType) : null); } public <T, C extends T> void putComponent(Class<T> interfaceType, C component) { if (mComponents != null) { mComponents.put(interfaceType, component); } } public static void overrideNotificationAppName(Context context, Notification.Builder n) { final Bundle extras = new Bundle(); extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME, context.getString(com.android.internal.R.string.android_system_label)); n.addExtras(extras); } }
public void startServicesIfNeeded() { startServicesIfNeeded(SERVICES); }
/** * The classes of the stuff to start. */ private final Class<?>[] SERVICES = new Class[] { Dependency.class, NotificationChannels.class, CommandQueue.CommandQueueStart.class, KeyguardViewMediator.class, Recents.class, VolumeUI.class, Divider.class, SystemBars.class, StorageNotification.class, PowerUI.class, RingtonePlayer.class, KeyboardUI.class, PipUI.class, ShortcutKeyDispatcher.class, VendorServices.class, GarbageMonitor.Service.class, LatencyTester.class, GlobalActionsComponent.class, RoundedCorners.class, };
startServicesIfNeeded方法会遍历SERVICES 这个数组,依次调用service的start方法启动服务。 private void startServicesIfNeeded(Class<?>[] services) { if (mServicesStarted) { return; } if (!mBootCompleted) { // check to see if maybe it was already completed long before we began // see ActivityManagerService.finishBooting() if ("1".equals(SystemProperties.get("sys.boot_completed"))) { mBootCompleted = true; if (DEBUG) Log.v(TAG, "BOOT_COMPLETED was already sent"); } } Log.v(TAG, "Starting SystemUI services for user " + Process.myUserHandle().getIdentifier() + "."); TimingsTraceLog log = new TimingsTraceLog("SystemUIBootTiming", Trace.TRACE_TAG_APP); log.traceBegin("StartServices"); final int N = services.length; for (int i = 0; i < N; i++) { Class<?> cl = services[i]; if (DEBUG) Log.d(TAG, "loading: " + cl); log.traceBegin("StartServices" + cl.getSimpleName()); long ti = System.currentTimeMillis(); try { Object newService = SystemUIFactory.getInstance().createInstance(cl); mServices[i] = (SystemUI) ((newService == null) ? cl.newInstance() : newService); } 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 " + cl.getName() + " took " + ti + " ms"); } if (mBootCompleted) { mServices[i].onBootCompleted(); } } log.traceEnd(); Dependency.get(PluginManager.class).addPluginListener( new PluginListener<OverlayPlugin>() { private ArraySet<OverlayPlugin> mOverlays; @Override public void onPluginConnected(OverlayPlugin plugin, Context pluginContext) { StatusBar statusBar = getComponent(StatusBar.class); if (statusBar != null) { plugin.setup(statusBar.getStatusBarWindow(), statusBar.getNavigationBarView()); } // Lazy init. if (mOverlays == null) mOverlays = new ArraySet<>(); if (plugin.holdStatusBarOpen()) { mOverlays.add(plugin); Dependency.get(StatusBarWindowManager.class).setStateListener(b -> mOverlays.forEach(o -> o.setCollapseDesired(b))); Dependency.get(StatusBarWindowManager.class).setForcePluginOpen( mOverlays.size() != 0); } } @Override public void onPluginDisconnected(OverlayPlugin plugin) { mOverlays.remove(plugin); Dependency.get(StatusBarWindowManager.class).setForcePluginOpen( mOverlays.size() != 0); } }, OverlayPlugin.class, true /* Allow multiple plugins */); mServicesStarted = true; }
状态栏
状态栏(SystemBars)service是SystemUI中最重要的service,代码量最多,最复杂的,界面结构也复杂。根据前面的内容可知,启动SystemBars是通过调用start()方法,如下图:
frameworks\base\packages\SystemUI\src\com\android\systemui\SystemBars.java
@Override public void start() { if (DEBUG) Log.d(TAG, "start"); createStatusBarFromConfig(); }
private void createStatusBarFromConfig() { if (DEBUG) Log.d(TAG, "createStatusBarFromConfig"); final String clsName = mContext.getString(R.string.config_statusBarComponent); if (clsName == null || clsName.length() == 0) { throw andLog("No status bar component configured", null); } Class<?> cls = null; try { cls = mContext.getClassLoader().loadClass(clsName); } catch (Throwable t) { throw andLog("Error loading status bar component: " + clsName, t); } try { mStatusBar = (SystemUI) cls.newInstance(); } catch (Throwable t) { throw andLog("Error creating status bar component: " + clsName, t); } mStatusBar.mContext = mContext; mStatusBar.mComponents = mComponents; mStatusBar.start(); if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName()); }
frameworks\base\packages\SystemUI\res\values\config.xml <string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.StatusBar</string>
@Override public void start() { mScreenLifecycle.addObserver(mScreenObserver); mWakefulnessLifecycle.addObserver(mWakefulnessObserver); mUiModeManager = mContext.getSystemService(UiModeManager.class); mBypassHeadsUpNotifier.setUp(); if (mBubblesOptional.isPresent()) { mBubblesOptional.get().setExpandListener(mBubbleExpandListener); } mStatusBarSignalPolicy.init(); mKeyguardIndicationController.init(); mColorExtractor.addOnColorsChangedListener(mOnColorsChangedListener); mStatusBarStateController.addCallback(mStateListener, SysuiStatusBarStateController.RANK_STATUS_BAR); mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); mDreamManager = IDreamManager.Stub.asInterface( ServiceManager.checkService(DreamService.DREAM_SERVICE)); mDisplay = mContext.getDisplay(); mDisplayId = mDisplay.getDisplayId(); updateDisplaySize(); mStatusBarHideIconsForBouncerManager.setDisplayId(mDisplayId); // start old BaseStatusBar.start(). mWindowManagerService = WindowManagerGlobal.getWindowManagerService(); mDevicePolicyManager = (DevicePolicyManager) mContext.getSystemService( Context.DEVICE_POLICY_SERVICE); mAccessibilityManager = (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController); mBarService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE); mWallpaperSupported = mWallpaperManager.isWallpaperSupported(); RegisterStatusBarResult result = null; try { result = mBarService.registerStatusBar(mCommandQueue); } catch (RemoteException ex) { ex.rethrowFromSystemServer(); } 将statusBar加入窗口 createAndAddWindows(result); if (mWallpaperSupported) { // Make sure we always have the most current wallpaper info. IntentFilter wallpaperChangedFilter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED); mBroadcastDispatcher.registerReceiver(mWallpaperChangedReceiver, wallpaperChangedFilter, null /* handler */, UserHandle.ALL); mWallpaperChangedReceiver.onReceive(mContext, null); } else if (DEBUG) { Log.v(TAG, "start(): no wallpaper service "); } // Set up the initial notification state. This needs to happen before CommandQueue.disable() setUpPresenter(); if (containsType(result.mTransientBarTypes, ITYPE_STATUS_BAR)) { showTransientUnchecked(); } mCommandQueueCallbacks.onSystemBarAttributesChanged(mDisplayId, result.mAppearance, result.mAppearanceRegions, result.mNavbarColorManagedByIme, result.mBehavior, result.mRequestedVisibilities, result.mPackageName); // StatusBarManagerService has a back up of IME token and it's restored here. mCommandQueueCallbacks.setImeWindowStatus(mDisplayId, result.mImeToken, result.mImeWindowVis, result.mImeBackDisposition, result.mShowImeSwitcher); // Set up the initial icon state int numIcons = result.mIcons.size(); for (int i = 0; i < numIcons; i++) { mCommandQueue.setIcon(result.mIcons.keyAt(i), result.mIcons.valueAt(i)); } if (DEBUG) { Log.d(TAG, String.format( "init: icons=%d disabled=0x%08x lights=0x%08x imeButton=0x%08x", numIcons, result.mDisabledFlags1, result.mAppearance, result.mImeWindowVis)); } IntentFilter internalFilter = new IntentFilter(); internalFilter.addAction(BANNER_ACTION_CANCEL); internalFilter.addAction(BANNER_ACTION_SETUP); mContext.registerReceiver(mBannerActionBroadcastReceiver, internalFilter, PERMISSION_SELF, null); if (mWallpaperSupported) { IWallpaperManager wallpaperManager = IWallpaperManager.Stub.asInterface( ServiceManager.getService(Context.WALLPAPER_SERVICE)); try { wallpaperManager.setInAmbientMode(false /* ambientMode */, 0L /* duration */); } catch (RemoteException e) { // Just pass, nothing critical. } } // end old BaseStatusBar.start(). // Lastly, call to the icon policy to install/update all the icons. mIconPolicy.init(); mKeyguardStateController.addCallback(new KeyguardStateController.Callback() { @Override public void onUnlockedChanged() { updateKeyguardState(); logStateToEventlog(); } }); startKeyguard(); mKeyguardUpdateMonitor.registerCallback(mUpdateCallback); mDozeServiceHost.initialize( this, mStatusBarKeyguardViewManager, mNotificationShadeWindowViewController, mNotificationPanelViewController, mAmbientIndicationContainer); updateLightRevealScrimVisibility(); mConfigurationController.addCallback(mConfigurationListener); mBatteryController.observe(mLifecycle, mBatteryStateChangeCallback); mLifecycle.setCurrentState(RESUMED); mAccessibilityFloatingMenuController.init(); // set the initial view visibility int disabledFlags1 = result.mDisabledFlags1; int disabledFlags2 = result.mDisabledFlags2; mInitController.addPostInitTask( () -> setUpDisableFlags(disabledFlags1, disabledFlags2)); mFalsingManager.addFalsingBeliefListener(mFalsingBeliefListener); mPluginManager.addPluginListener( new PluginListener<OverlayPlugin>() { private final ArraySet<OverlayPlugin> mOverlays = new ArraySet<>(); @Override public void onPluginConnected(OverlayPlugin plugin, Context pluginContext) { mMainExecutor.execute( () -> plugin.setup(getNotificationShadeWindowView(), getNavigationBarView(), new Callback(plugin), mDozeParameters)); } @Override public void onPluginDisconnected(OverlayPlugin plugin) { mMainExecutor.execute(() -> { mOverlays.remove(plugin); mNotificationShadeWindowController .setForcePluginOpen(mOverlays.size() != 0, this); }); } class Callback implements OverlayPlugin.Callback { private final OverlayPlugin mPlugin; Callback(OverlayPlugin plugin) { mPlugin = plugin; } @Override public void onHoldStatusBarOpenChange() { if (mPlugin.holdStatusBarOpen()) { mOverlays.add(mPlugin); } else { mOverlays.remove(mPlugin); } mMainExecutor.execute(() -> { mNotificationShadeWindowController .setStateListener(b -> mOverlays.forEach( o -> o.setCollapseDesired(b))); mNotificationShadeWindowController .setForcePluginOpen(mOverlays.size() != 0, this); }); } } }, OverlayPlugin.class, true /* Allow multiple plugins */); mStartingSurfaceOptional.ifPresent(startingSurface -> startingSurface.setSysuiProxy( (requestTopUi, componentTag) -> mMainExecutor.execute(() -> mNotificationShadeWindowController.setRequestTopUi( requestTopUi, componentTag)))); }
public void createAndAddWindows(@Nullable RegisterStatusBarResult result) { 创建StatusBar的视图 makeStatusBarView(result); mNotificationShadeWindowController.attach(); mStatusBarWindowController.attach(); }
protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) { updateDisplaySize(); // populates mDisplayMetrics updateResources(); updateTheme(); 加载StatusBar的布局文件 inflateStatusBarWindow(); }
包含status_bar_container 的framelayout的容器即为状态栏的view,在代码中通过fragmentmanager替换了了这个container。
protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) { ... FragmentHostManager.get(mStatusBarWindow) .addTagListener(...).getFragmentManager() .beginTransaction() .replace(R.id.status_bar_container, new CollapsedStatusBarFragment(), CollapsedStatusBarFragment.TAG) .commit();
而CollapsedStatusBarFragment的实现就是加载了status_bar.xml 这个布局。
@Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.status_bar, container, false); }
status_bar.xml 布局内容就是显示出来的状态栏布局。这样状态栏整体布局就比较清晰,包含了应用通知,系统图标, 时钟,电池等
(366条消息) Android系统状态栏定制_android 设置状态栏-CSDN博客
(366条消息) 什么是SystemUI?简单分析_Jason_Lee155的博客-CSDN博客