读取SystemUI核心组件(不再通过config.xml):
- SystemUIService调用SystemUIApplication的startSystemUserServicesIfNeeded()
- 通过 Dagger 组件 (
mSysUIComponent) 获取所有标注好的CoreStartable实现类。 - 通过 Dagger 的
@Binds注解自动注入到getStartables()集合中。
scss
//frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@Override
public void onCreate() {
super.onCreate();
//android12调用的是startServicesIfNeeded
// Start all of SystemUI
((SystemUIApplication) getApplication()).startSystemUserServicesIfNeeded();
...
}
//frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java)
public void startSystemUserServicesIfNeeded() {
if (!shouldStartSystemUserServices()) {
return;
}
//SystemUIInitializer mInitializer;
final String vendorComponent = mInitializer.getVendorComponent(getResources());
// Sort the startables so that we get a deterministic ordering.
// TODO: make #start idempotent and require users of CoreStartable to call it.
Map<Class<?>, Provider<CoreStartable>> sortedStartables = new TreeMap<>(
Comparator.comparing(Class::getName));
//全局核心服务
sortedStartables.putAll(mSysUIComponent.getStartables());
//用户核心服务
sortedStartables.putAll(mSysUIComponent.getPerUserStartables());
startServicesIfNeeded(
sortedStartables, "StartServices", vendorComponent);
}
真正启动组件:
- 遍历
sortedStartables列表,依次调用每个CoreStartable的start()方法。 - 处理传入的
vendorComponent字符串,通过反射机制实例化并启动这个厂商自定义组件。
ini
//frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java)
private void startServicesIfNeeded(
Map<Class<?>, Provider<CoreStartable>> startables,
String metricsPrefix,
String vendorComponent) {
if (mServicesStarted) {
return;
}
mServices = new CoreStartable[startables.size() + (vendorComponent == null ? 0 : 1)];
if (!mBootCompleteCache.isBootComplete()) {
// check to see if maybe it was already completed long before we began
// see ActivityManagerService.finishBooting()
if ("1".equals(getRootComponent().getSystemPropertiesHelper()
.get("sys.boot_completed"))) {
mBootCompleteCache.setBootComplete();
if (DEBUG) {
Log.v(TAG, "BOOT_COMPLETED was already sent");
}
}
}
DumpManager dumpManager = mSysUIComponent.createDumpManager();
Log.v(TAG, "Starting SystemUI services for user " +
Process.myUserHandle().getIdentifier() + ".");
TimingsTraceLog log = new TimingsTraceLog("SystemUIBootTiming",
Trace.TRACE_TAG_APP);
log.traceBegin(metricsPrefix);
HashSet<Class<?>> startedStartables = new HashSet<>();
// Perform a form of topological sort:
// 1) Iterate through a queue of all non-started startables
// If the startable has all of its dependencies met
// - start it
// Else
// - enqueue it for the next iteration
// 2) If anything was started and the "next" queue is not empty, loop back to 1
// 3) If we're done looping and there are any non-started startables left, throw an error.
//
// This "sort" is not very optimized. We assume that most CoreStartables don't have many
// dependencies - zero in fact. We assume two or three iterations of this loop will be
// enough. If that ever changes, it may be worth revisiting.
log.traceBegin("Topologically start Core Startables");
boolean startedAny = false;
ArrayDeque<Map.Entry<Class<?>, Provider<CoreStartable>>> queue;
ArrayDeque<Map.Entry<Class<?>, Provider<CoreStartable>>> nextQueue =
new ArrayDeque<>(startables.entrySet());
int numIterations = 0;
int serviceIndex = 0;
do {
startedAny = false;
queue = nextQueue;
nextQueue = new ArrayDeque<>(startables.size());
while (!queue.isEmpty()) {
Map.Entry<Class<?>, Provider<CoreStartable>> entry = queue.removeFirst();
Class<?> cls = entry.getKey();
Set<Class<? extends CoreStartable>> deps =
mSysUIComponent.getStartableDependencies().get(cls);
if (deps == null || startedStartables.containsAll(deps)) {
String clsName = cls.getName();
int i = serviceIndex; // Copied to make lambda happy.
timeInitialization(
clsName,
() -> mServices[i] = startStartable(clsName, entry.getValue()),
log,
metricsPrefix);
startedStartables.add(cls);
startedAny = true;
serviceIndex++;
} else {
nextQueue.add(entry);
}
}
numIterations++;
} while (startedAny && !nextQueue.isEmpty()); // if none were started, stop.
if (!nextQueue.isEmpty()) { // If some startables were left over, throw an error.
while (!nextQueue.isEmpty()) {
Map.Entry<Class<?>, Provider<CoreStartable>> entry = nextQueue.removeFirst();
Class<?> cls = entry.getKey();
Set<Class<? extends CoreStartable>> deps =
mSysUIComponent.getStartableDependencies().get(cls);
StringJoiner stringJoiner = new StringJoiner(", ");
for (Class<? extends CoreStartable> c : deps) {
if (!startedStartables.contains(c)) {
stringJoiner.add(c.getName());
}
}
Log.e(TAG, "Failed to start " + cls.getName()
+ ". Missing dependencies: [" + stringJoiner + "]");
}
throw new RuntimeException("Failed to start all CoreStartables. Check logcat!");
}
Log.i(TAG, "Topological CoreStartables completed in " + numIterations + " iterations");
log.traceEnd();
if (vendorComponent != null) {
timeInitialization(
vendorComponent,
() -> mServices[mServices.length - 1] =
startAdditionalStartable(vendorComponent),
log,
metricsPrefix);
}
for (serviceIndex = 0; serviceIndex < mServices.length; serviceIndex++) {
final CoreStartable service = mServices[serviceIndex];
if (mBootCompleteCache.isBootComplete()) {
notifyBootCompleted(service);
}
if (service.isDumpCritical()) {
dumpManager.registerCriticalDumpable(service);
} else {
dumpManager.registerNormalDumpable(service);
}
}
mSysUIComponent.getInitController().executePostInitTasks();
log.traceEnd();
mServicesStarted = true;
}
android16中StatusBar没有了,变成了CentralSurfacesImpl,不再继承SystemUI,改成了实现CoreStartable
启动状态栏,通知栏,导航栏
CentralSurfacesImpl
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java)
public void start() {
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
mWallpaperSupported = mWallpaperManager.isWallpaperSupported();
RegisterStatusBarResult result = null;
if (!StatusBarConnectedDisplays.isEnabled()) {
try {
//注册CommandQueue到StatusBarManagerService
result = mBarService.registerStatusBar(mCommandQueue);
} catch (RemoteException ex) {
ex.rethrowFromSystemServer();
}
}
//创建状态栏,导航栏,通知栏
createAndAddWindows(result);
//初始化通知栏状态
setUpPresenter();
// When the StatusBarConnectedDisplays flag is enabled, this logic will be done in
// StatusBarOrchestrator
if (!StatusBarConnectedDisplays.isEnabled()) {
if ((result.mTransientBarTypes & WindowInsets.Type.statusBars()) != 0) {
mStatusBarModeRepository.getDefaultDisplay().showTransient();
}
mCommandQueueCallbacks.onSystemBarAttributesChanged(
mDisplayId,
result.mAppearance,
result.mAppearanceRegions,
result.mNavbarColorManagedByIme,
result.mBehavior,
result.mRequestedVisibleTypes,
result.mPackageName,
result.mLetterboxDetails);
// StatusBarManagerService has a back up of IME token and it's restored here.
mCommandQueueCallbacks.setImeWindowStatus(
mDisplayId,
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 (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.
//初始化状态栏图标 PhoneStatusBarPolicy mIconPolicy
mIconPolicy.init();
startKeyguard();
mKeyguardUpdateMonitor.registerCallback(mUpdateCallback);
mDozeServiceHost.initialize(
this,
mStatusBarKeyguardViewManager,
getNotificationShadeWindowViewController(),
mAmbientIndicationContainer);
mStartingSurfaceOptional.ifPresent(startingSurface -> startingSurface.setSysuiProxy(
(requestTopUi, componentTag) -> mMainExecutor.execute(() ->
mNotificationShadeWindowController.setRequestTopUi(
requestTopUi, componentTag))));
}
注册CommandQueue到StatusBarManagerService,同时返回服务端保存的图标列表
StatusBarManagerService
//frameworks/base/services/core/java/com/android/server/statusbar/StatusBarManagerService.java)
public RegisterStatusBarResult registerStatusBar(IStatusBar bar) {
enforceStatusBarService();
enforceValidCallingUser();
Slog.i(TAG, "registerStatusBar bar=" + bar);
mBar = bar;
mDeathRecipient.linkToDeath();
notifyBarAttachChanged();
final ArrayMap<String, StatusBarIcon> icons;
synchronized (mIcons) {
icons = new ArrayMap<>(mIcons);
}
synchronized (mLock) {
final UiState state = mDisplayUiState.get(DEFAULT_DISPLAY);
return new RegisterStatusBarResult(icons, gatherDisableActionsLocked(mCurrentUserId, 1),
state.mAppearance, state.mAppearanceRegions, state.mImeWindowVis,
state.mImeBackDisposition, state.mShowImeSwitcher,
gatherDisableActionsLocked(mCurrentUserId, 2),
state.mNavbarColorManagedByIme, state.mBehavior, state.mRequestedVisibleTypes,
state.mPackageName, state.mTransientBarTypes, state.mLetterboxDetails);
}
}
PhoneStatusBarPolicy初始化状态栏图标入口
PhoneStatusBarPolicy:决定了哪些图标应在开机时加载到状态栏。它会根据系统状态(如蓝牙是否开启、是否有闹钟等)来显示和隐藏系统图标。StatusBar:SystemUI的主入口,负责初始化整体布局并实例。化PhoneStatusBarPolicy。StatusBarManagerService:系统服务,负责接收并管理来自各个应用的图标更新请求。IconManager:实际负责将StatusBarIconView添加到状态栏布局中。StatusBarIconView:负责单个图标的具体显示和更。StatusBarIconControllerImpl:作为中间层,将PhoneStatusBarPolicy的控制指令分发到具体的IconManager去执行。
StatusBarIconController实现类StatusBarIconControllerImpl,mIconController在构造函数中创建,创建的时候就会去加载配置的系统状态栏图标
scss
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java)
public void init() {
...
// TTY status
updateTTY();
// bluetooth status
updateBluetooth();
// Alarm clock
//private final StatusBarIconController mIconController;
//设置图标
mIconController.setIcon(mSlotAlarmClock, R.drawable.stat_sys_alarm, null);
mIconController.setIconVisibility(mSlotAlarmClock, false);
...
mCommandQueue.addCallback(this);
}
调用StatusBarIconControllerImpl设置状态栏图标资源,名字
scss
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerImpl.java
public void setIcon(String slot, int resourceId, CharSequence contentDescription) {
setResourceIconInternal(
slot,
Icon.createWithResource(mContext, resourceId),
/* preloadedIcon= */ null,
contentDescription,
StatusBarIcon.Type.SystemIcon,
StatusBarIcon.Shape.WRAP_CONTENT);
}
private void setResourceIconInternal(String slot, Icon resourceIcon,
@Nullable Drawable preloadedIcon, CharSequence contentDescription,
StatusBarIcon.Type type, StatusBarIcon.Shape shape) {
checkArgument(resourceIcon.getType() == Icon.TYPE_RESOURCE,
"Expected Icon of TYPE_RESOURCE, but got " + resourceIcon.getType());
String resPackage = resourceIcon.getResPackage();
if (TextUtils.isEmpty(resPackage)) {
resPackage = mContext.getPackageName();
}
StatusBarIconHolder holder = mStatusBarIconList.getIconHolder(slot, 0);
if (holder == null) {
StatusBarIcon icon = new StatusBarIcon(UserHandle.SYSTEM, resPackage,
resourceIcon, /* iconLevel= */ 0, /* number=*/ 0,
contentDescription, type, shape);
icon.preloadedIcon = preloadedIcon;
holder = StatusBarIconHolder.fromIcon(icon);
setIcon(slot, holder);
} else {
holder.getIcon().pkg = resPackage;
holder.getIcon().icon = resourceIcon;
holder.getIcon().contentDescription = contentDescription;
holder.getIcon().type = type;
holder.getIcon().shape = shape;
holder.getIcon().preloadedIcon = preloadedIcon;
handleSet(slot, holder);
}
}
public void setIcon(int index, @NonNull StatusBarIconHolder holder) {
boolean isNew = mStatusBarIconList.getIconHolder(slot, holder.getTag()) == null;
mStatusBarIconList.setIcon(slot, holder);
if (isNew) {
addSystemIcon(slot, holder);
} else {
handleSet(slot, holder);
}
}
private void addSystemIcon(String slot, StatusBarIconHolder holder) {
int viewIndex = mStatusBarIconList.getViewIndex(slot, holder.getTag());
boolean hidden = mIconHideList.contains(slot);
//private final ArrayList<IconManager> mIconGroups = new ArrayList<>();
//回调IconManager的onIconAdded()
mIconGroups.forEach(l -> l.onIconAdded(viewIndex, slot, hidden, holder));
}
private void handleSet(String slotName, StatusBarIconHolder holder) {
int viewIndex = mStatusBarIconList.getViewIndex(slotName, holder.getTag());
//private final ArrayList<IconManager> mIconGroups = new ArrayList<>();
//回调IconManager的onSetIconHolder()
mIconGroups.forEach(l -> l.onSetIconHolder(viewIndex, holder));
}
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/ui/IconManager.java.java)
protected void onIconAdded(int index, String slot, boolean blocked,
StatusBarIconHolder holder) {
addHolder(index, slot, blocked, holder);
}
protected StatusIconDisplayable addHolder(int index, String slot, boolean blocked,
StatusBarIconHolder holder) {
// This is a little hacky, and probably regrettable, but just set `blocked` on any icon
// that is in our blocked list, then we'll never see it
if (mBlockList.contains(slot)) {
blocked = true;
}
return switch (holder.getType()) {
case TYPE_ICON -> addIcon(index, slot, blocked, holder.getIcon());
case TYPE_WIFI_NEW -> addNewWifiIcon(index, slot);
case TYPE_MOBILE_NEW -> addNewMobileIcon(index, slot, holder.getTag());
case TYPE_BINDABLE ->
// Safe cast, since only BindableIconHolders can set this tag on themselves
addBindableIcon((BindableIconHolder) holder, index);
default -> null;
};
}
public void onSetIconHolder(int viewIndex, StatusBarIconHolder holder) {
switch (holder.getType()) {
case TYPE_ICON:
onSetIcon(viewIndex, holder.getIcon());
return;
case TYPE_MOBILE_NEW:
case TYPE_WIFI_NEW:
case TYPE_BINDABLE:
// Nothing, the new icons update themselves
return;
default:
break;
}
}
public void onSetIcon(int viewIndex, StatusBarIcon icon) {
StatusBarIconView view = (StatusBarIconView) mGroup.getChildAt(viewIndex);
if (ModesUiIcons.isEnabled()) {
ViewGroup.LayoutParams current = view.getLayoutParams();
ViewGroup.LayoutParams desired = onCreateLayoutParams(icon.shape);
if (desired.width != current.width || desired.height != current.height) {
view.setLayoutParams(desired);
}
}
view.set(icon);
}
状态栏图标列表配置在config.xml 中的 config_statusBarIcons 数组,StatusBarIconControllerImpl的构造函数中初始化StatusBarIconList的时候通过Dagger注入
scss
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java)
@Inject
public StatusBarIconControllerImpl(
Context context,
CommandQueue commandQueue,
DemoModeController demoModeController,
ConfigurationController configurationController,
TunerService tunerService,
DumpManager dumpManager,
StatusBarIconList statusBarIconList,
StatusBarPipelineFlags statusBarPipelineFlags,
BindableIconsRegistry modernIconsRegistry
) {
mStatusBarIconList = statusBarIconList;
mContext = context;
mStatusBarPipelineFlags = statusBarPipelineFlags;
configurationController.addCallback(this);
commandQueue.addCallback(mCommandQueueCallbacks);
tunerService.addTunable(this, ICON_HIDE_LIST);
demoModeController.addCallback(this);
dumpManager.registerDumpable(getClass().getSimpleName(), this);
addModernBindableIcons(modernIconsRegistry);
}
}
//状态栏图标列表
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
@Provides
@SysUISingleton
static StatusBarIconList provideStatusBarIconList(Context context) {
return new StatusBarIconList(
context.getResources().getStringArray(
com.android.internal.R.array.config_statusBarIcons));
}
创建状态栏,通知栏,导航栏
less
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java)
public void createAndAddWindows(@Nullable RegisterStatusBarResult result) { //1.创建状态栏,导航栏,通知栏View
makeStatusBarView(result);
//2.通过WindowManager.addView 添加通知栏窗口
mNotificationShadeWindowController.attach();
//当未启用新多屏功能时,通过 Store 获取默认显示屏的控制器
//3.通过WindowManager.addView 添加状态栏窗口
if (!StatusBarConnectedDisplays.isEnabled()) {
mStatusBarWindowControllerStore.getDefaultDisplay().attach();
}
}
创建状态栏,导航栏,通知栏View
scss
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java)
protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
...
setUpShade();
getNotificationShadeWindowView().setOnTouchListener(getStatusBarWindowTouchListener());
mWallpaperController.setRootView(getNotificationShadeWindowView());
mDemoModeController.addCallback(mDemoModeCallback);
// When the StatusBarConnectedDisplays flag is enabled, this logic will be done in
// StatusBarOrchestrator.
if (!StatusBarConnectedDisplays.isEnabled()) {
mJavaAdapter.alwaysCollectFlow(
mStatusBarModeRepository.getDefaultDisplay().isTransientShown(),
this::onTransientShownChanged);
mJavaAdapter.alwaysCollectFlow(
mStatusBarModeRepository.getDefaultDisplay().getStatusBarMode(),
this::updateBarMode);
}
mCommandQueueCallbacks = mCommandQueueCallbacksLazy.get();
mCommandQueue.addCallback(mCommandQueueCallbacks);
// TODO: Deal with the ugliness that comes from having some of the status bar broken out
// into fragments, but the rest here, it leaves some awkward lifecycle and whatnot.
ShadeExpansionChangeEvent currentState =
mShadeExpansionStateManager.addExpansionListener(mWakeUpCoordinator);
mWakeUpCoordinator.onPanelExpansionChanged(currentState);
// When the StatusBarConnectedDisplays flag is enabled, all this logic will be done in
// StatusBarOrchestrator.
if (!StatusBarConnectedDisplays.isEnabled()) {
// Allow plugins to reference DarkIconDispatcher and StatusBarStateController
mPluginDependencyProvider.allowPluginDependency(DarkIconDispatcher.class);
mPluginDependencyProvider.allowPluginDependency(StatusBarStateController.class);
// Set up CollapsedStatusBarFragment and PhoneStatusBarView
mStatusBarInitializer.setStatusBarViewUpdatedListener(
(statusBarViewController, statusBarTransitions) -> {
mPhoneStatusBarViewController = statusBarViewController;
mStatusBarTransitions = statusBarTransitions;
getNotificationShadeWindowViewController()
.setStatusBarViewController(mPhoneStatusBarViewController);
// Ensure we re-propagate panel expansion values to the panel controller and
// any listeners it may have, such as PanelBar. This will also ensure we
// re-display the notification panel if necessary (for example, if
// a heads-up notification was being displayed and should continue being
// displayed).
mShadeSurface.updateExpansionAndVisibility();
setBouncerShowingForStatusBarComponents(mBouncerShowing);
checkBarModes();
});
}
if (!StatusBarRootModernization.isEnabled() && !StatusBarConnectedDisplays.isEnabled()) {
// When the flag is on, we register the fragment as a core startable and this is not
// needed
mStatusBarInitializer.initializeStatusBar();
}
mShadeTouchableRegionManager.setup(getNotificationShadeWindowView());
if (!StatusBarConnectedDisplays.isEnabled()) {
createNavigationBar(result);
}
mAmbientIndicationContainer = getNotificationShadeWindowView().findViewById(
R.id.ambient_indication_container);
// When the StatusBarConnectedDisplays flag is enabled, all this logic will be done in
// StatusBarOrchestrator.
if (!StatusBarConnectedDisplays.isEnabled()) {
mAutoHideController.setStatusBar(
new AutoHideUiElement() {
@Override
public void synchronizeState() {
checkBarModes();
}
@Override
public boolean shouldHideOnTouch() {
return !mRemoteInputManager.isRemoteInputActive();
}
@Override
public boolean isVisible() {
return isTransientShown();
}
@Override
public void hide() {
mStatusBarModeRepository.getDefaultDisplay().clearTransient();
}
});
}
ScrimView scrimBehind = getNotificationShadeWindowView().findViewById(R.id.scrim_behind);
ScrimView notificationsScrim = getNotificationShadeWindowView()
.findViewById(R.id.scrim_notifications);
ScrimView scrimInFront = getNotificationShadeWindowView().findViewById(R.id.scrim_in_front);
mScrimController.setScrimVisibleListener(scrimsVisible -> {
mNotificationShadeWindowController.setScrimsVisibility(scrimsVisible);
});
mScrimController.attachViews(scrimBehind, notificationsScrim, scrimInFront);
mLightRevealScrim.setScrimOpaqueChangedListener((opaque) -> {
Runnable updateOpaqueness = () -> {
mNotificationShadeWindowController.setLightRevealScrimOpaque(
mLightRevealScrim.isScrimOpaque());
mScreenOffAnimationController
.onScrimOpaqueChanged(mLightRevealScrim.isScrimOpaque());
};
if (opaque) {
// Delay making the view opaque for a frame, because it needs some time to render
// otherwise this can lead to a flicker where the scrim doesn't cover the screen
mLightRevealScrim.post(updateOpaqueness);
} else {
updateOpaqueness.run();
}
});
mScreenOffAnimationController.initialize(this, mShadeSurface, mLightRevealScrim);
if (!SceneContainerFlag.isEnabled()) {
mShadeSurface.initDependencies(
this,
mGestureRec,
mShadeController::makeExpandedInvisible,
mHeadsUpManager);
}
// Set up the quick settings tile panel
final View container = getNotificationShadeWindowView().findViewById(R.id.qs_frame);
if (container != null && !SceneContainerFlag.isEnabled()) {
FragmentHostManager fragmentHostManager =
mFragmentService.getFragmentHostManager(container);
ExtensionFragmentListener.attachExtensonToFragment(
mFragmentService,
container,
QS.TAG,
R.id.qs_frame,
mExtensionController
.newExtension(QS.class)
.withPlugin(QS.class)
.withDefault(this::createDefaultQSFragment)
.build());
mBrightnessMirrorController = new BrightnessMirrorController(
getNotificationShadeWindowView(),
mShadeSurface,
mNotificationShadeDepthControllerLazy.get(),
mBrightnessSliderFactory,
this::setBrightnessMirrorShowing);
fragmentHostManager.addTagListener(QS.TAG, (tag, f) -> {
QS qs = (QS) f;
if (qs instanceof QSFragmentLegacy) {
QSFragmentLegacy qsFragment = (QSFragmentLegacy) qs;
mQSPanelController = qsFragment.getQSPanelController();
qsFragment.setBrightnessMirrorController(mBrightnessMirrorController);
}
});
}
mReportRejectedTouch = getNotificationShadeWindowView()
.findViewById(R.id.report_rejected_touch);
if (mReportRejectedTouch != null) {
updateReportRejectedTouchVisibility();
mReportRejectedTouch.setOnClickListener(v -> {
Uri session = mFalsingManager.reportRejectedTouch();
if (session == null) { return; }
StringWriter message = new StringWriter();
message.write("Build info: ");
message.write(SystemProperties.get("ro.build.description"));
message.write("\nSerial number: ");
message.write(SystemProperties.get("ro.serialno"));
message.write("\n");
if (!mPowerManager.isInteractive()) {
mBroadcastReceiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF));
}
mGestureWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
"sysui:GestureWakeLock");
// receive broadcasts
registerBroadcastReceiver();
// listen for USER_SETUP_COMPLETE setting (per-user)
mDeviceProvisionedController.addCallback(mUserSetupObserver);
mUserSetupObserver.onUserSetupChanged();
// disable profiling bars, since they overlap and clutter the output on app windows
ThreadedRenderer.overrideProperty("disableProfileBars", "true");
// Private API call to make the shadows look better for Recents
ThreadedRenderer.overrideProperty("ambientRatio", String.valueOf(1.5f));
}
//https://xrefandroid.com/android-16.0.0_r2/xref/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
private void setUpShade() {
mNotificationShadeWindowController.fetchWindowRootView();
getNotificationShadeWindowViewController().setupExpandedStatusBar();
getNotificationShadeWindowViewController().setupCommunalHubLayout();
}
//https://xrefandroid.com/android-16.0.0_r2/xref/frameworks/base/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
public void fetchWindowRootView() {
309 WindowRootViewComponent component = mWindowRootViewComponentFactory.create();
310 mWindowRootView = component.getWindowRootView();
311 collectFlow(
312 mWindowRootView,
313 mShadeInteractorLazy.get().isAnyExpanded(),
314 this::onShadeOrQsExpanded
315 );
316 collectFlow(
317 mWindowRootView,
318 mShadeInteractorLazy.get().isQsExpanded(),
319 this::onQsExpansionChanged
320 );
321 collectFlow(
322 mWindowRootView,
323 mCommunalInteractor.get().isCommunalVisible(),
324 this::onCommunalVisibleChanged
325 );
326
327 if (!SceneContainerFlag.isEnabled() && Flags.useTransitionsForKeyguardOccluded()) {
328 collectFlow(
329 mWindowRootView,
330 mNotificationShadeWindowModel.isKeyguardOccluded(),
331 this::setKeyguardOccluded
332 );
333 }
334 if (ComposeBouncerFlags.INSTANCE.isComposeBouncerOrSceneContainerEnabled()) {
335 collectFlow(mWindowRootView, mNotificationShadeWindowModel.isBouncerShowing(),
336 this::setBouncerShowing);
337 collectFlow(mWindowRootView, mNotificationShadeWindowModel.getDoesBouncerRequireIme(),
338 this::setKeyguardNeedsInput);
339 }
340 }
添加通知栏窗口
NotificationShadeWindowControllerImpl
//https://xrefandroid.com/android-16.0.0_r2/xref/frameworks/base/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
public void attach() {
// Now that the notification shade encompasses the sliding panel and its
// translucent backdrop, the entire thing is made TRANSLUCENT and is
// hardware-accelerated.
// mLP is assigned here (instead of the constructor) as its null value is also used to check
// if the shade window has been attached.
mLp = mShadeWindowLayoutParams;
mWindowManager.addView(mWindowRootView, mLp);
// We use BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE here, however, there is special logic in
// window manager which disables the transient show behavior.
// TODO: Clean this up once that behavior moves into the Shell.
if (mWindowRootView.getWindowInsetsController() != null) {
mWindowRootView.getWindowInsetsController().setSystemBarsBehavior(
BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
}
mLpChanged.copyFrom(mLp);
onThemeChanged();
// Make the state consistent with KeyguardViewMediator#setupLocked during initialization.
if (mKeyguardViewMediator.isShowingAndNotOccluded()) {
setKeyguardShowing(true);
}
}
添加状态栏窗口
StatusBarWindowControllerImpl
//https://xrefandroid.com/android-16.0.0_r2/xref/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerImpl.java
public void attach() {
if (StatusBarConnectedDisplays.isEnabled()) {
mStatusBarWindowView.setStatusBarConfigurationController(
mStatusBarConfigurationController);
}
// Now that the status bar window encompasses the sliding panel and its
// translucent backdrop, the entire thing is made TRANSLUCENT and is
// hardware-accelerated.
Trace.beginSection("StatusBarWindowController.getBarLayoutParams");
mLp = getBarLayoutParams(mContext.getDisplay().getRotation());
Trace.endSection();
try {
mWindowManager.addView(mStatusBarWindowView, mLp);
} catch (WindowManager.InvalidDisplayException e) {
// Wrapping this in a try/catch to avoid crashes when a display is instantly removed
// after being added, and initialization hasn't finished yet.
Log.e(
TAG,
"Unable to add view to WindowManager. Display with id "
+ mContext.getDisplayId()
+ " doesn't exist anymore.",
e);
}
mLpChanged.copyFrom(mLp);
mContentInsetsProvider.addCallback(this::calculateStatusBarLocationsForAllRotations);
calculateStatusBarLocationsForAllRotations();
mIsAttached = true;
apply(mCurrentState);
}