introduce
The black screen problem is a comprehensive problem related to display, involving the Android application layer, framework layer and underlying SurfaceFlinger, screen display and other fields. Here are some basic judgments to locate the black screen problem:
(1) If the screen does not light up and the backlight is 0, you need to analyze it from the perspective of power and screen display first.
(2) The screen is black, but you can take a three-finger screenshot, power key + If you press the volume down button to take a screenshot, and the screenshot is displayed normally (not a black image), you need to analyze it from the perspective of the screen display first (
3) If the video and camera display black screen, you need to confirm the codec and reading display problems first
(4) Application interface locality Black block, a certain control is black, confirm the view problem of the application
Common analysis methods
Starting from the display system, the software architecture is layered from top to bottom. The black screen problem is mainly divided into application field, window field, SF & screen display & bottom soft field. To analyze the black screen problem, first confirm which interface (layer) the black screen is, and then Only after confirming the cause of the black interface; the analysis methods mainly use dump data, Activity life cycle, systrace, raw data of screenshots, window drawing status, video operations, etc.
dumpsys SurfaceFlinger > SurfaceFlinger .txt
Confirm that the current dump SurfaceFlinger data corresponds to the time point of the black screen phenomenon.
First, confirm whether the layer synthesized and displayed by HWC layers is the application layer that should be displayed when the black screen is corresponding; then, check whether there is a focused layer and whether the layer corresponds to the required display. layer; then, check whether the position, size, and rotation angle are normal.
If the screen goes black when you start an application, and the layer of the current SurfaceFlinger .txt does not exist in the layer of the application, you need to further confirm whether the data in the display buffer is normal.
As can be seen from the SurfaceFlinger .txt dump data above, BufferStateLayer represents the current drawing window, and ContainerLayer is its parent container. There will be no drawing buffer. The parent and child are formed from top to bottom hierarchical trees; the drawing buffer of BufferStateLayer is activeBuffer, where you can It can be seen that the drawing has been completed, but the drawing status is not completed: activeBuffer=[0x 0: 0,Unknown/None] .
+ BufferStateLayer (com.example.mysystemdialog/com.example.mysystemdialog.MainActivity#117) uid=10117
Region TransparentRegion (this=0 count=0)
Region VisibleRegion (this=0 count=1)
[ 0, 0, 1440, 2960]
Region SurfaceDamageRegion (this=0 count=0)
layerStack= 0, z= 0, pos=(0,0), size=(1440,2960), crop=[ 0, 0, 0, 0], cornerRadius=0.000000, isProtected=0, isTrustedOverlay=0, isOpaque=0, invalidate=0, dataspace=Default, defaultPixelFormat=RGBA_8888, backgroundBlurRadius=0, color=(0.000,0.000,0.000,1.000), flags=0x00000100, tr=[0.00, 0.00][0.00, 0.00]
parent=9f63fd7 com.example.mysystemdialog/com.example.mysystemdialog.MainActivity#116
zOrderRelativeOf=none
activeBuffer=[0x0:0,Unknown/None], tr=[0.00, 0.00][0.00, 0.00] queued-frames=0 metadata={
dequeueTime:97987454113, windowType:1, ownerPID:2202, ownerUID:10117}, cornerRadiusCrop=[0.00, 0.00, 0.00, 0.00], shadowRadius=0.000,
In addition, we also need to focus on two parameters: color and flags. The last parameter of color represents alpha. If this parameter is 0, the layer will not be displayed; the flag parameter is visible in the last bit of the binary state. Sex, 1 means invisible, 0 means visible. It can also be summarized as if the flag is an even number, it means that the layer is visible, and if it is an odd number, it means that the layer is not visible.
View the corresponding layer content by using irfanview https://www.irfanview.com/
dumpsys window -a > window .txt
If there is no corresponding layer display in the previous dump sf.txt, you can check the data of the dump window to confirm the window display status of the corresponding application. Search Window # to find the corresponding Window.
The corresponding Window here is my own application interface. The above information describes the basic information of the window. The key point is to pay attention to mDrawState=HAS_DRAWN. mDrawState is the drawing state of the window. HAS_DRAWN means that WMS has completed the display process of the window. Among them, the two states of NO_SURFACE and DRAW_PENDING indicate that the application side has not completed the corresponding surface application and drawing. Such problems need to be checked by the application side; COMMIT_DRAW_PENDING and READY_TO_SHOW, which indicate that the application side has completed drawing and reported the status to WMS, require WMS to check the display. Control the process.
The two variables isOnScreen=true and isVisible=true are also very important to confirm that the current window is visible and displayed on the screen; others, such as requesting width and height, frame size, and position, can also be confirmed one by one.
For the window process, see: WMS window related process
adb shell dumpsys activity activities > activities.txt
Dumpsys activity activities can confirm the display status of the currently started activity. This data is traversed from top to bottom, from Task to the activity inside, and the activity information includes which application it belongs to, who started it, which Intent it passed, etc. Among them, to confirm whether the window of the activity is drawn normally, mainly depends on the information mNumInterestingWindows=1 mNumDrawnWindows=1 allDrawn=true.
mNumInterestingWindows represents the number of windows that require drawing, and mNumDrawnWindows represents the number of windows that have completed drawing. All 1 here indicates that the drawing has been completed. You can see a lot of information here, for example:
Keyguard's display status
InsetsState status
Display areas z order
adb shell dumpsys activity top > top_activity.txt
When the application starts with a black screen, you can use the raw tool to confirm that the application drawing and sending frames are black. You can also find the problematic activity and compare it with the View Hierarchy of the dump activity top to compare whether it is loaded normally.
activity life cycle, event.log
Analyze the activity life cycle through event.log to confirm whether the application's activity has executed onResume, whether the focus has been switched to the focus window, and even if the application has anr, etc.
Analysis steps
There are many analysis methods, just analyze according to personal habits
Confirm the problem phenomenon
Observe the black screen process by recording the screen and confirm the problem time point.
If you take a screenshot of the black screen phenomenon during the recording process and find that the screenshot is normal but the screen is black, you can directly determine that it is a screen display problem.
dump key log
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 activity top > ./dump/top_activity.txt
adb shell dumpsys activity containers > ./dump/containers.txt
adb shell dumpsys activity input > ./dump/input.txt
Find the problem window
You can find the problem window through SurfaceFlinger and window of dump
Analyze dump information
In no particular order
1、SurfaceFlinger
① Check whether there is a corresponding layer in SurfaceFlinger, that is, whether it is synthesized and displayed. If not, you can check the dump window first, see step 2. ② If there is
a layer, find the corresponding Layer and BufferStateLayer by id.
We can see that there is a string after Layer. Hexadecimal number, you can find the corresponding raw file in the log file. Use the irfanview tool to see the layer content. If the screen itself is black, it is most likely an application problem. See steps 2 and 3 for further confirmation.
Display indicates which screen is active. Let’s look at activie’s hwc layers . The layer with SurfaceView represents the content displayed by the application. Common video, game and other applications have this layer. Whether the layer is displayed mainly depends on its BufferStateLayer. activeBuffer, flag
activeBuffer=[0x 0: 0,Unknown/None] indicates the unfinished drawing status.
An even number indicates that the layer is visible, and an odd number indicates that the layer is invisible. For example: flags=0x00000100 indicates that it is visible.
2、window
Find the window in question and check the key parameters
mDrawState. Confirm the window drawing status
isOnScreen and isVisible. The current window is already visible and displayed on the screen.
NO_SURFACE and DRAW_PENDING indicate that the application has not completed the corresponding surface application and drawing. Such problems It needs to be checked by the application side; COMMIT_DRAW_PENDING and READY_TO_SHOW, which means that the application side has completed drawing and reported the status to WMS, requires WMS to check the display control process.
Window display related methods | Explanation of work content |
---|---|
addWindow | The App requests WMS to add a window record and will create a new WindowState (NO_SURFACE) in WMS. |
relayoutWindow | App applies for a surface from WMS for drawing. After execution, the window owns the surface (NO_SURFACE->DRAW_PENDING) |
finishDrawingWindow | After the App completes drawing on the surface, it notifies WMS (DRAW_PENDING->COMMIT_DRAW_PENDING) |
commitFinishDrawingLocked | WMS traverses the window, for the window that has completed drawing (COMMIT_DRAW_PENDING->READY_TO_SHOW) |
performShowLocked | Determine whether the system allows the window to be displayed isReadyForDisplay(READY_TO_SHOW->HAS_DRAWN) |
showSurfaceRobustlyLocked | For the window in the HAS_DRAWN state, use SurfaceControl to notify SurfaceFlinger to display it. |
If the drawing state is not displayed on the dump, you can search in the log: * windowmanager.mDrawState
3、activity top
Compare the normal dump and check whether there are any abnormalities in the View Hierarchy: hierarchical tree.
4. Life cycle
Search wm_ and input_focus in event.log to check whether the application life cycle has reached onresume and whether the window focus is normal (Focus entering has reached focus)
5. Other abnormal logs
For example, common ANR, OOM, etc.
Case
Douyin black screen
1. The input and output data of video playback is normal
2. There is no Douyin layer in the dump SurfaceFlinger
3. The mDrawState in the dump SurfaceFlinger is NO_SURFACE
4. The application life cycle has reached the onresume process, the current focus window is empty, and it is the same as the previous NO_SURFACE
5 .Check whether there is any abnormal log in the log and find out that there is OOM (OutOfMemoryError)