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 ).