Monday, September 27, 2010

PhonewindowManager - Some details.

Some details and information i would like to share about some framework related on window managers, phone window managers. It might be a insight to dig more by first come learners .. !!

The three important managers interlinked for an application to be displayed are

– Window manager

(frameworks/base/services/java/com/android/server/WindowManagerService.java)
(frameworks/base/core/java/android/view/WindowManager.java)

– Surface manager / Surface flinger

(frameworks/base/libs/surfacelinger)

–Activity manager

(frameworks/base/services/java/com/android/server/am/ActivityManagerService.java)


All the three are started as thread by main proc “SystemServer”, when the system starts.

Window manager

– Asks the surface manager to create layout surfaces on behalf of client application.

– Dispatches input events to client.

– Transitions animations

[ The window manager creates surfaces for the application, and applications draw directly into those surfaces without going through the window manager.]

Surface manager

– Allocates surfaces ( means creation of memory,front end, back end buffers for application to draw its layout ).

– Interacts with OpenGL.

Activity Manager

– Manages life cycles of activities, stacking of activities.

– Takes care of intent dispatching.

There are two window manager implemented one for phone (phoneWindow manager) and another for mid (midWindow manager which is obselete now).

Window - Is a abstract base class for a top-level window look and behavior policy. An instance of this class should be used as the top-level view added to the window manager. It provides standard UI policies such as a background, title area, default key processing, etc.

The only existing implementation of this abstract class is android.policy.PhoneWindow, which you should instantiate when needing a Window.So it is designed like when an application is started, the activity manager(ActivityThread main loop ) gets the handle and requests creation of a PhoneWindow for the application on which the application's layouts will be drawn with the surface manager as said earlier.



The instantiation of PhoneWindow is provided in /frameworks/policies/base/phone/com/android/internal/policy.java file.

public PhoneWindow makeNewWindow(Context context) {
return new PhoneWindow(context);
}

public PhoneLayoutInflater makeNewLayoutInflater(Context context) {
return new PhoneLayoutInflater(context);
}

public PhoneWindowManager makeNewWindowManager() {
return new PhoneWindowManager();
}



When the window manager is started by SystemServer, it instantiates the deamon kind of thread named 'PhoneWindowManager ' which manages each 'phoneWindow'.What are the activities it manages and for phoneWindow ?

– Starts the power manager intially when the window manager instantiates this class.

– Intercepts / Handles the keys like Home,Back,Menu,Search, Keyguard, Media Key up and down. All these keys will be given to each PhoneWindow. So all the interactions on these keys will be handled here.

– Long press of Home button shows Recent apps dialog.

– Behavior of the power button,long press on KeyGaurd shows this dialog.

– Behavior of how to handle END_BUTTON_BEHAVIOR(Call button),INCALL_POWER_BUTTON_BEHAVIOR,ACCELEROMETER_ROTATION,SCREEN_OFF_TIMEOUT,DEFAULT_INPUT_METHOD . Basically it registers for the above contentRegister URIs.

– Adds the startingWindow ( a phoneWindow ) for an application. Basically to this window object,views are added to display the content.



public View addStartingWindow(IBinder appToken, String packageName, int theme, CharSequence nonLocalizedLabel,
int labelRes, int icon) {
Window win = PolicyManager.makeNewWindow(context); --> lin 867
----------------------
win.getDecorView(); --> Asks the 'PhoneWindow' to get the view
}


When an application is started, activity manager and window manager handles creation of 'PhoneWindow'. I havenot figured out why two windows are created.


1- Created by WindowManager (PhoneWindowManager ) :
------------------------------------------------------


I/ActivityManager( 60): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.HelloWorld/.HelloWorld }
V/PhoneWindowManager( 60): addStartingWindow com.android.HelloWorld: nonLocalizedLabel=null theme=0
D/dalvikvm( 60): GC_FOR_MALLOC freed 10917 objects / 494680 bytes in 133ms
I/PhonePolicy( 60): Making new Phone Window
I/PhonePolicy( 60): java.lang.RuntimeException
I/PhonePolicy( 60): at com.android.internal.policy.impl.Policy.makeNewWindow(Policy.java:59)
I/PhonePolicy( 60): at com.android.internal.policy.impl.Policy.makeNewWindow(Policy.java:33)
I/PhonePolicy( 60): at com.android.internal.policy.PolicyManager.makeNewWindow(PolicyManager.java:58)
I/PhonePolicy( 60): at com.android.internal.policy.impl.PhoneWindowManager.addStartingWindow(PhoneWindowManager.java:867)
I/PhonePolicy( 60): at com.android.server.WindowManagerService$H.handleMessage(WindowManagerService.java:9007)
I/PhonePolicy( 60): at android.os.Handler.dispatchMessage(Handler.java:99)
I/PhonePolicy( 60): at android.os.Looper.loop(Looper.java:123)
I/PhonePolicy( 60): at com.android.server.WindowManagerService$WMThread.run(WindowManagerService.java:570)


2 – Activity manager asks for a new PhoneWindow.
---------------------------------------------------


I/PhonePolicy( 279): Making new Phone Window
I/PhonePolicy( 279): java.lang.RuntimeException
I/PhonePolicy( 279): at com.android.internal.policy.impl.Policy.makeNewWindow(Policy.java:59)
I/PhonePolicy( 279): at com.android.internal.policy.impl.Policy.makeNewWindow(Policy.java:33)
I/PhonePolicy( 279): at com.android.internal.policy.PolicyManager.makeNewWindow(PolicyManager.java:58)
I/PhonePolicy( 279): at android.app.Activity.attach(Activity.java:3746)
I/PhonePolicy( 279): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2610)
I/PhonePolicy( 279): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
I/PhonePolicy( 279): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
I/PhonePolicy( 279): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
I/PhonePolicy( 279): at android.os.Handler.dispatchMessage(Handler.java:99)
I/PhonePolicy( 279): at android.os.Looper.loop(Looper.java:123)
I/PhonePolicy( 279): at android.app.ActivityThread.main(ActivityThread.java:4627)
I/PhonePolicy( 279): at java.lang.reflect.Method.invokeNative(Native Method)
I/PhonePolicy( 279): at java.lang.reflect.Method.invoke(Method.java:521)
I/PhonePolicy( 279): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
I/PhonePolicy( 279): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
I/PhonePolicy( 279): at dalvik.system.NativeStart.main(Native Method)


setContentView()

– Whenever an setContentView() is called in application's main activity, it will be given to PhoneWindow instance to create the view and display it.At this point, window manager talk to surface manager to draw the layouts on to the Window. This fundamental is common for all applications in Android.



public class HelloWorld extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}





V/PhoneWindow( 279): Phonewindow generateLayout
V/PhoneWindow( 279): java.lang.RuntimeException
V/PhoneWindow( 279): at com.android.internal.policy.impl.PhoneWindow.generateLayout(PhoneWindow.java:2058)
V/PhoneWindow( 279): at com.android.internal.policy.impl.PhoneWindow.installDecor(PhoneWindow.java:2234)
V/PhoneWindow( 279): at com.android.internal.policy.impl. PhoneWindow.setContentView(PhoneWindow.java:200)
V/PhoneWindow( 279): at android.app.Activity.setContentView(Activity.java:1647)
V/PhoneWindow( 279): at com.android.HelloWorld.HelloWorld.onCreate(HelloWorld.java:13)
V/PhoneWindow( 279): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
V/PhoneWindow( 279): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
V/PhoneWindow( 279): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
V/PhoneWindow( 279): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
V/PhoneWindow( 279): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
V/PhoneWindow( 279): at android.os.Handler.dispatchMessage(Handler.java:99)
V/PhoneWindow( 279): at android.os.Looper.loop(Looper.java:123)
V/PhoneWindow( 279): at android.app.ActivityThread.main(ActivityThread.java:4627)
V/PhoneWindow( 279): at java.lang.reflect.Method.invokeNative(Native Method)
V/PhoneWindow( 279): at java.lang.reflect.Method.invoke(Method.java:521)
V/PhoneWindow( 279): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
V/PhoneWindow( 279): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
V/PhoneWindow( 279): at dalvik.system.NativeStart.main(Native Method)



PhoneWindowManager and PhoneWindow – Plays a major role in framework to display the content of view, talk to surface manager and handles common utilities which a window ( in otherwords an application) can get. Like, menu,back, call, media keys handling.

There many ways we can set a View to an activity. One way is to create a LinearLayout?FrameLayout add it to a ViewGroup then add the ViewGroup to Window to display it. This is followed in showing Lock screen.

The hierarchy between them is as follows,

onCreate()
Activty --------------------------> Window
|
setContentView(View v, LayoutParams p) - Set a view to a Window.

View --> ViewGroup --> LinearLayout/FrameLayout.
|
|
|
addview(View , LayoutParams ) ( This is inherited to all subclasses )



Example to explain:
------------------------------


public class HelloWorld extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
View v = new MyLinearLayoutView(this);
setContentView(v);
}

}

public class MyLinearLayoutView extends LinearLayout
{
public MyLinearLayoutView(Context context)
{
super(context);
this.setOrientation(LinearLayout.VERTICAL);

\ TextView welcome = new TextView(context);
welcome.setTypeface(Typeface.SANS_SERIF, Typeface.BOLD);
welcome.setText("Welcome screen");

TextView content = new TextView(context);
content.setTypeface(Typeface.SANS_SERIF, Typeface.BOLD);
content.setText("This is a LinearLayout");

LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
this.addView(welcome,params);
this.addView(content,params);
}
}


If you dont specify the LayoutParams the default will be set as
new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT);

This is the same methodology which will be followed in the flow of creating LockScreen,UnlockScreen. In this way, to the 'PhoneWindow' instance addView( is used to set the content for the window ).

8 comments:

  1. Excellent post. Thank you very much. You have helped me a lot.

    ReplyDelete
  2. Hey great post,
    i had a question and was wondering if you could be of some help to my understanding of the android GUI system.

    Im working on an android-x86 project that ports an xegl like server running a sub-compositor (a sub-surfaceMG) in android to run beside the current surfaceMG strictly for GUP accel purposes. An issue i ran into with this method, is i didn't want to make the xegl server have any communication with the standard surfaceMG. What i had in mind was if possible have the xegl ran its own sub compositing manager that would somehow interact with the android windowMG. This way we can have two systems and depending on the application requirements it define the path window manager takes (i.e surfaceMG or the X implementation). Since it ideally starts at window manager, i was wondering does my sub-compositor running with xegl have to pass surfaces to the window manager, my understand was that window manager requests for a surface from surface manager, so its not ideally dependant on a specific surface manager but if i was to make my own implementation of a sub-surface manager, is it possible that i can have window manager deal both situations? ie does window manager strictly deal with surfaces only.
    Or is it best to have a separate window manager deals with my compositor. this wouldn't be ideal, i dont think its even possible to have 2 window manager running simultaneously.

    ReplyDelete
  3. Excellent post..It helped me lot in understanding..thanks

    ReplyDelete
  4. Excellent post
    it helps me to understand how android app activity communicate with framework classes

    ReplyDelete
  5. Awesome.. Helped me a lot.. can u provide me the info abt keyguard manager..????

    ReplyDelete
  6. This comment has been removed by a blog administrator.

    ReplyDelete
  7. Awesome article!! I am basically trying to understand the window manager and all the components associated with it from framework perspective. If you know about any further detailed documentation on window manager please suggest.

    ReplyDelete