还未完成,待继续补充.
SystemUI概述
Android8.1.0 SystemUI代码统计如下:
1 | ------------------------------------------------------------------------------- |
从Android7.0开始,把Keyguard模块的代码也一起放到了SystemUI模块中,从代码统计来看,SystemUI中Java代码大概有14万行.
实际SystemUI与Framework有很多的交互,还有很多的代码是在Framework的其他模块里面.
4.4版本SystemUI中SystemBar启动流程如下:
主要类功能初步解析
ImmersiveModeConfirmation.java
首次隐藏状态栏和导航栏,进入沉浸模式是的提示
SystemUI包含的服务
SystemUI通过java启动的服务有13个,分别是:
1.TunerService 系统界面调谐器
系统界面调制器是安卓M加入的,当用户长按下拉菜单的齿轮卡3秒中就可以在setting app里加入界面调制器。
可以对状态栏、导航栏、勿扰模式以及锁屏界面进行局部定制.
2.KeyguardViewMediator
锁屏管理
3.Recents
最近应用模块,
4.VolumeUI
音量的调节
5.Divider
6.SystemBars
7.StorageNotification
8.PowerUI
9.RingtonePlayer
10.KeyboardUI
11.PipUI
12.ShortcutKeyDispatcher
13.VendorServices
通过xml启动的服务有6个,分别是:
1.SystemUIService
2.SystemUISecondaryUserService
3.TakeScreenshotService
4.ImageWallpaper
5.RecentsSystemUserService
6.DessertCaseDream
7.KeyguardService
8.DozeService
先以KeyguardViewMediator服务启动流程图为例进行分析,其它服务启动顺序与这个类似,只是功能不同而已。
SystemBar的启动流程图如下:
PhoneStatusBar.java中的createAndAddWindows()会初始化并且加载SystemUI的绝大多数界面,包括statusbar与navigationbar,以及初始化QSHostView。
SystemUI的功能模块
SystemUI的功能模块:
a)Keyguard
锁屏和壁纸
b)StatusBar:电量、时间、SIM卡状态和信号、WIFI、Bluetooth、数据连接状态
通知、
c)NavigationBar
d)Shortcut
截图和录屏
e)Recents
f)PipUI
g)Tuner
h)RingtonePlayer
SystemUI重难点
- 滑动事件的处理
2.
状态栏
锁屏状态栏
状态栏反色
沉浸式状态栏
信号图标的刷新
凹口处理
导航栏 NavigationBar
导航栏中的Back键和HOME键的事件处理:
https://blog.csdn.net/span76/article/details/48441971
Recent键的处理呢?
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
中的onRecentsClick函数处理Recent键
导航栏的加载流程
基于Android8.1代码
对于NavigationBar的加载从PhoneWindowManager开始讲起,PhoneWindowManager主要用于处理几个实体按键或者虚拟按键(Home/Back/Recent/Power/Volume up/Volume down)等按键事件,包括音量加减,截图,长按Power调出关机界面,长按Home/Back/Recent键,短按Home/Back/Recent/Power键. 显示点击点的位置.BugReport
以及SystemUI的NavigationBar和StatusBar的加载.手势,方向,HDMI,
StatusBar,NavigationBar,Wallpaper,文字输入法和语言输入法等窗口的绘制
显示开机界面中的Android正在启动.
在PhoneWindowManager.java中与StatusBar和NavigationBar相关的代码如下:
1 | public class PhoneWindowManager implements WindowManagerPolicy { |
快捷开关
下拉通知栏
截图模块
防误触模块
亮度调节
PIP 画中画
双屏异显
Recent模块
在AndroidManifest.xml里面,我们注意到SystemUISecondaryUserService,对于每一个用户都有一个SystemUI进程,所以在用户切换的时候,需要用SystemUISecondaryUserService来确保新的用户进程创建.
1 | <!-- Recents depends on every user having their own SystemUI process, so on user switch, |
RecentsActivity.java的onCreate函数开始
1 | public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreDrawListener, |
SystemUI 新功能
隐藏导航栏
悬浮按钮
单手模式(小屏模式)
单手键盘
口袋模式(防误触模式)
凹口设计
灭屏动画
翻转静音
1.来电静音
2.计时器和闹钟静音
双击唤醒
指关节截屏
字母手势
面部解锁
画中画
异屏双显
沉浸模式
##SB和NB颜色
通知栏和状态栏功能
通知
通知:允许通知.通知方式:状态栏上显示、在屏幕顶部悬浮显示、在锁屏上显示.
通知栏:
通知栏下拉规则:1)智能判断,有通知时,下拉显示通知,无通知时,下拉显示开关
2)依据下拉位置来判断:左边下拉显示通知页,右边下拉显示开关页
在通知栏显示流量信息.
状态栏:
显示运营商名称
有通知时显示图标
显示实时网速
显示电量百分比,电量百分比显示方式
Demo模式命令调试SystemUI
在SystemUI目录有一个Readme.md文件,在8.1.0版本中内容如下:
1 | * [Demo Mode](/packages/SystemUI/docs/demo_mode.md) |
我们到此目录查看demo_mode.md文件
如下:
Demo Mode for the Android System UI
Demo mode for the status bar allows you to force the status bar into a fixed state, useful for taking screenshots with a consistent status bar state, or testing different status icon permutations. Demo mode is available in recent versions of Android.
Enabling demo mode
Demo mode is protected behind a system setting. To enable it for a device, run:
1 | adb shell settings put global sysui_demo_allowed 1 |
Protocol
The protocol is based on broadcast intents, and thus can be driven via the command line (adb shell am broadcast) or an app (Context.sendBroadcast).
Broadcast action
1 | com.android.systemui.demo |
Commands
Commands and subcommands (below) are sent as string extras in the broadcast
intent.
Commands are sent as string extras with key command (required). Possible values are:
Command | Subcommand | Argument | Description |
---|---|---|---|
enter | Enters demo mode, bar state allowed to be modified (for convenience, any of the other non-exit commands will automatically flip demo mode on, no need to call this explicitly in practice) | ||
exit | Exits demo mode, bars back to their system-driven state | ||
battery | Control the battery display | ||
level | Sets the battery level (0 - 100) | ||
plugged | Sets charging state (true, false) | ||
powersave | Sets power save mode (true, anything else) | ||
network | Control the RSSI display | ||
airplane | show to show icon, any other value to hide | ||
fully | Sets MCS state to fully connected (true, false) | ||
wifi | show to show icon, any other value to hide | ||
level | Sets wifi level (null or 0-4) | ||
mobile | show to show icon, any other value to hide | ||
datatype | Values: 1x, 3g, 4g, e, g, h, lte, roam, any other value to hide | ||
level | Sets mobile signal strength level (null or 0-4) | ||
carriernetworkchange | Sets mobile signal icon to carrier network change UX when disconnected (show to show icon, any other value to hide) | ||
sims | Sets the number of sims (1-8) | ||
nosim | show to show icon, any other value to hide | ||
bars | Control the visual style of the bars (opaque, translucent, etc) | ||
mode | Sets the bars visual style (opaque, translucent, semi-transparent) | ||
status | Control the system status icons | ||
volume | Sets the icon in the volume slot (silent, vibrate, any other value to hide) | ||
bluetooth | Sets the icon in the bluetooth slot (connected, disconnected, any other value to hide) | ||
location | Sets the icon in the location slot (show, any other value to hide) | ||
alarm | Sets the icon in the alarm_clock slot (show, any other value to hide) | ||
sync | Sets the icon in the sync_active slot (show, any other value to hide) | ||
tty | Sets the icon in the tty slot (show, any other value to hide) | ||
eri | Sets the icon in the cdma_eri slot (show, any other value to hide) | ||
mute | Sets the icon in the mute slot (show, any other value to hide) | ||
speakerphone | Sets the icon in the speakerphone slot (show, any other value to hide) | ||
notifications | Control the notification icons | ||
visible | false to hide the notification icons, any other value to show | ||
clock | Control the clock display | ||
millis | Sets the time in millis | ||
hhmm | Sets the time in hh:mm |
Examples
Enter demo mode
1 | adb shell am broadcast -a com.android.systemui.demo -e command enter |
Exit demo mode
1 | adb shell am broadcast -a com.android.systemui.demo -e command exit |
Set the clock to 12:31
1 | adb shell am broadcast -a com.android.systemui.demo -e command clock -e hhmm |
Set the wifi level to max
1 | adb shell am broadcast -a com.android.systemui.demo -e command network -e wifi |
Show the silent volume icon
1 | adb shell am broadcast -a com.android.systemui.demo -e command status -e volume |
Empty battery, and not charging (red exclamation point)
1 | adb shell am broadcast -a com.android.systemui.demo -e command battery -e level |
Hide the notification icons
1 | adb shell am broadcast -a com.android.systemui.demo -e command notifications -e |
Exit demo mode
1 | adb shell am broadcast -a com.android.systemui.demo -e command exit |
Example demo controller app in AOSP
1 | frameworks/base/tests/SystemUIDemoModeController |
Example script (for screenshotting purposes)
1 |
|
导航栏和状态栏的显示与隐藏
POLICY_CONTROL实现
隐藏虚拟键及顶部状态栏:
adb shell settings put global policy_control immersive.full=
隐藏顶部状态栏(底部虚拟键会显示):
adb shell settings put global policy_control immersive.status=
隐藏虚拟键(顶部状态栏会显示):
adb shell settings put global policy_control immersive.navigation=*
恢复原来的设置:
adb shell settings put global policy_control null
参考文献
Doze模式
Android5.1 系统之省电模式探索一启动流程
《深入理解Android 卷III》第七章 深入理解SystemUI
NavigationBar相关
Android SystemUI中HOME key的处理
去除首次进入沉浸模式气泡提示
Android 修改横屏角度为顺时针270度