- SystemUI是一个系统级的app,我们常用的状态栏,导航栏,通知栏,锁屏,recents等等都是包含在这个应用里的。
- 我们这里先按照启动流程分析下相关的ui都是如何添加到屏幕的。
- 注意一下,这个app是没有默认的启动页面的。
1.SystemUI咋启动的
这里就要提到SystemServer了,这个server的启动流程,网上很多,可以自己查下资料
1.1.SystemServer
frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
>1.run
下边是run方法里的核心代码
//初始化系统上下文,补充2
createSystemContext();
// Call per-process mainline module initialization.
ActivityThread.initializeMainlineModules();
// Sets the dumper service
ServiceManager.addService("system_server_dumper", mDumper);
mDumper.addDumpable(this);
// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart,
mRuntimeStartElapsedTime, mRuntimeStartUptime);
mDumper.addDumpable(mSystemServiceManager);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Prepare the thread pool for init tasks that can be parallelized
SystemServerInitThreadPool tp = SystemServerInitThreadPool.start();
mDumper.addDumpable(tp);
//...
// Start services.
try {
startBootstrapServices(t);
startCoreServices(t);
startOtherServices(t);//补充3
startApexServices(t);
} catch (Throwable ex) {
>2.createSystemContext
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();//参考1.2
mSystemContext = activityThread.getSystemContext();//参考1.2.3
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
final Context systemUiContext = activityThread.getSystemUiContext();
systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
>3.startOtherServices
try {
startSystemUi(context, windowManagerF);//参考1.3
}
1.2.ActivityThread
>1.systemMain
创建系统主线程
public static ActivityThread systemMain() {
ThreadedRenderer.initForSystemProcess();
ActivityThread thread = new ActivityThread();
thread.attach(true, 0);//补充2
return thread;
}
>2.attach(true,0)
} else {
// Don't set application object here -- if the system crashes,
// we can't display an alert, we just want to die die die.
android.ddm.DdmHandleAppName.setAppName("system_process",
UserHandle.myUserId());
try {
mInstrumentation = new Instrumentation();
mInstrumentation.basicInit(this);
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplicationInner(true, null);
mInitialApplication.onCreate();
}
}
>3.getSystemContext
public ContextImpl getSystemContext() {
synchronized (this) {
if (mSystemContext == null) {
mSystemContext = ContextImpl.createSystemContext(this);//补充4
}
return mSystemContext;
}
}
>4.getSystemContext
ContextImpl.java
static ContextImpl createSystemContext(ActivityThread mainThread) {
LoadedApk packageInfo = new LoadedApk(mainThread);
ContextImpl context = new ContextImpl(null, mainThread, packageInfo,
ContextParams.EMPTY, null, null, null, null, null, 0, null, null);
context.setResources(packageInfo.getResources());
context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
context.mResourcesManager.getDisplayMetrics());
context.mContextType = CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI;
return context;
}
1.3.startSystemUi方法
这里是启动了SystemUI的service
private static void startSystemUi(Context context, WindowManagerService windowManager) {
PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
Intent intent = new Intent();
intent.setComponent(pm.getSystemUiServiceComponent());//补充2
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
context.startServiceAsUser(intent, UserHandle.SYSTEM);
windowManager.onSystemUiStarted();
}
>1.PackageManagerInternal来源
PackageManagerService的构造方法里有添加PackageManagerInternalImpl的实例
LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
>2.getSystemUiServiceComponent
- packageManagerInternal的子类,也是PackageManagerInternalImpl的父类
- frameworks/base/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
public final ComponentName getSystemUiServiceComponent() {
return ComponentName.unflattenFromString(getContext().getResources().getString(
com.android.internal.R.string.config_systemUIServiceComponent));
}
字符串内容
<!-- SystemUi service component -->
<string name="config_systemUIServiceComponent" translatable="false"
>com.android.systemui/com.android.systemui.SystemUIService</string>
2.SystemUIAppComponentFactory
- Activity,Service,Broadcast 交给mComponentHelper来实例化
- Application,ContentProvider还是父类来实例化,完事进行了一些额外的初始化操作
public class SystemUIAppComponentFactory extends AppComponentFactory {
@Inject
public ContextComponentHelper mComponentHelper;//注解生成的
2.1.清单文件
- appComponentFactory是自定义的,也就是说SystemUI的四大组件都是这个自定义的工厂类来实例化的
<application
android:name=".SystemUIApplication"
android:persistent="true"
android:allowClearUserData="false"
android:backupAgent=".backup.BackupHelper"
android:killAfterRestore="false"
android:hardwareAccelerated="true"
android:label="@string/app_label"
android:icon="@drawable/icon"
android:process="com.android.systemui"
android:supportsRtl="true"
android:theme="@style/Theme.SystemUI"
android:defaultToDeviceProtectedStorage="true"
android:directBootAware="true"
android:appComponentFactory=".SystemUIAppComponentFactory">
2.2.instantiateApplicationCompat
public Application instantiateApplicationCompat(
@NonNull ClassLoader cl, @NonNull String className)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
Application app = super.instantiateApplicationCompat(cl, className);
//如果实现了这个接口,就设置对应的回调
if (app instanceof ContextInitializer) {
((ContextInitializer) app).setContextAvailableCallback(
context -> {
//参考2.7.1
SystemUIFactory.createFromConfig(context);
//给SysUIComponent注入当前对象
SystemUIFactory.getInstance().getSysUIComponent().inject(
SystemUIAppComponentFactory.this);
}
);
}
return app;
}
2.3.instantiateProviderCompat
public ContentProvider instantiateProviderCompat(
@NonNull ClassLoader cl, @NonNull String className)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
ContentProvider contentProvider = super.instantiateProviderCompat(cl, className);
//如果实现了这个接口,就设置对应的回调
if (contentProvider instanceof ContextInitializer) {
((ContextInitializer) contentProvider).setContextAvailableCallback(
context -> {
SystemUIFactory.createFromConfig(context);
SysUIComponent rootComponent =
SystemUIFactory.getInstance().getSysUIComponent();
try {
//给SysUIComponent注入contentProvider
Method injectMethod = rootComponent.getClass()
.getMethod("inject", contentProvider.getClass());
injectMethod.invoke(rootComponent, contentProvider);
}
}
);
}
return contentProvider;
}
2.4.instantiateActivityCompat
public Activity instantiateActivityCompat(@NonNull ClassLoader cl, @NonNull String className,
@Nullable Intent intent)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
if (mComponentHelper == null) {
//正常情况不应该走这里
SystemUIFactory.getInstance().getSysUIComponent().inject(
SystemUIAppComponentFactory.this);
}
//通过helper类创建activity
Activity activity = mComponentHelper.resolveActivity(className);
if (activity != null) {
return activity;
}
//失败再走默认的方法
return super.instantiateActivityCompat(cl, className, intent);
}
2.5.instantiateServiceCompat
public Service instantiateServiceCompat(
@NonNull ClassLoader cl, @NonNull String className, Intent intent)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
if (mComponentHelper == null) {
SystemUIFactory.getInstance().getSysUIComponent().inject(
SystemUIAppComponentFactory.this);
}
//同样交给helper类创建服务,失败再走默认的方法
Service service = mComponentHelper.resolveService(className);
if (service != null) {
return service;
}
return super.instantiateServiceCompat(cl, className, intent);
}
2.6.instantiateReceiverCompat
public BroadcastReceiver instantiateReceiverCompat(@NonNull ClassLoader cl,
@NonNull String className, @Nullable Intent intent)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
if (mComponentHelper == null) {
SystemUIFactory.getInstance().getSysUIComponent().inject(
SystemUIAppComponentFactory.this);
}
//同样交给helper类创建广播对象,失败再走默认的方法
BroadcastReceiver receiver = mComponentHelper.resolveBroadcastReceiver(className);
if (receiver != null) {
return receiver;
}
return super.instantiateReceiverCompat(cl, className, intent);
}
2.7.SystemUIFactory
>1.getInstance
单例默认
static SystemUIFactory mFactory;
public static <T extends SystemUIFactory> T getInstance() {
return (T) mFactory;
}
>2.createFromConfig
2.2或者2.3会调用
public static void createFromConfig(Context context) {
createFromConfig(context, false);
}
public static void createFromConfig(Context context, boolean fromTest) {
if (mFactory != null) {
return;
}
final String clsName = context.getString(R.string.config_systemUIFactoryComponent);
if (clsName == null || clsName.length() == 0) {
throw new RuntimeException("No SystemUIFactory component configured");
}
try {
Class<?> cls = null;
cls = context.getClassLoader().loadClass(clsName);
mFactory = (SystemUIFactory) cls.newInstance();
mFactory.init(context, fromTest);
}
}
<!-- SystemUIFactory component -->
<string name="config_systemUIFactoryComponent" >com.android.systemui.SystemUIInitializerImpl</string>
>3.init
public void init(Context context, boolean fromTest)
throws ExecutionException, InterruptedException {
//只有在主系统进程,系统用户的情况下初始化组件
mInitializeComponents = !fromTest
&& android.os.Process.myUserHandle().isSystem()
&& ActivityThread.currentProcessName().equals(ActivityThread.currentPackageName());
//补充4
mRootComponent = buildGlobalRootComponent(context);
// 启动 WMComponent,补充5
setupWmComponent(context);
if (mInitializeComponents) {
//
mWMComponent.init();
}
//
SysUIComponent.Builder builder = mRootComponent.getSysUIComponent();
if (mInitializeComponents) {
builder = prepareSysUIComponentBuilder(builder, mWMComponent)
.setPip(mWMComponent.getPip())
.setLegacySplitScreen(mWMComponent.getLegacySplitScreen())
.setSplitScreen(mWMComponent.getSplitScreen())
.setOneHanded(mWMComponent.getOneHanded())
.setBubbles(mWMComponent.getBubbles())
.setHideDisplayCutout(mWMComponent.getHideDisplayCutout())
.setShellCommandHandler(mWMComponent.getShellCommandHandler())
.setAppPairs(mWMComponent.getAppPairs())
.setTaskViewFactory(mWMComponent.getTaskViewFactory())
.setTransitions(mWMComponent.getTransitions())
.setStartingSurface(mWMComponent.getStartingSurface())
.setDisplayAreaHelper(mWMComponent.getDisplayAreaHelper())
.setTaskSurfaceHelper(mWMComponent.getTaskSurfaceHelper())
.setRecentTasks(mWMComponent.getRecentTasks())
.setCompatUI(mWMComponent.getCompatUI())
.setDragAndDrop(mWMComponent.getDragAndDrop())
.setBackAnimation(mWMComponent.getBackAnimation());
} else {//不需要初始化,设置数据都是空
builder = prepareSysUIComponentBuilder(builder, mWMComponent)
.setPip(Optional.ofNullable(null))
.setLegacySplitScreen(Optional.ofNullable(null))
.setSplitScreen(Optional.ofNullable(null))
.setOneHanded(Optional.ofNullable(null))
.setBubbles(Optional.ofNullable(null))
.setHideDisplayCutout(Optional.ofNullable(null))
.setShellCommandHandler(Optional.ofNullable(null))
.setAppPairs(Optional.ofNullable(null))
.setTaskViewFactory(Optional.ofNullable(null))
.setTransitions(new ShellTransitions() {})
.setDisplayAreaHelper(Optional.ofNullable(null))
.setStartingSurface(Optional.ofNullable(null))
.setTaskSurfaceHelper(Optional.ofNullable(null))
.setRecentTasks(Optional.ofNullable(null))
.setCompatUI(Optional.ofNullable(null))
.setDragAndDrop(Optional.ofNullable(null))
.setBackAnimation(Optional.ofNullable(null));
}
mSysUIComponent = builder.build();
if (mInitializeComponents) {
mSysUIComponent.init();
}
//
Dependency dependency = mSysUIComponent.createDependency();
dependency.start();
}
>4.buildGlobalRootComponent
- DaggerGlobalRootComponent源码里没有这个类的,这是dagger库自动生成的,原本接口是GlobalRootComponent
protected GlobalRootComponent buildGlobalRootComponent(Context context) {
return DaggerGlobalRootComponent.builder()
.context(context)
.build();
}
>5.setupWmComponent
private void setupWmComponent(Context context) {
WMComponent.Builder wmBuilder = mRootComponent.getWMComponentBuilder();
if (!mInitializeComponents || !WMShellConcurrencyModule.enableShellMainThread(context)) {
mWMComponent = wmBuilder.build();
return;
}
// If the shell main thread is enabled, initialize the component on that thread
HandlerThread shellThread = WMShellConcurrencyModule.createShellMainThread();
shellThread.start();
// Use an async handler since we don't care about synchronization
Handler shellHandler = Handler.createAsync(shellThread.getLooper());
boolean built = shellHandler.runWithScissors(() -> {
wmBuilder.setShellMainThread(shellThread);
mWMComponent = wmBuilder.build();
}, 5000);
3.SystemUIApplication
3.1.onCreate
public void onCreate() {
super.onCreate();
//callback是2.2赋值的
mContextAvailableCallback.onContextAvailable(this);
mRootComponent = SystemUIFactory.getInstance().getRootComponent();
mSysUIComponent = SystemUIFactory.getInstance().getSysUIComponent();
mComponentHelper = mSysUIComponent.getContextComponentHelper();
mBootCompleteCache = mSysUIComponent.provideBootCacheImpl();
setTheme(R.style.Theme_SystemUI);
if (Process.myUserHandle().equals(UserHandle.SYSTEM)) {
IntentFilter bootCompletedFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
bootCompletedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
int sfPriority = SurfaceControl.getGPUContextPriority();
if (sfPriority == ThreadedRenderer.EGL_CONTEXT_PRIORITY_REALTIME_NV) {
ThreadedRenderer.setContextPriority(
ThreadedRenderer.EGL_CONTEXT_PRIORITY_HIGH_IMG);
}
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (mBootCompleteCache.isBootComplete()) return;
unregisterReceiver(this);
mBootCompleteCache.setBootComplete();
//服务是否已经启动,3.2方法执行完会设置为true
if (mServicesStarted) {
final int N = mServices.length;
for (int i = 0; i < N; i++) {
mServices[i].onBootCompleted();
}
}
}
}, bootCompletedFilter);
IntentFilter localeChangedFilter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) {
if (!mBootCompleteCache.isBootComplete()) return;
//语言改变,更新通知渠道名
NotificationChannels.createAll(context);
}
}
}, localeChangedFilter);
} else {
/
String processName = ActivityThread.currentProcessName();
ApplicationInfo info = getApplicationInfo();
if (processName != null && processName.startsWith(info.processName + ":")) {
return;
}
startSecondaryUserServicesIfNeeded();
}
}
3.2.startServicesIfNeeded
- SystemUIService.java的onCreate方法里调用
public void startServicesIfNeeded() {
//厂商自定义的组件在这里启动,参考3.3
final String vendorComponent = mInitializer.getVendorComponent(getResources());
//按类名排序的map
Map<Class<?>, Provider<CoreStartable>> sortedStartables = new TreeMap<>(
Comparator.comparing(Class::getName));
//添加一些实现了startable接口的类,方便循环执行他们的start方法
sortedStartables.putAll(mSysUIComponent.getStartables());
sortedStartables.putAll(mSysUIComponent.getPerUserStartables());
//补充1
startServicesIfNeeded(
sortedStartables, "StartServices", vendorComponent);
}
>1.startServicesIfNeeded
暂时先不管Startables数据咋获取的,继续往下看
private void startServicesIfNeeded(
Map<Class<?>, Provider<CoreStartable>> startables,
String metricsPrefix,
String vendorComponent) {
if (mServicesStarted) {
return;
}
//...
//通用的组件
int i = 0;
for (Map.Entry<Class<?>, Provider<CoreStartable>> entry : startables.entrySet()) {
String clsName = entry.getKey().getName();
int j = i; // Copied to make lambda happy.
//这个方法就是打印下runnable的用时
timeInitialization(
clsName,
//实际就是执行这个,参考补充2
() -> mServices[j] = startStartable(clsName, entry.getValue()),
log,
metricsPrefix);
i++;
}
//厂商自定义的组件
if (vendorComponent != null) {
timeInitialization(
vendorComponent,
() -> mServices[mServices.length - 1] =
startAdditionalStartable(vendorComponent),//补充3
log,
metricsPrefix);
}
for (i = 0; i < mServices.length; i++) {
if (mBootCompleteCache.isBootComplete()) {
notifyBootCompleted(mServices[i]);
}
mDumpManager.registerDumpable(mServices[i].getClass().getName(), mServices[i]);
}
//...
mServicesStarted = true;
}
>2.startStartable()
- 可以看到拿到CoreStartable对象,调用其start方法
private static CoreStartable startStartable(String clsName, Provider<CoreStartable> provider) {
CoreStartable startable = provider.get();
return startStartable(startable);
}
private static CoreStartable startStartable(CoreStartable startable) {
startable.start();
return startable;
}
>3.startAdditionalStartable()
厂商那个是返回的class的名字,所以是反射创建对象,同样调用其start方法
private static CoreStartable startAdditionalStartable(String clsName) {
try {
startable = (CoreStartable) Class.forName(clsName).newInstance();
}
return startStartable(startable);
}
3.3.getVendorComponent
SystemUIInitializer.java
public String getVendorComponent(Resources resources) {
return resources.getString(R.string.config_systemUIVendorServiceComponent);
}
<!-- SystemUI vender service, used in config_systemUIServiceComponents. -->
<string name="config_systemUIVendorServiceComponent" translatable="false">com.android.systemui.VendorServices</string>
>1.VendorServices
源码里这个service是空的实现
/**
* Placeholder for any vendor-specific services.
*/
public class VendorServices implements CoreStartable {
public VendorServices() {
}
@Override
public void start() {
// no-op
}
}
3.4.SysUIComponent
看下下边这两个值是啥,好确定都启动了哪些服务
sortedStartables.putAll(mSysUIComponent.getStartables());
sortedStartables.putAll(mSysUIComponent.getPerUserStartables());
- 注解生成的
- 这个类是通过@Subcomponent.Builder来实例化的
>1.接口类
@SysUISingleton
@Subcomponent(modules = {
DefaultComponentBinder.class,
DependencyProvider.class,
NotificationInsetsModule.class,
QsFrameTranslateModule.class,
SystemUIBinder.class,
SystemUIModule.class,
SystemUICoreStartableModule.class,
ReferenceSystemUIModule.class})
public interface SysUIComponent {
/**
* Builder for a SysUIComponent.
*/
@SysUISingleton
@Subcomponent.Builder
interface Builder {
@BindsInstance
Builder setShell(ShellInterface s);
//...
//这个是相关的startbles
Map<Class<?>, Provider<CoreStartable>> getStartables();
//这个目前就发现一个 NotificationChannels,也在下边那个module类里
@PerUser Map<Class<?>, Provider<CoreStartable>> getPerUserStartables();
>2.SystemUICoreStartableModule
- 上述getStartables()返回的map数据主要是在这个类里,可能还有其他的,需要自己搜下"): CoreStartable"
- 另外这个类是对普通手机来讲的,如果是car,tv就会是其他类了,比如CarSystemUICoreStartableModule,TVSystemUICoreStartableModule
- 通过注解@IntoMap把数据传给map的,下边贴了部分
@Module(includes = [MultiUserUtilsModule::class])
abstract class SystemUICoreStartableModule {
/** Inject into AuthController. */
@Binds
@IntoMap
@ClassKey(AuthController::class)
abstract fun bindAuthController(service: AuthController): CoreStartable
/** Inject into FsiChromeWindowBinder. */
@Binds
@IntoMap
@ClassKey(FsiChromeViewBinder::class)
abstract fun bindFsiChromeWindowBinder(sysui: FsiChromeViewBinder): CoreStartable
/** Inject into GarbageMonitor.Service. */
@Binds
@IntoMap
@ClassKey(GarbageMonitor::class)
abstract fun bindGarbageMonitorService(sysui: GarbageMonitor.Service): CoreStartable
/** Inject into LatencyTests. */
@Binds
@IntoMap
@ClassKey(LatencyTester::class)
abstract fun bindLatencyTester(sysui: LatencyTester): CoreStartable
/** Inject into NotificationChannels. */
@Binds
@IntoMap
@ClassKey(NotificationChannels::class)
@PerUser //这个就是给同样注解的map用的
abstract fun bindNotificationChannels(sysui: NotificationChannels): CoreStartable
>3.StartCentralSurfacesModule
补充1里声明的子模块ReferenceSystemUIModule.class里边声明的子模块CentralSurfacesModule.class,
@Module
interface StartCentralSurfacesModule {
/** Start the CentralSurfaces */
@Binds
@IntoMap
@ClassKey(CentralSurfaces::class)
abstract fun bindsCentralSurfaces(centralSurfaces: CentralSurfacesImpl): CoreStartable
}
4.CentralSurfacesImpl
- SystemUI的启动核心就在这个类里了,这个类的构造方法参数就有90个左右,吓死个人,还好用的dagger2注解生成的对象,要不想想都怕
- 这个类也在mSysUIComponent.getStartables()返回的map里,所以会调用start方法
4.1.start方法
核心方法了,一切从这里开始
public void start() {
mScreenLifecycle.addObserver(mScreenObserver);
mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
mUiModeManager = mContext.getSystemService(UiModeManager.class);
if (mBubblesOptional.isPresent()) {
mBubblesOptional.get().setExpandListener(mBubbleExpandListener);
}
//statusBar相关,主要处理和信号有关的icon,比如mobile,wifi,vpn等
mStatusBarSignalPolicy.init();
//TODO
mKeyguardIndicationController.init();
//回调里会update theme
mColorExtractor.addOnColorsChangedListener(mOnColorsChangedListener);
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
mDisplay = mContext.getDisplay();
mDisplayId = mDisplay.getDisplayId();
updateDisplaySize();
//TODO
mStatusBarHideIconsForBouncerManager.setDisplayId(mDisplayId);
initShadeVisibilityListener();
// 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();
}
//这里就是添加view的核心代码了,参考4.2
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()
//初始化通知栏状态,具体见章节6
setUpPresenter();
if (containsType(result.mTransientBarTypes, ITYPE_STATUS_BAR)) {
showTransientUnchecked();
}
mCommandQueueCallbacks.onSystemBarAttributesChanged(mDisplayId, result.mAppearance,
result.mAppearanceRegions, result.mNavbarColorManagedByIme, result.mBehavior,
result.mRequestedVisibilities, result.mPackageName, result.mLetterboxDetails);
// 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));
}
//TODO banner到底是啥?
IntentFilter internalFilter = new IntentFilter();
internalFilter.addAction(BANNER_ACTION_CANCEL);
internalFilter.addAction(BANNER_ACTION_SETUP);
mContext.registerReceiver(mBannerActionBroadcastReceiver, internalFilter, PERMISSION_SELF,
null, Context.RECEIVER_EXPORTED_UNAUDITED);
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.
//这个是常见的icon的处理类,比如蓝牙,定位,录屏等状态图标的显示
mIconPolicy.init();
// Based on teamfood flag, turn predictive back dispatch on at runtime.
if (mFeatureFlags.isEnabled(Flags.WM_ENABLE_PREDICTIVE_BACK_SYSUI)) {
mContext.getApplicationInfo().setEnableOnBackInvokedCallback(true);
}
mKeyguardStateController.addCallback(new KeyguardStateController.Callback() {
//...
//锁屏相关,4.6
startKeyguard();
mKeyguardUpdateMonitor.registerCallback(mUpdateCallback);
//TODO
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(
//...
mStartingSurfaceOptional.ifPresent(startingSurface -> startingSurface.setSysuiProxy(
(requestTopUi, componentTag) -> mMainExecutor.execute(() ->
mNotificationShadeWindowController.setRequestTopUi(
requestTopUi, componentTag))));
}
4.2.ceateAndAddWindows(result)
public void createAndAddWindows(@Nullable RegisterStatusBarResult result) {
makeStatusBarView(result);//参考4.3
mNotificationShadeWindowController.attach();//添加通知栏面板到屏幕,具体的见6.3
mStatusBarWindowController.attach();//添加statusBar到屏幕,具体的见6.4
}
4.3.makeStatusBarView
protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
updateDisplaySize(); // populates mDisplayMetrics
updateResources();
updateTheme();
//状态栏,补充1
inflateStatusBarWindow();
mNotificationShadeWindowView.setOnTouchListener(getStatusBarWindowTouchListener());
mWallpaperController.setRootView(mNotificationShadeWindowView);
mNotificationIconAreaController.setupShelf(mNotificationShelfController);
mShadeExpansionStateManager.addExpansionListener(mWakeUpCoordinator);
// Allow plugins to reference DarkIconDispatcher and StatusBarStateController
mPluginDependencyProvider.allowPluginDependency(DarkIconDispatcher.class);
mPluginDependencyProvider.allowPluginDependency(StatusBarStateController.class);
// Set up CollapsedStatusBarFragment and PhoneStatusBarView
StatusBarInitializer initializer = mCentralSurfacesComponent.getStatusBarInitializer();
initializer.setStatusBarViewUpdatedListener(
(statusBarView, statusBarViewController, statusBarTransitions) -> {
mStatusBarView = statusBarView;
mPhoneStatusBarViewController = statusBarViewController;
mStatusBarTransitions = statusBarTransitions;
mNotificationShadeWindowViewController
.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).
mNotificationPanelViewController.updatePanelExpansionAndVisibility();
setBouncerShowingForStatusBarComponents(mBouncerShowing);
checkBarModes();
});
//replace容器为CollapsedStatusBarFragment
initializer.initializeStatusBar(mCentralSurfacesComponent);
mStatusBarTouchableRegionManager.setup(this, mNotificationShadeWindowView);
mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager);
//导航栏,补充3
createNavigationBar(result);
if (ENABLE_LOCKSCREEN_WALLPAPER && mWallpaperSupported) {
mLockscreenWallpaper = mLockscreenWallpaperLazy.get();
}
mAmbientIndicationContainer = mNotificationShadeWindowView.findViewById(
R.id.ambient_indication_container);
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() {
clearTransient();
}
});
ScrimView scrimBehind = mNotificationShadeWindowView.findViewById(R.id.scrim_behind);
ScrimView notificationsScrim = mNotificationShadeWindowView
.findViewById(R.id.scrim_notifications);
ScrimView scrimInFront = mNotificationShadeWindowView.findViewById(R.id.scrim_in_front);
mScrimController.setScrimVisibleListener(scrimsVisible -> {
mNotificationShadeWindowController.setScrimsVisibility(scrimsVisible);
});
mScrimController.attachViews(scrimBehind, notificationsScrim, scrimInFront);
mLightRevealScrim = mNotificationShadeWindowView.findViewById(R.id.light_reveal_scrim);
if (mFeatureFlags.isEnabled(Flags.LIGHT_REVEAL_MIGRATION)) {
LightRevealScrimViewBinder.bind(
mLightRevealScrim, mLightRevealScrimViewModelLazy.get());
}
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, mLightRevealScrim);
updateLightRevealScrimVisibility();
mNotificationPanelViewController.initDependencies(
this,
mGestureRec,
mShadeController::makeExpandedInvisible,
mNotificationShelfController);
BackDropView backdrop = mNotificationShadeWindowView.findViewById(R.id.backdrop);
mMediaManager.setup(backdrop, backdrop.findViewById(R.id.backdrop_front),
backdrop.findViewById(R.id.backdrop_back), mScrimController, mLockscreenWallpaper);
float maxWallpaperZoom = mContext.getResources().getFloat(
com.android.internal.R.dimen.config_wallpaperMaxScale);
mNotificationShadeDepthControllerLazy.get().addListener(depth -> {
float scale = MathUtils.lerp(maxWallpaperZoom, 1f, depth);
backdrop.setPivotX(backdrop.getWidth() / 2f);
backdrop.setPivotY(backdrop.getHeight() / 2f);
backdrop.setScaleX(scale);
backdrop.setScaleY(scale);
});
// Set up the quick settings tile panel
final View container = mNotificationShadeWindowView.findViewById(R.id.qs_frame);
if (container != null) {
FragmentHostManager fragmentHostManager = FragmentHostManager.get(container);
ExtensionFragmentListener.attachExtensonToFragment(container, QS.TAG, R.id.qs_frame,
mExtensionController
.newExtension(QS.class)
.withPlugin(QS.class)
.withDefault(this::createDefaultQSFragment)
.build());
mBrightnessMirrorController = new BrightnessMirrorController(
mNotificationShadeWindowView,
mNotificationPanelViewController,
mNotificationShadeDepthControllerLazy.get(),
mBrightnessSliderFactory,
(visible) -> {
mBrightnessMirrorVisible = visible;
updateScrimController();
});
fragmentHostManager.addTagListener(QS.TAG, (tag, f) -> {
QS qs = (QS) f;
if (qs instanceof QSFragment) {
mQSPanelController = ((QSFragment) qs).getQSPanelController();
((QSFragment) qs).setBrightnessMirrorController(mBrightnessMirrorController);
}
});
}
mReportRejectedTouch = mNotificationShadeWindowView
.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");
startActivityDismissingKeyguard(Intent.createChooser(new Intent(Intent.ACTION_SEND)
.setType("*/*")
.putExtra(Intent.EXTRA_SUBJECT, "Rejected touch report")
.putExtra(Intent.EXTRA_STREAM, session)
.putExtra(Intent.EXTRA_TEXT, message.toString()),
"Share rejected touch report")
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
true /* onlyProvisioned */, true /* dismissShade */);
});
}
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();
IntentFilter demoFilter = new IntentFilter();
if (DEBUG_MEDIA_FAKE_ARTWORK) {
demoFilter.addAction(ACTION_FAKE_ARTWORK);
}
mContext.registerReceiverAsUser(mDemoReceiver, UserHandle.ALL, demoFilter,
android.Manifest.permission.DUMP, null,
Context.RECEIVER_EXPORTED_UNAUDITED);
// 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));
}
>1.inflateStatusBarWindow
private void inflateStatusBarWindow() {
//...
## 拿到dagger2生成的component
mCentralSurfacesComponent = mCentralSurfacesComponentFactory.create();
## 把component里方法返回类型是fragment的储存起来,方便之后实例化fragment对象,补充2
mFragmentService.addFragmentInstantiationProvider(mCentralSurfacesComponent);
## 帧布局,注解生成的,加载的是一个布局,具体在StatusBarViewModule.java,详见另一篇blog
mNotificationShadeWindowView = mCentralSurfacesComponent.getNotificationShadeWindowView();
## 注解获取,参考6.1
mNotificationShadeWindowViewController = mCentralSurfacesComponent
.getNotificationShadeWindowViewController();
## 把view传给controller,6.2小节用到
mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView);
mNotificationShadeWindowViewController.setupExpandedStatusBar();
mNotificationPanelViewController =
mCentralSurfacesComponent.getNotificationPanelViewController();
mShadeController.setNotificationPanelViewController(mNotificationPanelViewController);
mShadeController.setNotificationShadeWindowViewController(
mNotificationShadeWindowViewController);
## 锁屏icon的controller
mCentralSurfacesComponent.getLockIconViewController().init();
mStackScrollerController =
mCentralSurfacesComponent.getNotificationStackScrollLayoutController();
## mNotificationPanelViewController构造方法里给view赋值的
mStackScroller = mStackScrollerController.getView();
mNotifListContainer = mCentralSurfacesComponent.getNotificationListContainer();
mPresenter = mCentralSurfacesComponent.getNotificationPresenter();
mNotificationActivityStarter = mCentralSurfacesComponent.getNotificationActivityStarter();
mNotificationShelfController = mCentralSurfacesComponent.getNotificationShelfController();
## 解锁成功后的波纹效果
mAuthRippleController = mCentralSurfacesComponent.getAuthRippleController();
mAuthRippleController.init();
##警告管理监听
mHeadsUpManager.addListener(mCentralSurfacesComponent.getStatusBarHeadsUpChangeListener());
// Listen for demo mode changes
mDemoModeController.addCallback(mDemoModeCallback);
if (mCommandQueueCallbacks != null) {
mCommandQueue.removeCallback(mCommandQueueCallbacks);
}
mCommandQueueCallbacks =
mCentralSurfacesComponent.getCentralSurfacesCommandQueueCallbacks();
// Connect in to the status bar manager service
mCommandQueue.addCallback(mCommandQueueCallbacks);
// Perform all other initialization for CentralSurfacesScope
for (CentralSurfacesComponent.Startable s : mCentralSurfacesComponent.getStartables()) {
s.start();
}
}
>2.addFragmentInstantiationProvider
public void addFragmentInstantiationProvider(Object daggerComponent) {
for (Method method : daggerComponent.getClass().getDeclaredMethods()) {
if (Fragment.class.isAssignableFrom(method.getReturnType())
&& (method.getModifiers() & Modifier.PUBLIC) != 0) {
String fragmentName = method.getReturnType().getName();
if (mInjectionMap.containsKey(fragmentName)) {
Log.w(TAG, "Fragment " + fragmentName + " is already provided by different"
+ " Dagger component; Not adding method");
continue;
}
mInjectionMap.put(
fragmentName, new FragmentInstantiationInfo(method, daggerComponent));
}
}
}
>3.createNavigationBar(result);
导航栏的创建
protected void createNavigationBar(@Nullable RegisterStatusBarResult result) {
//参考5.1
mNavigationBarController.createNavigationBars(true /* includeDefaultDisplay */, result);
}
4.4.setUpPresenter();
通知的初始化
private void setUpPresenter() {
// Set up the initial notification state.
mActivityLaunchAnimator.setCallback(mActivityLaunchAnimatorCallback);
mActivityLaunchAnimator.addListener(mActivityLaunchAnimatorListener);
mNotificationAnimationProvider = new NotificationLaunchAnimatorControllerProvider(
mNotificationShadeWindowViewController,
mNotifListContainer,
mHeadsUpManager,
mJankMonitor);
mNotificationShelfController.setOnActivatedListener(mPresenter);
mRemoteInputManager.addControllerCallback(mNotificationShadeWindowController);
mStackScrollerController.setNotificationActivityStarter(mNotificationActivityStarter);
mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
mShadeController.setNotificationPresenter(mPresenter);
mNotificationsController.initialize(
this,
mPresenter,
mNotifListContainer,
mStackScrollerController.getNotifStackController(),
mNotificationActivityStarter,
mCentralSurfacesComponent.getBindRowCallback());
}
我们看下最后那个initialize方法
>1.NotificationsController
这个类有两个实现类,根据配置参数决定加载哪个,
@Provides
static NotificationsController provideNotificationsController(
Context context,
Provider<NotificationsControllerImpl> realController,//正常是这个,参考4.5
Provider<NotificationsControllerStub> stubController) {//这个是空的实现
if (context.getResources().getBoolean(R.bool.config_renderNotifications)) {
return realController.get();
} else {
return stubController.get();
}
}
4.5.NotificationsControllerImpl
>1.initialize
override fun initialize(
centralSurfaces: CentralSurfaces,
presenter: NotificationPresenter,
listContainer: NotificationListContainer,
stackController: NotifStackController,
notificationActivityStarter: NotificationActivityStarter,
bindRowCallback: NotificationRowBinderImpl.BindRowCallback
) {
notificationListener.registerAsSystemService()
notifPipeline.get().addCollectionListener(object : NotifCollectionListener {
override fun onEntryRemoved(entry: NotificationEntry, reason: Int) {
listContainer.cleanUpViewStateForEntry(entry)
}
})
//通知item的点击事件,交给clickBuilder处理
notificationRowBinder.setNotificationClicker(
clickerBuilder.build(
Optional.ofNullable(centralSurfaces), bubblesOptional,
notificationActivityStarter))
notificationRowBinder.setUpWithPresenter(
presenter,
listContainer,
bindRowCallback)
headsUpViewBinder.setPresenter(presenter)
notifBindPipelineInitializer.initialize()
animatedImageNotificationManager.bind()
notifPipelineInitializer.get().initialize(
notificationListener,
notificationRowBinder,
listContainer,
stackController)
targetSdkResolver.initialize(notifPipeline.get())
notificationsMediaManager.setUpWithPresenter(presenter)
notificationLogger.setUpWithContainer(listContainer)
peopleSpaceWidgetManager.attach(notificationListener)
fgsNotifListener.init()
if (featureFlags.isEnabled(Flags.NOTIFICATION_MEMORY_MONITOR_ENABLED)) {
memoryMonitor.get().init()
}
}
4.6.startKeyguard
protected void startKeyguard() {
Trace.beginSection("CentralSurfaces#startKeyguard");
mStatusBarStateController.addCallback(mStateListener,
SysuiStatusBarStateController.RANK_STATUS_BAR);
mBiometricUnlockController = mBiometricUnlockControllerLazy.get();
mBiometricUnlockController.addBiometricModeListener(
new BiometricUnlockController.BiometricModeListener() {
@Override
public void onResetMode() {
setWakeAndUnlocking(false);
notifyBiometricAuthModeChanged();
}
@Override
public void onModeChanged(int mode) {
switch (mode) {
case BiometricUnlockController.MODE_WAKE_AND_UNLOCK_FROM_DREAM:
case BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING:
case BiometricUnlockController.MODE_WAKE_AND_UNLOCK:
setWakeAndUnlocking(true);
}
notifyBiometricAuthModeChanged();
}
private void setWakeAndUnlocking(boolean wakeAndUnlocking) {
if (getNavigationBarView() != null) {
getNavigationBarView().setWakeAndUnlocking(wakeAndUnlocking);
}
}
});
mKeyguardViewMediator.registerCentralSurfaces(
/* statusBar= */ this,
mNotificationPanelViewController,
mShadeExpansionStateManager,
mBiometricUnlockController,
mStackScroller,
mKeyguardBypassController);
mKeyguardStateController.addCallback(mKeyguardStateControllerCallback);
mKeyguardIndicationController
.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
mBiometricUnlockController.setKeyguardViewController(mStatusBarKeyguardViewManager);
mRemoteInputManager.addControllerCallback(mStatusBarKeyguardViewManager);
mLightBarController.setBiometricUnlockController(mBiometricUnlockController);
mMediaManager.setBiometricUnlockController(mBiometricUnlockController);
mKeyguardDismissUtil.setDismissHandler(this::executeWhenUnlocked);
}
5.NavigationBarController
- 这个类,在systemUI目录下,inputmethod那边也有个同名类,别找错了。
5.1. createNavigationBars
public void createNavigationBars(final boolean includeDefaultDisplay,
RegisterStatusBarResult result) {
updateAccessibilityButtonModeIfNeeded();
//看下是否创建了taskbar(平板用),两者是二选一
final boolean shouldCreateDefaultNavbar = includeDefaultDisplay
&& !initializeTaskbarIfNecessary();
Display[] displays = mDisplayManager.getDisplays();
for (Display display : displays) {
if (shouldCreateDefaultNavbar || display.getDisplayId() != DEFAULT_DISPLAY) {
//补充1
createNavigationBar(display, null /* savedState */, result);
}
}
}
>1.createNavigationBar
void createNavigationBar(Display display, Bundle savedState, RegisterStatusBarResult result) {
//...
final Context context = isOnDefaultDisplay
? mContext
: mContext.createDisplayContext(display);
NavigationBarComponent component = mNavigationBarComponentFactory.create(
context, savedState);
//这个是注解生成的对象
NavigationBar navBar = component.getNavigationBar();
navBar.init();
mNavigationBars.put(displayId, navBar);
5.2.NavigationBar
>1.构造方法
- 变量mView就是NavigationBarView,mFrame就是NavigationBarFrame
- 构造方法里用到的对象也都注解生成的,参考补充3
@Inject
NavigationBar(
NavigationBarView navigationBarView,
NavigationBarFrame navigationBarFrame,
//...
super(navigationBarView);
mFrame = navigationBarFrame;
super方法
protected ViewController(T view) {
mView = view;
}
>2.onInit
- init是父类的方法,子类实现的是onInit,在这里会把view添加到窗口上
@Override
public void onInit() {
mView.setBarTransitions(mNavigationBarTransitions);
mView.setTouchHandler(mTouchHandler);
setNavBarMode(mNavBarMode);
mEdgeBackGestureHandler.setStateChangeCallback(mView::updateStates);
mNavigationBarTransitions.addListener(this::onBarTransition);
mView.updateRotationButton();
mView.setVisibility(
mStatusBarKeyguardViewManager.isNavBarVisible() ? View.VISIBLE : View.INVISIBLE);
//..mFrame,构造方法里传递进来的。
mWindowManager.addView(mFrame,
getBarLayoutParams(mContext.getResources().getConfiguration().windowConfiguration
.getRotation()));
>3.NavigationBarModule.java
- 补充1的构造方法里用到的对象都是下边注解生成的
- 导航栏里边的具体逻辑这里暂时不看了,后续其他帖子再深入
@Provides
@NavigationBarScope
@DisplayId
static LayoutInflater provideLayoutInflater(@DisplayId Context context) {
return LayoutInflater.from(context);
}
/**加载根容器布局 */
@Provides
@NavigationBarScope
static NavigationBarFrame provideNavigationBarFrame(@DisplayId LayoutInflater layoutInflater) {
return (NavigationBarFrame) layoutInflater.inflate(R.layout.navigation_bar_window, null);
}
/**又加载一个容器布局到上边的frame里*/
@Provides
@NavigationBarScope
static NavigationBarView provideNavigationBarview(
@DisplayId LayoutInflater layoutInflater, NavigationBarFrame frame) {
View barView = layoutInflater.inflate(R.layout.navigation_bar, frame);
return barView.findViewById(R.id.navigation_bar_view);
}
6.NotificationShadeWindowController
- 这个类是个接口,它的实例化应该是通过注解生成的,参考6.1
- 搜下这个类,一般应该在XXXXModule.java类里边
6.1.ReferenceSystemUIModule.java
- 实现类是NotificationShadeWindowControllerImpl.java
@Binds
abstract NotificationShadeWindowController bindNotificationShadeController(
NotificationShadeWindowControllerImpl notificationShadeWindowController);
6.2.setNotificationShadeView
小节4.3.1调用
public void setNotificationShadeView(ViewGroup view) {
mNotificationShadeView = view;
}
6.3.attach
public void attach() {
mLp = new LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT,
LayoutParams.TYPE_NOTIFICATION_SHADE,
LayoutParams.FLAG_NOT_FOCUSABLE
| LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
| LayoutParams.FLAG_SPLIT_TOUCH
| LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
PixelFormat.TRANSLUCENT);
mLp.token = new Binder();
mLp.gravity = Gravity.TOP;
mLp.setFitInsetsTypes(0 /* types */);
mLp.setTitle("NotificationShade");
mLp.packageName = mContext.getPackageName();
mLp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
mLp.privateFlags |= PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
mLp.insetsFlags.behavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
//通过windowManager添加view,数据6.2设置的
mWindowManager.addView(mNotificationShadeView, mLp);
mLpChanged.copyFrom(mLp);
onThemeChanged();
if (mKeyguardViewMediator.isShowingAndNotOccluded()) {
setKeyguardShowing(true);
}
}
>1.StatusBarViewModule
mNotificationShadeWindowView也是注解生成的,具体如下,加载的布局
@Provides
@CentralSurfacesComponent.CentralSurfacesScope
public static NotificationShadeWindowView providesNotificationShadeWindowView(
LayoutInflater layoutInflater) {
NotificationShadeWindowView notificationShadeWindowView = (NotificationShadeWindowView)
layoutInflater.inflate(R.layout.super_notification_shade, /* root= */ null);
if (notificationShadeWindowView == null) {
throw new IllegalStateException(
"R.layout.super_notification_shade could not be properly inflated");
}
return notificationShadeWindowView;
}
6.4.StatusBarWindowController
>1.构造方法
- mStatusBarWindowView是构造方法里传递进来的,注解生成的
public StatusBarWindowController(
Context context,
//注解生成的,参考补充2
@StatusBarWindowModule.InternalWindowView StatusBarWindowView statusBarWindowView,
WindowManager windowManager,
IWindowManager iWindowManager,
StatusBarContentInsetsProvider contentInsetsProvider,
@Main Resources resources,
Optional<UnfoldTransitionProgressProvider> unfoldTransitionProgressProvider) {
mContext = context;
mWindowManager = windowManager;
mIWindowManager = iWindowManager;
mContentInsetsProvider = contentInsetsProvider;
mStatusBarWindowView = statusBarWindowView;//这个
mLaunchAnimationContainer = mStatusBarWindowView.findViewById(
R.id.status_bar_launch_animation_container);
mLpChanged = new WindowManager.LayoutParams();
if (mBarHeight < 0) {
mBarHeight = SystemBarUtils.getStatusBarHeight(mContext);
}
2.StatusBarWindowModule
可以看到,StatusBarWindowView也是加载布局生成的
@Module
abstract class StatusBarWindowModule {
/**
* Only [StatusBarWindowController] should inject the view.
*/
@Module
companion object {
@JvmStatic
@Provides
@SysUISingleton
@InternalWindowView
fun providesStatusBarWindowView(layoutInflater: LayoutInflater): StatusBarWindowView {
return layoutInflater.inflate(
R.layout.super_status_bar,
/* root= */null
) as StatusBarWindowView?
?: throw IllegalStateException(
"R.layout.super_status_bar could not be properly inflated"
)
}
}
>3.attach
通过windowmanager把statusbar的view添加到屏幕上
public void attach() {
mLp = getBarLayoutParams(mContext.getDisplay().getRotation());
//...
mWindowManager.addView(mStatusBarWindowView, mLp);
7.总结
- SystemUi是个系统app,是通过SystemServer启动的
- 在SystemUiService里会调用Appilcation里的方法,启动一系列实现了startable的对象,其中最重要的一个就是CentralSurfacesImpl这个类了。
- 在CentralSurfacesImpl这个类,会通过windowManager添加各种view,比如状态栏,导航栏,通知栏等等
- 每一部分都很复杂,所以后边再细看,这边就简单整理下整体流程。