WindowManagerService relayoutWindow release surface

345 views
Skip to first unread message

Thành Công Vũ

unread,
Sep 21, 2016, 1:25:02 AM9/21/16
to android-platform
Hello.

I am working on Android Mashmallow 6.0.0_r3 source code.
I am trying to understand how WindowManagerService (WMS), ActivityManagerService (AMS), and Application (ActivityThread) control the visibility of a window.

As I understand, the AMS will call WMS.setAppVisibility() to change the app's visibility when activity stack changes.
Then WMS call dispatchAppVisibility to its client (ActivityThread) to schedule a traversal.
After a short time, doTraversal is executed and application thread send request to WMS through WMS.relayoutWindow() to create/destroy Surface.

I'd like to ask 2 questions:

1. Is my understand correct ?

2. WMS uses win.mAppToken.clientHidden to control whether should create a new surface or destroy/releasing old surface in relayoutWindow().

However, the application thread doesn't know about this variable, then there's a case that application request to be visible (visble=View.VISIBLE) but
WMS releases the surface instead of creating (because clientHidden now changed to true for some reason).
For example: AM try to resume an activity right after pausing it -> no surface is drawn.
So why do we need to check for win.mAppToken.clientHidden in relayoutWindow() ?

Thank you!

Thành Công Vũ

unread,
Oct 24, 2016, 10:50:58 AM10/24/16
to android-platform
Hello.

I have fixed a blackscreen issue caused by mismatched states between mAppVisible (Client) and clientHidden (Server).
I post my patch here in case somebody have the same issue.

Issue occurs when many startActivity() are called continuously in short time (< 150 ms) 
 
ActivityThread                        WindowManagerService
     |                                                    |
     |<--------------------------------dispatchAppVisibility(true)
handleAppVisibility(true)                   |
mAppVisible=true                             |
     |                                                    |
     |<--------------------------------dispatchAppVisibility(false)
     |                                                   |
performTraversals()                         |
relayoutWindow(old=8, new=0)---->|   Error: Releasing surface because clientHidden=true!
     |                                                   |
     |<--------------------------------dispatchAppVisibility(true)
     |
handleAppVisibility(false)
mAppVisible=false
     |
handleAppVisibility(true)
mAppVisible=true
     |
performTraversals()
Error: no relayout is called!

This patch is created and tested on MashMallow, I am not sure it should be applied on Nougat. 
fix_blackscreen.diff
Reply all
Reply to author
Forward
0 new messages