ProtoLog开关
在代码中我们经常看见ProtoLog打印的log,如下:
ProtoLog.i(WM_DEBUG_ANIM,"Animation start delayed for %s",mAnimatable);这种log正常情况不会显示,因此我们需要打开开关,其格式为:adb shell wm logging enable-text [代码中对应的TAG]
我们这段代码的TAG是WM_DEBUG_ANIM,因此通过命令adb shell wm logging enable-text WM_DEBUG_ANIM打开log开关
另一种情况
ProtoLog.v(WM_SHELL_TASK_ORG,"Task info changed taskId=%d",taskInfo.taskId);wmshell的log比较特殊,其在SystemUI进程,如果我们直接运行adb shell wm logging enable-text WM_SHELL_TASK_ORG会报错,打印如下:
Loaded749log definitions from /system/etc/protolog.conf.json.gz No IProtoLogGroup named WM_SHELL_TASK_ORG Not handled, please use`adb shell dumpsys activityserviceSystemUIService WMShell`ifyou are lookingforProtoLoginWMShell根据提示我们打开logadb shell dumpsys activity service SystemUIService WMShell protolog enable WM_SHELL_TASK_ORG
logcat抓取log
# 抓取普通的andorid logadb shell logcat>log.txt# 仅抓取events logadb shell logcat-bevents>log.txt# 抓取所有类型logadb shell logcat-ball>log.txt# 根据关键字抓取log,-i可以忽略大小,-e可以添加多条关键字,如下:adb shell logcat-bevents|grep-ie"关键log1"-ie"关键log2">log.txtevents.log中对应代码查找
events log对应代码的规律是:
events log开头的字段,比如wm_xxx
则对应的代码可以通过 grep 抓取 writeWmxxx 找出是在哪里打印的该events log
例如:
应用走到onresume生命周期的logwm_on_resume_called: [223605563,com.tencent.mm.ui.LauncherUI,RESUME_ACTIVITY,10]
EventLogTags.writeWmOnResumeCalled(mIdent,getComponentName().getClassName(),reason);通知cancel的lognotification_canceled: [0|com.tencent.mm|40|null|10218,8,19980,19980,7720,-1,-1,NULL]
EventLogTags.writeNotificationCanceled(canceledKey,reason,r.getLifespanMs(now),r.getFreshnessMs(now),r.getExposureMs(now),rank,count,listenerName);使用winscope
手机要处于root状态才能使用
使用手机自带的winscope
在手机设置里面,找到开发者选项->快捷设置开发者图块->打开 “ Winscope跟踪 ”
打开后复现问题,最后再关闭这个开关,就表示抓取完成
导出文件adb pull /data/misc/wmtrace
把导出文件在源码路径的android-13.0.0_r6/prebuilts/misc/common/winscope/winscope.html打开即可使用脚本抓取winscope(推荐)
附链接:
winscope-t
winscope-u
winscope-v
winscope-t和winscope-u均可离线使用,但是V的版本却不行,需要进行以下操作
1.需要用npm安装http-servernpm install -g http-server
2.安装完成后运行http-server,进入下面任意一个ip即可下载后,连接手机,直接运行脚本中的
./run.sh,或者python3 winscope_proxy.py
START TRACE: 可以持续dump window和SurfaceFlinger信息,一般适用于闪黑场景,复现之前按下,复现后停止即可。
DMUP STATE: 相当于就是抓取一次dumpsys window和dumpsys SurfaceFlingerandroid 15之后离线抓取winscope方法
# SurfaceFlinger# 开启adb shell perfetto--out/data/misc/perfetto-traces/winscope-proxy-trace.perfetto-trace--txt--config/data/misc/perfetto-configs/winscope-proxy-trace.conf--detach=WINSCOPE-PROXY-TRACING-SESSION# 停止adb shell perfetto--attach=WINSCOPE-PROXY-TRACING-SESSION--stop# 导出adb pull /data/misc/perfetto-traces/winscope-proxy-trace.perfetto-trace# 有些设备可能没有winscope-proxy-trace.conf这类conf文件,可以尝试使用Android 15之前的方法adb shellsurootservicecall Surface Flinger1025i321adb shellsurootservicecall Surface Flinger1025i320adb pull /data/misc/wmtrace/layers_trace.pb# window(window的抓取方法在Android15没有变化)# 开启adb shell cmd window tracing start# 停止adb shell cmd window tracing stop# 导出adb pull /data/misc/wmtrace/wm_trace.winscope手机里的 /data/misc/perfetto-configs/中不一定都是以
winscope-proxy-trace.conf命名,比如:/data/misc/perfetto-configs# lswinscope-proxy.surfaceflinger.conf运行指令也可能报错
adb shell perfetto--out/data/misc/perfetto-traces/winscope-proxy-trace.perfetto-trace--txt--config/data/misc/perfetto-configs/winscope-proxy.surfaceflinger.conf--detach=WINSCOPE-PROXY-TRACING-SESSION[191.423]perfetto_cmd.cc:794 TraceConfig's write_into_file must betruewhen using--detach这里提示需要
write_into_file为true设置这个时候就需要我们修改脚本
在原始脚本的脚本的基础上修改即可vi/data/misc/perfetto-configs/winscope-proxy.surfaceflinger.conf data_sources:{config{name:"android.surfaceflinger.layers"surfaceflinger_layers_config:{mode: MODE_ACTIVE trace_flags: TRACE_FLAG_INPUT trace_flags: TRACE_FLAG_COMPOSITION trace_flags: TRACE_FLAG_HWC trace_flags: TRACE_FLAG_BUFFERS}}}# 添加代码解决write_into_file:true
常见dump命令
adb shell dumpsys SurfaceFlinger>./dump/SurfaceFlinger.txt adb shell dumpsys window-a>./dump/window.txt adb shell dumpsys activity activities>./dump/activities.txt adb shell dumpsys activitytop>./dump/top_activity.txt adb shell dumpsys activity containers>./dump/containers.txt adb shell dumpsys input>./dump/input.txt查找dump命令的方法
代码路径:frameworks/base/core/java/android/content/Context.java
这个代码里面有很多serviceName
@StringDef(suffix={"_SERVICE"},value={POWER_SERVICE,//@hide: POWER_STATS_SERVICE,WINDOW_SERVICE,LAYOUT_INFLATER_SERVICE,ACCOUNT_SERVICE,ACTIVITY_SERVICE,ALARM_SERVICE,NOTIFICATION_SERVICE,ACCESSIBILITY_SERVICE,CAPTIONING_SERVICE,KEYGUARD_SERVICE,LOCATION_SERVICE,HEALTHCONNECT_SERVICE,//@hide: COUNTRY_DETECTOR,SEARCH_SERVICE,SENSOR_SERVICE,SENSOR_PRIVACY_SERVICE,STORAGE_SERVICE,STORAGE_STATS_SERVICE,WALLPAPER_SERVICE,VIBRATOR_MANAGER_SERVICE,VIBRATOR_SERVICE,//@hide: STATUS_BAR_SERVICE,CONNECTIVITY_SERVICE,PAC_PROXY_SERVICE,VCN_MANAGEMENT_SERVICE,//@hide: IP_MEMORY_STORE_SERVICE,IPSEC_SERVICE,VPN_MANAGEMENT_SERVICE,TEST_NETWORK_SERVICE,//@hide: UPDATE_LOCK_SERVICE,//@hide: NETWORKMANAGEMENT_SERVICE,NETWORK_STATS_SERVICE,//@hide: NETWORK_POLICY_SERVICE,WIFI_SERVICE,WIFI_AWARE_SERVICE,WIFI_P2P_SERVICE,WIFI_SCANNING_SERVICE,//@hide: LOWPAN_SERVICE,//@hide: WIFI_RTT_SERVICE,//@hide: ETHERNET_SERVICE,WIFI_RTT_RANGING_SERVICE,NSD_SERVICE,AUDIO_SERVICE,AUDIO_DEVICE_VOLUME_SERVICE,AUTH_SERVICE,FINGERPRINT_SERVICE,//@hide: FACE_SERVICE,BIOMETRIC_SERVICE,MEDIA_ROUTER_SERVICE,TELEPHONY_SERVICE,TELEPHONY_SUBSCRIPTION_SERVICE,CARRIER_CONFIG_SERVICE,EUICC_SERVICE,//@hide: MMS_SERVICE,TELECOM_SERVICE,CLIPBOARD_SERVICE,INPUT_METHOD_SERVICE,TEXT_SERVICES_MANAGER_SERVICE,TEXT_CLASSIFICATION_SERVICE,APPWIDGET_SERVICE,//@hide: VOICE_INTERACTION_MANAGER_SERVICE,//@hide: BACKUP_SERVICE,REBOOT_READINESS_SERVICE,ROLLBACK_SERVICE,DROPBOX_SERVICE,//@hide: DEVICE_IDLE_CONTROLLER,//@hide: POWER_WHITELIST_MANAGER,DEVICE_POLICY_SERVICE,UI_MODE_SERVICE,DOWNLOAD_SERVICE,NFC_SERVICE,BLUETOOTH_SERVICE,//@hide: SIP_SERVICE,USB_SERVICE,LAUNCHER_APPS_SERVICE,//@hide: SERIAL_SERVICE,//@hide: HDMI_CONTROL_SERVICE,INPUT_SERVICE,DISPLAY_SERVICE,//@hide COLOR_DISPLAY_SERVICE,USER_SERVICE,RESTRICTIONS_SERVICE,APP_OPS_SERVICE,ROLE_SERVICE,//@hide ROLE_CONTROLLER_SERVICE,CAMERA_SERVICE,//@hide: PLATFORM_COMPAT_SERVICE,//@hide: PLATFORM_COMPAT_NATIVE_SERVICE,PRINT_SERVICE,CONSUMER_IR_SERVICE,//@hide: TRUST_SERVICE,TV_INTERACTIVE_APP_SERVICE,TV_INPUT_SERVICE,//@hide: TV_TUNER_RESOURCE_MGR_SERVICE,//@hide: NETWORK_SCORE_SERVICE,USAGE_STATS_SERVICE,MEDIA_SESSION_SERVICE,MEDIA_COMMUNICATION_SERVICE,BATTERY_SERVICE,JOB_SCHEDULER_SERVICE,//@hide: PERSISTENT_DATA_BLOCK_SERVICE,//@hide: OEM_LOCK_SERVICE,MEDIA_PROJECTION_SERVICE,MIDI_SERVICE,RADIO_SERVICE,HARDWARE_PROPERTIES_SERVICE,//@hide: SOUND_TRIGGER_SERVICE,SHORTCUT_SERVICE,//@hide: CONTEXTHUB_SERVICE,SYSTEM_HEALTH_SERVICE,//@hide: INCIDENT_SERVICE,//@hide: INCIDENT_COMPANION_SERVICE,//@hide: STATS_COMPANION_SERVICE,COMPANION_DEVICE_SERVICE,VIRTUAL_DEVICE_SERVICE,CROSS_PROFILE_APPS_SERVICE,//@hide: SYSTEM_UPDATE_SERVICE,//@hide: TIME_DETECTOR_SERVICE,//@hide: TIME_ZONE_DETECTOR_SERVICE,PERMISSION_SERVICE,LIGHTS_SERVICE,LOCALE_SERVICE,//@hide: PEOPLE_SERVICE,//@hide: DEVICE_STATE_SERVICE,//@hide: SPEECH_RECOGNITION_SERVICE,UWB_SERVICE,MEDIA_METRICS_SERVICE,//@hide: ATTESTATION_VERIFICATION_SERVICE,//@hide: SAFETY_CENTER_SERVICE,DISPLAY_HASH_SERVICE,CREDENTIAL_SERVICE,DEVICE_LOCK_SERVICE,VIRTUALIZATION_SERVICE,GRAMMATICAL_INFLECTION_SERVICE,})我们只需要根据这些常量找到对应的名称即可,比如输入法:
/** * Use with {@link #getSystemService(String)} to retrieve a * {@link android.view.inputmethod.InputMethodManager} for accessing input * methods. * * @see #getSystemService(String) */publicstaticfinalStringINPUT_METHOD_SERVICE="input_method";我们可以看到,其实就是通过getSystemService方法中调用的字符常量,我们要dump输入法服务相关的命令就是adb shell dumpsys input_method
如果我们想知道这个dump的方法具体在哪,会有哪些打印,则只需通过对应Mananger找到对应的ManagerService即可。
比如,我们这里以输入法为例,那么其对应的就是InputMethodManagerService,在这个里面就有对应的dump方法:
代码路径:frameworks/base/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
voiddump(@NonNullPrintWriterpw,@NonNullStringprefix){finalSimpleDateFormatdataFormat=newSimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS",Locale.US);for(inti=0;i<mEntries.length;++i){finalEntryentry=mEntries[(i+mNextIndex)%mEntries.length];if(entry==null){continue;}pw.print(prefix);pw.println("SoftInputShowHideHistory #"+entry.mSequenceNumber+":");pw.print(prefix);pw.println(" time="+dataFormat.format(newDate(entry.mWallTime))+" (timestamp="+entry.mTimestamp+")");pw.print(prefix);pw.print(" reason="+InputMethodDebug.softInputDisplayReasonToString(entry.mReason));pw.println(" inFullscreenMode="+entry.mInFullscreenMode);pw.print(prefix);pw.println(" requestClient="+entry.mClientState);pw.print(prefix);pw.println(" focusedWindowName="+entry.mFocusedWindowName);pw.print(prefix);pw.println(" requestWindowName="+entry.mRequestWindowName);pw.print(prefix);pw.println(" imeControlTargetName="+entry.mImeControlTargetName);pw.print(prefix);pw.println(" imeTargetNameFromWm="+entry.mImeTargetNameFromWm);pw.print(prefix);pw.print(" editorInfo: ");pw.print(" inputType="+entry.mEditorInfo.inputType);pw.print(" privateImeOptions="+entry.mEditorInfo.privateImeOptions);pw.println(" fieldId (viewId)="+entry.mEditorInfo.fieldId);pw.print(prefix);pw.println(" focusedWindowSoftInputMode="+InputMethodDebug.softInputModeToString(entry.mFocusedWindowSoftInputMode));}}}有些命令是带参数的,比如:adb shell dumpsys activity top
可以加上-h来查看所有的命令,如:adb shell dumpsys activity -h
打印结果如下:
Activitymanager dump options:[-a][-c][-pPACKAGE][-h][WHAT]...WHATmay be one of:a[ctivities]:activity stack state r[recents]:recent activities state b[roadcasts][PACKAGE_NAME][history[-s]]:broadcast state broadcast-stats[PACKAGE_NAME]:aggregated broadcast statistics i[ntents][PACKAGE_NAME]:pending intent state p[rocesses][PACKAGE_NAME]:process state o[om]:out of memory management perm[issions]:URIpermission grant state prov[iders][COMP_SPEC...]:content provider state provider[COMP_SPEC]:provider client-side state s[ervices][COMP_SPEC...]:service state allowed-associations:currentpackageassociationrestrictions as[sociations]:tracked app associations exit-info[PACKAGE_NAME]:historical process exit information lmk:stats on low memory killer lru:rawLRUprocess list binder-proxies:stats on binder objects andIPCssettings:currently applied config settings service[COMP_SPEC]:service client-side statepackage[PACKAGE_NAME]:all state relatedtogivenpackageall:dump all activities top:dump the top activity users:user stateWHATmay also be aCOMP_SPECtodumpactivities.COMP_SPECmay be a component name(com.foo/.myApp),a partial substring in a component name,a hex object identifier.-a:include all available server state.-c:include client state.-p:limit outputtogivenpackage.-d:limit outputtogivendisplay.--checkin:output checkin format,resetting data.--C:output checkin format,not resetting data.--proto:output dump in protocol buffer format.--dump-dumpable:dump just theDUMPABLE-related state of anactivity.Usethe--list-dumpables optiontolistthe supportedDUMPABLEs--list-dumpables:show the available dumpables in an activity