ANR问题基于aosp14修改monitor事件导致的复现及测试分析-学员作业

0 阅读3分钟

转载于:ANR问题基于aosp14修改monitor事件导致的复现及测试分析-学员作业

背景:

昨天有相关学员朋友一直在vip群里提出他的一个ANR问题,一直说自己分析这个ANR完全没有相关的头绪 在这里插入图片描述 针对这个ANR问题,我与该学员沟通了解情况后,发现他这种anr问题明显不是常规的那种app某个地方执行耗时导致的卡顿,所以常规那种抓取anr trace来分析定位的套路明显就不行了。 那么他这个anr到底是怎么复现的呢,具体是个啥情况呢?今天马哥来给大家在aosp14上复现该ANR问题然后先提供给大家作为一个课程作业进行完成哈,答案后期会blog或者vip群分享方式给大家。

问题复现:

需要复现该问题,其实需要对系统正常的相关源码进行一些修改才可以,学员朋友也是一样,他修改了相关源码引入了ANR问题,但是又不知道怎么引入的。

修改代码如下: frameworks/base/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java

diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
index 093c09fff995..98a84557dbe7 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
@@ -327,10 +327,10 @@ public class ScreenshotView extends FrameLayout implements
         }
         return touchRegion;
     }
-
+    static int count = 0;
     private void startInputListening() {
-        stopInputListening();
-        mInputMonitor = new InputMonitorCompat("Screenshot", mDefaultDisplay);
+       // stopInputListening();
+        mInputMonitor = new InputMonitorCompat("Screenshot " +(count++), mDefaultDisplay);
         mInputEventReceiver = mInputMonitor.getInputReceiver(
                 Looper.getMainLooper(), Choreographer.getInstance(), ev -> {
                     if (ev instanceof MotionEvent) {
@@ -345,14 +345,14 @@ public class ScreenshotView extends FrameLayout implements
     }
 
     void stopInputListening() {
-        if (mInputMonitor != null) {
-            mInputMonitor.dispose();
-            mInputMonitor = null;
-        }
-        if (mInputEventReceiver != null) {
-            mInputEventReceiver.dispose();
-            mInputEventReceiver = null;
-        }
+//        if (mInputMonitor != null) {
+//            mInputMonitor.dispose();
+//            mInputMonitor = null;
+//        }
+//        if (mInputEventReceiver != null) {
+//            mInputEventReceiver.dispose();
+//            mInputEventReceiver = null;
+//        }
     }
 

简单概述一下修改: 1、针对new InputMonitorCompat和InputEventReceiver前不想进行stopInputListening()调用 2、同时让stopInputListening()方法其他地方也不要调用 即ScreenshotView一旦创建了相关的InputMonitor就不希望它自我销毁掉,会一直存在。 其实看上面修改表面上也没啥问题,就相当于多了一个全局事件监听者InputMonitor会一直监听系统事件而已。

复现ANR步骤 第一步触发截图: 上面修改完成后进行编译运行,但是需要让系统运行到让这个ScreenshotView展示,就需要触发系统截图

这里大家实体机的话可以用组合键截图等,模拟器的话建议就用模拟key事件来截图,截图按键命令:

adb shell input keyevent 120

执行后就会发现有截图动作和窗口产生 在这里插入图片描述

看到这个后说明ScreenshotView相关的InputMonitor已经注册,如果不放心可以用dumpsys命令确认一下:

adb shell dumpsys input | grep Screenshot
    Reason: [Gesture Monitor] Screenshot 0 (server) is not responding. Waited 5000ms for MotionEvent(deviceId=4, eventTime=55126095000, source=TOUCHSCREEN | STYLUS | BLUETOOTH_STYLUS, displayId=0, action=MOVE, actionButton=0x00000000, flags=0x00000000, metaState=0x00000000, buttonState=0x00000000, classification=NONE, edgeFlags=0x00000000, xPrecision=22.8, yPrecision=11.1, xCursorPosition=nan, yCursorPosition=nan, pointers=[0: (844.0, 2242.9)]), policyFlags=0x62000000
    Window: [Gesture Monitor] Screenshot 0 - [Gesture Monitor] Screenshot 0
      1: name='[Gesture Monitor] Screenshot 0', id=110, displayId=0, inputConfig=NOT_FOCUSABLE | TRUSTED_OVERLAY | SPY, alpha=1.00, frame=[0,0][0,0], globalScale=1.000000, applicationInfo.name=[Gesture Monitor] Screenshot 0, applicationInfo.token=<null>, touchableRegion=[-14399,-29599][14400,29600], ownerPid=1965, ownerUid=10111, dispatchingTimeout=5000ms, hasToken=0x73a263ddddd0, touchOcclusionMode=BLOCK_UNTRUSTED
    559: channelName='[Gesture Monitor] Screenshot 0 (server)', windowName='[Gesture Monitor] Screenshot 0 (server)', status=NORMAL, monitor=false, responsive=false

第二步操作:

不断在手机模拟器进行相关的触摸点击操作直到anr产生(预计1分钟以内既可以) 在这里插入图片描述

作业要求:

1、要求可以按上面步骤产生出anr

2、分析出anr的原因

更多framework实战干货,请关注下面公众号“千里马学框架”