android display/graphics相关的调试方法和优化工作效率技巧整理
RenderThread渲染绘制(结合systrace)
参考:Android Systrace 基础知识(7) - Vsync 解读
参考:BufferQueue 学习总结(内附动态图)
参考:android 判断list里有这条数据_Android图形渲染原理(中)
1 | ---- |
合成送显流程
Android Q,非最新AOSP流程,有变动
SurfaceFlinger模块
1 | SurfaceFlinger::handleMessageRefresh(); |
HWC模块
1 | HWCSession::PresentDisplay(); |
DRM模块
1 | msm_atomic_commit(); |
Fence同步机制
DummySwSyncTimeline CreateDummyFence()
创建软件模拟fence
核心只有两件事情:
- sw_sync_fence_create 创建一个软件模拟的fence
- sw_sync_timeline_inc sync_timeline 时间轴向后推一个时间同步点
BufferSlot对应的BufferItem中的mFence对象就是Fence类,最后会在setUpHwcComposer中prepareFrame
设置到Hal中
在Android Framework中有一个用于操作fence同步栅的类(libsync中sync_wait类)
Google平台帧率切换
关键函数:
setFrameRate
getRefreshRate
app: 用于接收vsync信号并且上报给App进程,App开始画图 属性名:VSYNC_EVENT_PHASE_OFFSET_NS
sf: 用于SurfaceFlinger接收vsync信号用于渲染 属性名:SF_VSYNC_EVENT_PHASE_OFFSET_NS
磁盘空间占满100%
- 使用命令
sudo du -sh *
查看各个目录的占内存情况,使用du -h -x --max-depth=1
查看哪个深度1的目录占用过高 - 如果发现
/usr/local/tomcat
的目录占用的磁盘空间特别大,则进入该目录,发现logs的目录特别大,Tomcat的日志太大,可以将其删除。比如本地电脑发现~/.cache/vmware
目录下的drag_and_drop文件很大,这是因为虚拟机和主系统之间每次拖拉文件,都会生成一个复制文件,造成该文件越来越大,可以删除。 - 再使用
df -h
发现磁盘空间
Android设备分辨率、密度以及dp的理解
- dpi计算方法:
- 分辨率的平方和开方(勾股定理)
adb shell wm size
- 然后除以屏幕的物理英寸,即是dpi
adb shell wm density
可以查看当前的dpi(一般有的手机会在计算的结果上调整)
- dp计算方法(开发者选项最小宽度dp)
1.在安卓中,系统密度为160dpi的中密度手机屏幕为基准屏幕,即320×480的手机屏幕。在这个屏幕中,1dp=1px
2.分辨率的宽高分别除以dpi,获取到sw320dp,h533dp
值
可通过adb shell dumpsys window
查看到
低内存分析方向和技巧
dumpsys meminfo:
1 | Total RAM: 2,697,524K (status normal) |
查看进程占用内存情况
adb shell procrank
1 | PID Vss Rss Pss Uss Swap PSwap USwap ZSwap cmdline |
- VSS: 一个进程总共可访问的地址空间。其大小还包括了可能不在RAM中的内存(比如虽然malloc分配了空间,但尚未写入)。 VSS 很少被用于判断一个进程的真实内存使用量
- RSS: 一个进程在RAM中真实存储的总内存。仅仅表示该进程所使用的所有共享库的大小,而不管有多少个进程使用该共享库,该共享库仅被加载到内存一次。所以RSS并不能准确反映单进程的内存占用情况
- PSS: 按比例表示使用的共享库。系统中所有进程的PSS都相加的话,就刚好反映了系统中的总共占用的内存。而当一个进程被销毁之后, 其占用的共享库那部分比例的PSS,将会再次按比例分配给余下使用该库的进程
- USS: 进程所占用的私有内存(内存泄漏的最佳观察数据)。不包含so库占用内存的
ubuntu查看公网ip
三种方法:
curl www.icanhazip.com
curl ifconfig.me
curl -4sSkL https://myip.ipip.net
查看视频解码的分辨率及对应的帧率支持
日志关键词MediaCodec
配置文件:/vendor/etc/media_codecs.xml
linux和windows书签同步
about:config网址搜索sync:
identity.sync.tokenserver.uri
:
修改:
linux:
https://sync.firefox.com.cn/token/1.0/sync/1.5
windows:
https://token.services.mozilla.com/1.0/sync/1.5
getService配置权限
首先getService获取服务,紧接着就是getTransport的接口调用。如果在配置文件里面没找到我们所要求的服务,就会报错并结束服务的获取
- 首先会去
system/etc/vintf/manifest.xm
l文件去找我们调用者的服务名,如果找到就返回。 - 如果没找到就会去
vendor/etc/vintf/manifest.xml
文件去找,如果找到就返回。如果没找到则返回NULLPRT。同时打印Cannot find entry xxx in either framework or device manifest.
所以,如果碰到这样的log,首先要去检测这两个文件里面有没有配置我们调用的服务,没有就要自己配置。
一般是没有配置引起的,当然也有可能是xml增加的语法有问题,比如格式对齐等。
HIDL编写/升级流程
总体流程:
- 创建HIDL接口文件
XXX.hal
:HIDL为每个HAL模块设计了不同接口定义hal文件,以.hal
结尾,在hidl-gen
工具的帮助下即可自动编译生成对应接口C++实现或者Java实现 hidl-gen
生成interface hash
, 添加至current.txthidl-gen
生成接口,更新接口, XXX.bp, XXX.mk
等- 更新vendor manifest文件:对于TA开发来说, 底层TA是服务提供者(需求提供者), 因此提供的是manifest(vendor), 将
vintf/manifests.xml
push到设备端:adb push manifest.xml /vendor/etc/vintf
;system(framwork是发起需求者,需要设什么样的需求), 这部分内容在新平台上也在vintf/manifests.xml
,push到设备端:adb push compatibity.device.xml /system/etc/vintf
- 更新fcm(matrix),即compatibility matrix XML编写:manifest文件描述了提供给对方的feature, Matrix描述了需要对方提供什么样的feature. Manifest和Matrix在OTA升级之前会进行匹配检查, 确保framework和device是兼容的, 总的来说,manifest是feature提供端, matrix是feature需求端
- 关于compatibility Matrices:
framework compatibility matrix
:描述了framwork对device的需求, 这个matrix文件是和system.img关联的, 这些需求需要被device manifest支持
device compatibility matrix
:描述了device对framework的需求
1 | //xml manifest语法 |
结构层级:
1 | manifest:version type //这一层级申明当前manifest |
- 启动服务:首先需要将生成的库文件和服务守护进程分别push到设备端, 其次, 使用
lshal
查看对应的服务是否启动,如果为启动,需要查看对应的rc文件是否存在, 若不存在,则push(vendor/etc/xxx.rc)
, 手动启服务
概念:hidl接口哈希,是一种旨在防止意外更改接口,并确保接口更改经过全面审查的机制.因为HIDL接口带有版本号, 因此,接口一旦发布就bade在更改
布局:每个软件包根目录,都必须包含一个列出所有已经发布的HIDL接口的current.txt文件
使用hidl-gen添加哈希:hidl-gen生成的每个接口定义库都包含哈希,通过调用
IBase::getHashChain
可检索这些哈希。hidl-gen 编译接口时,会检查HAL软件包根目录中的current.txt 文件,以查看HAL是否已被更改- 如果没有找到HAL的哈希,则接口会被视为未发布(处于开发阶段),并且编译会继续进行
- 如果找到了相应哈希,则会对照当前接口对其进行检查
如果接口与哈希匹配,则编译会继续进行
如果接口与哈希不匹配,则编译会暂停,因为这意味着之前发布的接口会被更改
如要进行保留ABI的更改(ABI稳定性),必须先修改current.txt文件,然后编译才能继续进行
所有其他更改都应在接口的minor或major版本升级中进行
Tips:
- 查看HIDL编写的hal服务是否启动:
adb shell lshal
- 重启
ssk-key生成current.txt hash值
1 | $ hidl-gen -L hash -r vendor.....Testservice(service名称):/vendor/.../interfaces/Testservice(路径) -r android.hidl:system/libhidl/transport vendor...Testservice@1.0 |
修改git remote -v的orign源
git remote -v
查看远程提交信息git remote rm origin
删除- 添加:
git remote add origin (正确的信息)ssh://..../platform/frameworks/native
git remote -v
查看,如果push未修改成功没有关系- 提交代码,记得加上
-u
选项:git push -u orign master
git报错无法push(不建议使用)
报错信息:
1 | fatal: Unpack error, check server log |
使用:git push --no-thin origin dev
git commit修改作者名称
git commit --amend --author="wizzie <wizzie@test.com>"
gerrit拉取Andorid指定模块代码
- repo init
- gerrit提交代码的界面projects里面搜索要拉取的指定模块
- 复制
git clone
然后本地执行 git branch -a
查看所有分支,然后git checkout 分支名
(不包含orign/master)- git pull
ubuntu命令查看dns
nm-tool
1 | - Device: eth0 [Auto Ethernet] ------------------------------------------------ |
markdown数学公式语法
行内公式:将公式插入到本行内,符号:
$公式内容$
,如:$xyz$独行公式:将公式插入到新的一行内,并且居中,符号:
$$公式内容$$
,如:$$xyz$$上标符号,符号:^,如:$x^4$
下标符号,符号:_,如:$x_1$
组合符号,符号:{},如:${16}{8}O{2+}{2}$
安装adb和fastboot
sudo apt-get install android-tools-adb
sudo apt-get install android-tools-fastboot
或者使用Android SDK/platform-tools
针对image编译
- 编译所有image
1 | source build/envsetup.sh |
- 编译system.img,生成在qssi目录下
1 | source build/envsetup.sh |
- 编译super.img
1 | source build/envsetup.sh |
- 编译其它img,例如vendorimage(如果不指定会编译其它所有img)
1 | source build/envsetup.sh |
安装APK报错
如果安装APK报错,控制台输出如下:
1 | $ adb install test.apk |
需要先删除原先的APK,并且清楚缓存,重启:
1 | adb shell dumpsys activity top|grep ACTIVITY |
查看当前前台app包名(实时)
adb shell dumpsys window | grep mCurrentFocus
监控设备实时获取当前的包名
adb shell am monitor
APP增加多国语言
- 目录在:
res/values-***
- 将各个语言区域的字符串值添加到相应文件中。在运行时,Android 系统会根据当前为用户设备设置的语言区域使用相应的字符串资源集的
- 如需添加对更多语言的支持,在
res/
目录下创建名称末尾不同的values,其中目录末尾ISO语言代码则对应着相应语言,譬如:values-fr
则代表着手机系统语言为法语时读取的目录
例如:
- 英语(默认语言区域),
/values/strings.xml
- 中文,
/values-zh/strings.xml
- 法语,
values-fr/strings.xml
native crash分析
使用addr2line命令定位堆栈地址:
1 | /out/target/product/product/symbols/system/lib64$ addr2line -f -e libgui.so 00000000000c39a0 |
解释:-e
后加上.so的文件名;-f
可同时输出函数名称
分析工具:
- addr2line:
addr2line –e obj/local/armeabi/libhello-jni.so 00004de8
, 用来分析单个pc地址对应的源码行数 - objdump:
objdump –S obj/local/armeabi/libhello-jni.so > hello.asm
,或者symbols/out/target/product/merlin/symbols$ objdump -tT system/lib64/libdisplayfeature.so
用来把相应的so变成汇编语言的asm文件,然后根据地址信息(比如00000000000c39a0)就可以找到更加详细的相关函数信息; - ndk-stack:用来把log信息全部翻译成更加详细的带源码行数信息的log,相当于是在整个crash堆栈信息都执行addr2line命令。
addr2line -Cef .so address
或者:
- 可以使用
readelf -a [.so/.bin]
解析库地址 - 根据解析结果查询函数,C++在linux系统编译后会变成类似
_ZNK...
的修饰名。使用c++filt
获取函数的原始名称:
c++filt [_ZNK...函数修饰名]
YUV数据查看
- 从ffmpeg官网:
http://ffmpeg.org/download.html
下载最新的ffmpeg安装包,然后通过如下命令解压:tar jxf ffmpeg-2.5.3.tar.bz2
- 查看YUV:
ffplay -f rawvideo -video_size 1280x800 raw_1280x800_1878.yuv
或者使用YUVPlayer工具,执行:
wine yuvplayer.exe
YUV Player工具获取:
- https://github.com/Yonsm/RawPlayer RawPlayer
- https://github.com/latelee/YUVPlayer YUVPlayer
- https://github.com/figgis/yuv-viewer yuv-viewer
- https://github.com/Luomingbear/YuvPlayer android yuv播放器 SDL
关闭硬件加速
三种不同针对对象的方法:
- 在AndroidManifest.xml中设置
android:hardwareAccelerated="false"
,注意关闭整个app的硬件加速,慎用 - View有个方法支持单独的View关闭硬件加速,可以设置
mView.setLaterType(View.LAYER_TYPE_SOFTWARE);
- 关闭某一个控件的硬件加速功能:
findViewById(R.id.btn).setLayerType(View.LAYER_TYPE_SOFTWARE,null);
linux绘图UML/序列图工具dia
- 安装:
sudo apt-get install dia
- 使用,终端执行:
dia
屏幕旋转/转向切换命令
1 | adb root |
Surface两种合成方式(dump sf)
Client合成:Client合成方式是相对于硬件合成来说的,其合成方式是,将各个Layer的内容用GPU渲染到暂存缓冲区中,最后将暂存缓冲区传送到显示硬件。这个暂存缓冲区,我们称为FBTarget,每个Display设备有各自的FBTarget。Client合成,之前称为GLES合成,我们也可以称之为GPU合成。Client合成,采用RenderEngine进行合成
Device合成:就是用专门的硬件合成器进行合成HWComposer,所以硬件合成的能力就取决于硬件的实现。其合成方式是将各个Layer的数据全部传给显示硬件,并告知它从不同的缓冲区读取屏幕不同部分的数据。HWComposer是Devicehec的抽象。
getprop查看当前版本是user/userdebug
adb shell getprop ro.system.build.type
getprop查看设备信息
adb shell getprop ro.build.product
滑动到边缘Pixel值调试
AOSP源码位置:/frameworks/base/core/java/com/android/internal/widget/PointerLocationView.java
的onDraw函数中有ps.mCoords.x
和ps.mCoords.y
(float类型),可以将其打印出来,如果有问题可以修改此处转换逻辑
Input调试(PointerLocation)
systrace查看
systrace可以查看到touch点击的事件
点击input事件(up/down)
adb shell getevent -lrt
查看帮助:adb shell getevent -h
1 | [ 1423.973137] /dev/input/event2: EV_ABS ABS_MT_TRACKING_ID 0000003b |
input和wms的debug log开关打开
1 | adb root |
FPS帧率测试
查看设备的帧率:while true;do adb shell dumpsys SurfaceFlinger | grep "refresh-rate";done
获取实时帧率(主要用于获取游戏/视频应用的fps数据)
参考前面的文章:Android 两种实时获取FPS的方法
- 查询当前的layer(直接dump sf):
adb shell dumpsys SurfaceFlinger --list
adb shell dumpsys SurfaceFlinger --latency SurfaceView
dump gfxinfo信息
adb shell dumpsys gfxinfo <package_name>
查看每一帧的信息:adb shell dumpsys gfxinfo <package_name> framestats
结果:
- Graphics info for pid 31148 [com.android.settings]: 表明当前dump的为设置界面的帧信息,pid为31148
- Total frames rendered: 105 本次dump搜集了105帧的信息
- Janky frames: 2 (1.90%) 105帧中有2帧的耗时超过了16ms,卡顿概率为1.9%
- Number Missed Vsync: 0 垂直同步失败的帧
- Number High input latency: 0 处理input时间超时的帧数
- Number Slow UI thread: 2 因UI线程上的工作导致超时的帧数
- Number Slow bitmap uploads: 0 因bitmap的加载耗时的帧数
- Number Slow issue draw commands: 1 因绘制导致耗时的帧数
- HISTOGRAM: 5ms=78 6ms=16 7ms=4 … 直方图数据
例如:while true;do adb shell dumpsys gfxinfo com.android.home framestat;sleep 1;done|tee swipeHome_dumpgfx.log
然后通过一秒抓一次,递减总帧数,确认每秒绘制的帧数:
重置:
adb shell dumpsys gfxinfo com.android.home reset
抓取:
adb shell dumpsys gfxinfo com.android.home framestats
查看帧率以及如何在systrace分析帧率
1 | adb root |
之后可以在logcat中通过fps
关键字查看帧率
Tips:
- 该帧率为实时帧率,一个动画的首帧和尾帧存在误差,可以忽略
debug.gr.calcfps.period n
:后面的数字n控制统计的帧数- 重启手机后将不再统计帧率
systrace中的Frame
在每个app进程,都有一个Frames行,正常情况以绿色的圆点表示。当圆点颜色为黄色或者红色时,意味着这一帧超过16.6ms(即发现丢帧),点击黄色或红色的Frames圆点便会有相关的提示信息;
另外,在systrace的最右侧,有一个Alerts tab
可以展开,这里记录着所有的的警告提示信息;
也可以通过放大那一帧进一步分析问题。
对于Android 5.0(API level 21)或者更高的设备,该问题主要聚焦在UI Thread
和Render Thread
这两个线程当中
屏幕录制视频(限定时间长)
adb shell screenrecord --time-limit 10 --verbose /sdcard/record.mp4
录屏带--bugreport
调试参数:
adb shell screenrecord --bugreport /sdcard/test.mp4
截图命令
adb shell screencap /sdcard/screencap.png
dump sf查看buffer/layer列表
adb shell dumpsys SurfaceFlinger --list
dump windows/inpu/sf
1 | adb root |
源码打开input debug日志开关
- frameworks/native/services/inputflinger/InputDispatcher.cpp:
bool gInputLogEnabled = false;
改为true - frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java:
static final boolean DEBUG_INPUT = false;
adb打印kernel log,即内核调试信息dmsg和kmsg
Android的log信息分为内核空间和用户空间中LOG,查看用户空间(也就是app等上层的log)的log直接用
adb logcat
就可以如果想过滤一些信息就用
adb logcat | grep -E "log_xxx|log_aaa”
命令,这样log只会显示含有log_aaa和log_xxx的log信息了。上层的log信息另行查看。
执行dmesg命令,可以查看全部消息。如果想把log信息保存到文件,可以用
adb shell dmesg > E:/Kernel.log
(输出内核信息)adb shell cat /proc/kmsg
:程序里面用printk函数打印的信息会显示出来。
用cat /proc/kmsg
命令打印出来的信息跟与dmesg不同。第一次执行/proc/kmsg
打印到当前时间的所有内核信息,再次执行cat /proc/kmsg
,不会再打印已经打印的信息,只打印上一次执行之后打印出来的新的信息。
Tips:查看kernel log时间,前面是秒,然后隔一段时间会打印android time
标记日志
合并kmsg log
adb shell logcat -v time -f /dev/kmsg | adb shell cat /proc/kmsg | tee kernel_logcat.txt
- “-f”选项 : 该选向后面跟着输入日志的文件, 使用
adb logcat -f /sdcard/log.txt
命令, 注意这个log文件是输出到手机上,需要指定合适的路径
例如触屏inpu事件log抓取:
adb shell logcat -v threadtime -f /dev/kmsg | adb shell cat /proc/kmsg | grep -Ei "InputDispatcher|DOWN\!|Up\!|ViewRootImpl|onTouchEvent"
查看设备的白名单
adb shell cat vendor/etc/power_whitelist_cfg.xml
代码添加示例:
1 | //vendor/PLATFORM/proprietary/hardware/power/config/平台型号/power_whitelist_cfg.xml |
Android.mk和Android.bp转换语法
相互转换的定义在:
1 | //该代码Android Q AOSP,在R之后该文件有变化 |
将HIDL接口服务从设备system移到vendor
- 修改Android.bp中添加
vendor:true
(或者vendor_avaiable:ture
);如果是Android.mk,则添加如下:
1 | LOCAL_MODULE_PATH_64 = $(TARGET_OUT_VENDOR)/lib64 |
- 如果有
.rc
文件,则需要修改其中的目录;其中class hal
是不会自动启动的,所以需要将其修改成class main
;并且onrestart restart
后面添加的是service名称。
可以在adb shell;cd /vendor/bin/
里面手动执行bin文件,然后查看进程是否启动。
- 在seploicy添加权限:
device/PLATFORM/sepolicy/basic/non_plat/file_contexts
Android.bp(可参考)
系统将通过以下规则确定cc_library或cc_library_shared的默认安装路径:
将核心变体安装到/system/lib[64]中
供应商变体安装路径可能会有所不同:
如果
vndk.enabled
为false,则将供应商变体将安装到/vendor/lib[64]
中如果
vndk.enabled
为true,则vndk.support_system_process
可以是true或false。如果:- 为false,则供应商变体将安装到
/system/lib[64]/vndk-${VER}
中
- 为false,则供应商变体将安装到
- 为true,则供应商变体将安装到
/system/lib[64]/vndk-sp-${VER}
中
- 为true,则供应商变体将安装到
C函数memset(…)
函数解释:将s中当前位置后面的n个字节
(typedef unsigned int size_t )
用ch替换并返回s
- memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法
- memset()函数原型:是
extern void *memset(void *buffer, int c, int count)
,buffer为指针或是数组,c是赋给buffer的值,count是buffer的长度
domain.te错误类型
错误日志:
The following types on /vendor/ must be associated with the "vendor_file_type" attribute: ×××_exec
- 如果是system/则
type ***_exec, exec_type, system_file_type, file_type;
- 如果是svendor/则
type ***_exec, exec_type, vendor_file_type, file_type;
查看手机硬件设备(包含屏幕信息)
adb shell cat proc/cmdline
ubuntu的ll
命令不能使用
将ll
作为一个别名:
1 | ... |
然后执行source .bash_profile
生效
ubuntu挂载硬盘
- 查看硬盘:
sudo fdisk -l
比如打印:Disk /dev/sdb: 3000.6 GB, 3000592982016 bytes
- 编辑添加到文件:
sudo vim /etc/fstab
比如打印:/dev/sdb /sunwg/ ext4 defaults 0 0 (后面的目录是挂载的目录)
- 重启电脑,然后
df -h
查看系统分区
find命令
find ./ -iname "*gpuinfo*"
## 查看CPU/GPU硬件频率
- 查看CPU:
adb shell "cat /proc/cpufreq/*/cpufreq_freq"
- 查看DDR:
adb shell "cat /sys/devices/platform/10012000.dvfsrc/helio-dvfsrc/dvfsrc_dump | grep -e uv -e khz -e CONTROL -e VCORE_OPP -e DDR_OPP -e LEVEL -e RSV_9"
- 查看GPU频率:
adb shell cat /proc/gpufreq/gpufreq_var_dump
或者adb shell cat /proc/gpufreq/gpufreq_opp_dump
设置GPU频率
1 | adb root; |
☆CPU/GPU信息文件路径
CPU信息是在:/sys/devices/system/cpu
GPU的信息在如下目录查看:/sys/class/kgsl/kgsl-3d0
加大dequeuebuffer数目
有时候从systrace中看到dequeuebuffer耗时长,如果可能和gpu/cpu相关,则可以参照上面的方式对gpu/cpu进行提频;
也可以尝试修改文件:/frameworks/native/services/surfaceflinger/BufferQueueLayer.cpp
mProducer->setMaxDequeuedBufferCount(1); //增加这里值
比如修改为3,看是否有改善
windows cmd过滤log
adb logcat |find "***"
vscode插件
gitlens:可以查看提交
抓取perfetto-trace(替代systrace)
- 打开
开发者选项->系统跟踪->显示‘快捷设置’图块
或者命令方式打开:adb shell am start com.android.traceur/com.android.traceur.MainActivity
- 然后点击“录制跟踪记录”开始抓取
- 点击停止后分享生成文件,或者命令导出:
adb pull data/local/traces
- 使用chrome登录perfetto-trace网站:
https://ui.perfetto.dev/#!/
或者转换成html格式:
1 | // 仅支持python 2.7 且需要GLIBC_2.28版本 |
systrace打开空白或者打不开
在chrome地址栏中输入”chrome:tracing”,然后点击load按钮load你的trace.html文件
atrace转换到html
./systrace.py --from-file 2-1.atrace
结果文件生成2-1.html
systrace的类别和选项(直接添加)
systrace脚本来源:
Android\Sdk\platform-tools\systrace
示例命令:
./systrace.py -b 8000 -t 5 –list-categories="Screen turning on" hal app sched gfx view wm power binder_driver -o systrace.html
options | 描述 |
---|---|
-o < FILE > | 输出的目标文件 |
-t N, –time=N | 执行时间,默认5s |
-b N, –buf-size=N | buffer大小(单位kB),用于限制trace总大小,默认无上限 |
-k < KFUNCS >,–ktrace=< KFUNCS > | 追踪kernel函数,用逗号分隔 |
-a < APP_NAME >,–app=< APP_NAME > | 追踪应用包名,用逗号分隔 |
–from-file=< FROM_FILE > | 从文件中创建互动的systrace |
-e < DEVICE_SERIAL >,–serial=< DEVICE_SERIAL > | 指定设备 |
-l, –list-categories | 列举可用的tags |
category | 描述 |
---|---|
gfx | Graphics |
input | Input |
view | View System |
webview | WebView |
wm | Window Manager |
am | Activity Manager |
sm | Sync Manager |
audio | Audio |
video | Video |
camera | Camera |
hal | Hardware Modules |
app | Application |
res | Resource Loading |
dalvik | Dalvik VM |
rs | RenderScript |
bionic | Bionic C Library |
power | Power Management |
sched | CPU Scheduling |
irq | IRQ Events |
freq | CPU Frequency |
idle | CPU Idle |
disk | Disk I/O |
mmc | eMMC commands |
load | CPU Load |
sync | Synchronization |
workq | Kernel Workqueueszuidi |
几个比较常用的模块:
- sched:CPU调度的信息,非常重要;你能看到CPU在每个时间段在运行什么线程;线程调度情况,比如锁信息
- gfx:Graphic系统的相关信息,包括SurfaceFlinger,VSYNC消息,Texture,RenderThread等;分析卡顿非常依赖这个
- view:View绘制系统的相关信息,比如onMeasure,onLayout等;对分析卡顿比较有帮助
- am:ActivityManager调用的相关信息;用来分析Activity的启动过程比较有效
- dalvik: 虚拟机相关信息,比如GC停顿等
- binder_driver:Binder驱动的相关信息,如果你怀疑是Binder IPC的问题,不妨打开这个
- core_services:SystemServer中系统核心Service的相关信息,分析特定问题用
SElinux权限相关
参考网站程序员大本营selinux
- scontext表示进程的
SContext,u:r:bluetooth:s0
,属于bluetooth域; - tcontext表示目标的
SContext,u:r:system_data_file:s0
,属于system_data_file类型; - tclass表示进程要操作的
ObjectClass
,dir表示目录;
自动生成selinux权限代码
过滤
avc
关键词代码,导入到新文件log.txt需要安装:
policycoreutils
执行命令或区域权限的代码:
cat log.txt | grep avc | audit2al
命令执行后生成权限相关代码,然后进行修改,例如下面:
1 | #============= mcd ============== |
开启/关闭Selinux权限
1 | adb shell setenforce 0 //设置成permissive模式,临时关闭selinux |
重启后失效
使用adb shell getenforce
查看当前权限状态。
可能返回结果有三种:
- Disabled代表SELinux被禁用
- Permissive代表仅记录安全警告但不阻止可疑行
- Enforcing代表记录警告且阻止可疑行为
进入fastboot
adb reboot fastboot
或者
adb reboot bootloader
LCD屏幕低温残影现象
LCD屏幕里的像素发光是由液晶偏转来控制的,而液晶这种材料对温度十分敏感,温度越低,液晶翻转的速度也就越慢,屏幕的响应速度也就会越慢。当画面已经刷新到了下一帧时,液晶还未翻转完成,新生成的画面与未消失的画面错位存在,看上去就像重影一样。
而OLED屏幕的像素点是由一个个单独控制的发光二级管所组成的,低温对其响应速度影响不大,所以单独发光的OLED的响应速度要远高于LCD屏幕。所以OLED屏幕的手机在低温下几乎不会出现拖影的问题。
此外,录屏是录取不到拖影的现象,需要拍视频才能看的到。
makefile
makefile中-D*
表示:#define *
如:-DPOSGP730 等价于 #define POSGP730
亮度单位nit
nit(尼特),1nit=1坎德拉/平方米[cd/m2]
亮度(L)指物体明暗的程度,定义是单位面积的发光强度,是表示眼睛从某一方向所看到物体反射光的强度。
光学单位lux
0.1Lux是指摄像机的照度
Lux是一个光学单位,指的是每平方米的光照亮,可以理解成对光线强度的反应,在同等光线条件下,LUX越小的摄像机感光度越好。
场所/环境 | 光照度 |
---|---|
晴天 | 30000~300000 lux |
晴天室内 | 100~1000 lux |
阴天 | 3000~10000 lux |
阴暗夜晚 | 0.003~0.0007 lux |
夜间路灯 | 0.1 lux |
启动activity/关闭activity
1 | //使用Action方式打开系统设置-输入法设置 |
Git命令
查看代码提交历史(具体到某一行)
git blame SurfaceFlinger.cpp(文件名)
提交代码
git push origin HEAD:refs/for/×××Branch
提交草稿代码
git push origin HEAD:refs/drafts/×××Branch
提交代码、sync代码报错Agent admitted failure to sign using the key
执行:ssh-add ~/.ssh/id_rsa
apt-get报错不能进行正常更新
提示错误信息
The package lists or status file could not be parsed or opened
解决方法:
1 | sudo rm -vf /var/lib/apt/lists/* |
ubuntu自带截图快捷键
1 | Alt + Print Screen #截取选中的窗口 |
gedit乱码
执行:gconftool-2 --set --type=list --list-type=string /apps/gedit-2/preferences/encodings/auto_detected "[UTF-8,CURRENT,GB18030,BIG5-HKSCS,UTF-16]"
跳过开机向导
1 | adb shell settings put secure user_setup_complete 1 |
ubuntu快速下载命令
axel -n 20 下载链接
谷歌GMS服务
GMS(Google Mobile Service),即谷歌移动服务,是Google提供的移动设备上的一系列应用服务,比如包含Play Sotre,Gmail,YouTube,Chrome,Google Maps等。
如果需要预置GMS应用,需要通过Google认证,比如CTS、GTS等跑测。
GMS测试注意事项
- 如果升级应用到最新版本不再复现,则是应用本身的问题,Google在升级过程中已进行修补
- 如果仍旧复现,则使用对比机器进行对比验证
常见问题
开机向导设置密码后关机再开机黑屏
修改方式:
- 找到
frameworks/base/packages/SystemUI/src/com/android/systemui/Keyguard/KeyguardViewMediator.java
- 找到函数
private void doKeyguardLocked(Bundle options)
- 修改
if (!lockedOrMissing && !provisioned && !antiTheftLocked)
—>if(!lockedOrMissing && shouldWaitForProvisioning() && !antiTheftLocked)
Play Store无法正常连接
无法登陆Google账户,提示与Google服务器通信时出现问题
如果可以登录Google账户(设置添加Google账户),而不能进入Google Play,可以抓取一份log,搜索关键字CheckinTask
,如果出现如下log:
E CheckinTask: Checkin failed: https://android.clients.google.com/checkin (request #0): java.io.IOException: Bad Content-Type: text/html; charset=UTF-8
就先检查系统以下属性值的设定是否存在“非法”字符:
1 | ro.product.model |
Play Store下载应用失败
从服务器检索信息时出错 (Error retrieving information from server)
GMS应用首次登陆闪退,第二次正常
闪退问题先Check log中是否收到
PACKAGE_CHANGED的
广播
查看
system log
,Google Maps如果有发生package changed,这是厂商的Maps版本比较旧,开机后联网情况下会自动从server升级造成process kill
,属于正常的行为。关键log如下:
1 | V ActivityManager: Broadcast: Intent { act=android.intent.action.PACKAGE_CHANGED dat=package:com.google.android.apps.maps flg=0x4000010 (has extras) } ordered=false userid=0 callerApp=null |
GMS应用缺少部分菜单
如果系统分区太小,会拿掉一些feature,你可以尝试更大的RAM size,比如1GB或更大。
GMS部分应用联网后消失
GMS中部分应用有地域使用限制,Play Books, Play Magazine, Play Movies等应用目前不支持在中国大陆这边使用,所以联网后应用会自己屏蔽掉,此为正常现象。