Android应用程序窗口(Activity)与WindowManagerService服务的连接过程分析

Android应用程序窗口(Activity)与WindowManagerService服务的连接过程分析

 

Android应用程序窗口(Activity)与WindowManagerService服务的连接过程分析_第1张图片

 

Android应用程序窗口(Activity)与WindowManagerService服务的连接过程分析_第2张图片

 

 Android应用程序窗口(Activity)与WindowManagerService服务的连接过程分析_第3张图片

 


   从图1还可以看出,每一个Activity组件在ActivityManagerService服务内部,都对应有一个ActivityRecord对象,这个ActivityRecord对象是Activity组件启动的过程中创建的,用来描述Activity组件的运行状态,这一点可以参考前面Android应用程序启动过程源代码分析一文。这样,每一个Activity组件在应用程序进程、WindowManagerService服务和ActivityManagerService服务三者之间就分别一一地建立了连接。在本文中,我们主要关注Activity组件在应用程序进程和WindowManagerService服务之间以及在WindowManagerService服务和ActivityManagerService服务之间的连接。


 final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward) {
  getWindowManager
  当应用程序进程启动第一个Activity组件的时候,就会请求WindowManagerService服务发送一个建立连接的Binder进程间通信请求。
  
 wm.addView(decor, l);
public class WindowManagerImpl implements WindowManager {
    ......
 
    public void addView(View view, ViewGroup.LayoutParams params)
    {
WindowManagerGlobal
  public void addView(View view, ViewGroup.LayoutParams params,
            Display display, Window parentWindow) {
            
             root = new ViewRootImpl(view.getContext(), display);
             
             
public class Activity extends ContextThemeWrapper

Activity    ActivityManagerService    WindowManagerService

ViewRootImpl
public final class ViewRootImpl implements ViewParent,

    final IWindowSession mWindowSession;
    
     public ViewRootImpl(Context context, Display display) {
        mContext = context;
        mWindowSession = WindowManagerGlobal.getWindowSession();
        
        
        WindowManagerGlobal (代理IWindowManager)
        public static IWindowSession getWindowSession() {
        
            private static IWindowSession sWindowSession;
            
                IWindowManager windowManager = getWindowManagerService();
                    sWindowSession = windowManager.openSession(
                            new IWindowSessionCallback.Stub() {
                            
                                        if (sWindowManagerService == null) {
                sWindowManagerService = IWindowManager.Stub.asInterface(
                        ServiceManager.getService("window"));
            }
            return sWindowManagerService;
            
            IWindowManager.Stub.asInterface             ServiceManager.getService("window")
            
                            
    
    WindowManagerService(本地 IWindowManager)
 @Override
    public IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client,
            IInputContext inputContext) {    
                 Session session = new Session(this, callback, client, inputContext);
                 代理
                 
    
    IWindowSession
final class Session extends IWindowSession.Stub


Session
     @Override
    public int add(IWindow window, int seq, WindowManager.LayoutParams attrs,
            
            
            IWindowSession
            public interface IWindowSession extends android.os.IInterface
            
            Stub(本地Session实例)
            public static abstract class Stub extends android.os.Binder implements android.view.IWindowSession
            
            
    @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_add:
{
data.enforceInterface(DESCRIPTOR);

Proxy(代理Session实例)
private static class Proxy implements android.view.IWindowSession
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}


@Override public int add(android.view.IWindow window, int seq, android.view.WindowManager.LayoutParams attrs, int viewVisibility, android.graphics.Rect outContentInsets, android.view.InputChannel outInputChannel) throws android.os.RemoteException
{
mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);

        
        
            public class WindowManagerService extends IWindowManager.Stub
            
            
        final class Session extends IWindowSession.Stub

        
        
            ViewRoot
public final class ViewRoot extends Handler implements ViewParent,  

              public void setView(View view, WindowManager.LayoutParams attrs,  

res = sWindowSession.add(mWindow, mWindowAttributes,  
                            getHostVisibility(), mAttachInfo.mContentInsets,  
                            mInputChannel);  
 

public final class ViewRoot extends Handler implements ViewParent,  
        View.AttachInfo.Callbacks {  
    ......
 
    static IWindowSession sWindowSession;
    ......  
  
    final W mWindow;
 
    View mView;  
    ......  
 
    public ViewRoot(Context context) {
        super();
        ......
 
        mWindow = new W(this, context);
        ......
 
    }
 
    ......
  
    public void setView(View view, WindowManager.LayoutParams attrs,  
            View panelParentView) {  
        synchronized (this) {  
            if (mView == null) {  
                mView = view;  
                ......  
                  
                try {  
                    res = sWindowSession.add(mWindow, mWindowAttributes,  
                            getHostVisibility(), mAttachInfo.mContentInsets,  
                            mInputChannel);  
                } catch (RemoteException e) {  
                    ......  
                } finally {  
                    ......
                }  
  
                ......  
            }  
  
            ......  
        }  
    }  
  
    ......  
}  

 

Android应用程序窗口(Activity)与WindowManagerService服务的连接过程分析_第4张图片

WindowManagerService    IWindowSession

dispatch windowAddedLocked

AppWindowToken    WindowState 

public class ActivityStack {

    final ActivityManagerService mService;

    
    private final void startActivityLocked(ActivityRecord r, boolean newTask,
    
    
    mService.mWindowManager.addAppToken(addPos, r, r.task.taskId,

    
    
    mTokenList mTokenMap
    由于参数token描述的是一个Activity组件窗口,因此,函数就会为它创建一个AppWindowToken对象,
    
       atoken = new AppWindowToken(this, token, voiceInteraction);

WindowManagerService       
AppWindowToken

Activity
 ActivityManagerService     ActivityRecord
    
    
    
    WindowManagerImpl(实现类) addView 
    
    
    public class WindowManagerService extends IWindowManager.Stub
        implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
    
    ActivityRecord = AppWindowToken
    

WindowState


Android应用程序窗口(Activity)与WindowManagerService服务的连接过程分析_第5张图片

WindowManagerService服务和ActivityManagerService服务三者之间就分别一一地建立了连接。在本文中,我们主要关注Activity组件在应用程序进程和WindowManagerService服务之间以及在WindowManagerService服务和ActivityManagerService服务之间的连接。


 final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward) {
  getWindowManager
  当应用程序进程启动第一个Activity组件的时候,就会请求WindowManagerService服务发送一个建立连接的Binder进程间通信请求。
  
 wm.addView(decor, l);
public class WindowManagerImpl implements WindowManager {
    ......
 
    public void addView(View view, ViewGroup.LayoutParams params)
    {
WindowManagerGlobal
  public void addView(View view, ViewGroup.LayoutParams params,
            Display display, Window parentWindow) {
            
             root = new ViewRootImpl(view.getContext(), display);
             
             
public class Activity extends ContextThemeWrapper

Activity    ActivityManagerService    WindowManagerService

ViewRootImpl
public final class ViewRootImpl implements ViewParent,

    final IWindowSession mWindowSession;
    
     public ViewRootImpl(Context context, Display display) {
        mContext = context;
        mWindowSession = WindowManagerGlobal.getWindowSession();
        
        
        WindowManagerGlobal (代理IWindowManager)
        public static IWindowSession getWindowSession() {
        
            private static IWindowSession sWindowSession;
            
                IWindowManager windowManager = getWindowManagerService();
                    sWindowSession = windowManager.openSession(
                            new IWindowSessionCallback.Stub() {
                            
                                        if (sWindowManagerService == null) {
                sWindowManagerService = IWindowManager.Stub.asInterface(
                        ServiceManager.getService("window"));
            }
            return sWindowManagerService;
            
            IWindowManager.Stub.asInterface             ServiceManager.getService("window")
            
                            
    
    WindowManagerService(本地 IWindowManager)
 @Override
    public IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client,
            IInputContext inputContext) {    
                 Session session = new Session(this, callback, client, inputContext);
                 代理
                 
    
    IWindowSession
final class Session extends IWindowSession.Stub


Session
     @Override
    public int add(IWindow window, int seq, WindowManager.LayoutParams attrs,
            
            
            IWindowSession
            public interface IWindowSession extends android.os.IInterface
            
            Stub(本地Session实例)
            public static abstract class Stub extends android.os.Binder implements android.view.IWindowSession
            
            
    @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_add:
{
data.enforceInterface(DESCRIPTOR);

Proxy(代理Session实例)
private static class Proxy implements android.view.IWindowSession
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}


@Override public int add(android.view.IWindow window, int seq, android.view.WindowManager.LayoutParams attrs, int viewVisibility, android.graphics.Rect outContentInsets, android.view.InputChannel outInputChannel) throws android.os.RemoteException
{
mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);

        
        
            public class WindowManagerService extends IWindowManager.Stub
            
            
        final class Session extends IWindowSession.Stub

        
        
            ViewRoot
public final class ViewRoot extends Handler implements ViewParent,  

              public void setView(View view, WindowManager.LayoutParams attrs,  

res = sWindowSession.add(mWindow, mWindowAttributes,  
                            getHostVisibility(), mAttachInfo.mContentInsets,  
                            mInputChannel);  

ViewRoot
IWindowSession
W
sWindowSession.add


public final class ViewRoot extends Handler implements ViewParent,  
        View.AttachInfo.Callbacks {  
    ......
 
    static IWindowSession sWindowSession;
    ......  
  
    final W mWindow;
 
    View mView;  
    ......  
 
    public ViewRoot(Context context) {
        super();
        ......
 
        mWindow = new W(this, context);
        ......
 
    }
 
    ......
  
    public void setView(View view, WindowManager.LayoutParams attrs,  
            View panelParentView) {  
        synchronized (this) {  
            if (mView == null) {  
                mView = view;  
                ......  
                  
                try {  
                    res = sWindowSession.add(mWindow, mWindowAttributes,  
                            getHostVisibility(), mAttachInfo.mContentInsets,  
                            mInputChannel);  
                } catch (RemoteException e) {  
                    ......  
                } finally {  
                    ......
                }  
  
                ......  
            }  
  
            ......  
        }  
    }  
  
    ......  
}  

public final class ViewRootImpl implements ViewParent,
  static class W extends IWindow.Stub {
        private final WeakReference mViewAncestor;
        private final IWindowSession mWindowSession;

        
        ViewRoot
        setView
           mWindowSession = WindowManagerGlobal.getWindowSession();
        
        mWindowSession.add
        
        WindowManagerService
         public int addWindow(Session session, IWindow client, int seq,
            WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
            Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
        
        就会通过前面所获得一个Session代理对象来传递给WindowManagerService服务,
        而WindowManagerService服务接收到这个W对象之后,
        就会在内部创建一个WindowState对象来描述与该W对象所关联的Activity组件的窗口状态,
        并且以后就通过这个W对象来控制对应的Activity组件的窗口状态。

        应用程序进程就可以通过保存在ViewRoot类的静态成员变量sWindowSession所描述的一个Session代理对象所实现的IWindowSession接口来与WindowManagerService服务通信,
        
        例如:
        
        WindowManagerService
          public int addWindow(Session session, IWindow client, int seq,
            WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
            Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
            InputChannel outInputChannel) {
        
        
              1. 在Activity组件的启动过程中,调用这个IWindowSession接口的成员函数add可以将一个关联的W对象传递到WindowManagerService服务,以便WindowManagerService服务可以为该Activity组件创建一个WindowState对象。

        2. 在Activity组件的销毁过程中,调用这个这个IWindowSession接口的成员函数remove来请求WindowManagerService服务之前为该Activity组件所创建的一个WindowState对象,这一点可以参考前面Android应用程序键盘(Keyboard)消息处理机制分析一文的键盘消息接收通道注销过程分析。

        3. 在Activity组件的运行过程中,调用这个这个IWindowSession接口的成员函数relayout来请求WindowManagerService服务来对该Activity组件的UI进行布局,以便该Activity组件的UI可以正确地显示在屏幕中。

WindowState
        
        ,后者于是就会得到一个W代理对象,
        并且会以这个W代理对象来创建一个WindowState对象,即将这个W代理对象保存在新创建的WindowState对象的成员变量mClient中
        
        
        W IWindow.Stub   
        
            final IWindow mClient;
        
        
        WindowManagerService extends IWindowManager.Stub
        
        Session extends IWindowSession.Stub(Stub Binder本地)
        
        Stub(本地)    Impl(实现类) Proxy(代理)
        
        attach
        
        

WindowManagerService
        addWindow
         public int addWindow(Session session, IWindow client, int seq,
                WindowState attachedWindow = null;
        
          attachedWindow = windowForClientLocked(null, attrs.token, false);
        
        WindowState win = mWindowMap.get(client);
        
            final HashMap mWindowMap = new HashMap<>();
            
             token = new WindowToken(this, attrs.token, -1, false);
            
                WindowToken(WindowManagerService _service, IBinder _token, int type, boolean _explicit) {
        service = _service;
        token = _token;
        windowType = type;
        explicit = _explicit;
    }
    
     WindowState win = new WindowState(this, session, client, token,
                    attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
    
    
    
    
            if (addToken) {
                mTokenMap.put(attrs.token, token);
            }
            win.attach();
            mWindowMap.put(client.asBinder(), win);
    
    
    
    
     void attach() {
        if (WindowManagerService.localLOGV) Slog.v(
            TAG, "Attaching " + this + " token=" + mToken
            + ", list=" + mToken.windows);
        mSession.windowAddedLocked();
    }

    

        

public class WindowManagerService extends IWindowManager.Stub
        implements Watchdog.Monitor {
    ......
 
    private final class WindowState implements WindowManagerPolicy.WindowState {
        ......
 
        WindowState(Session s, IWindow c, WindowToken token,
               WindowState attachedWindow, WindowManager.LayoutParams a,
               int viewVisibility) {
            mSession = s;
            mClient = c;
            mToken = token;
            mAttrs.copyFrom(a);
            mViewVisibility = viewVisibility;
            DeathRecipient deathRecipient = new DeathRecipient();
            mAlpha = a.alpha;


WindowManagerService IWindowManager.Stub

WindowState WindowManagerPolicy.WindowState 

       -mSession:指向一个类型为Session的Binder本地对象,使用参数s来初始化,表示当前所创建的WindowState对象是属于哪一个应用程序进程的。

        -mClient:指向一个实现了IWindow接口的Binder代理对象,它引用了运行在应用程序进程这一侧的一个类型为W的Binder本地对象,使用参数c来初始化,通过它可以与运行在应用程序进程这一侧的Activity组件进行通信。

        -mToken:指向一个WindowToken对象,使用参数token来初始化,通过它就可以知道唯一地标识一个窗口。

        -mAttrs:指向一个WindowManager.LayoutParams对象,使用参数a来初始化,通过它就可以知道当前当前所创建的WindowState对象所描述的窗口的布局参数。

        -mViewVisibility:这是一个整型变量,使用参数viewVisibility来初始化,表示当前所创建的WindowState对象所描述的窗口视图的可见性。

        -mAlpha:这是一个浮点数,使用参数a所描述的一WindowManager.LayoutParams对象的成员变量alpha来初始化,表示当前所创建的WindowState对象所描述的窗口的Alpha通道。


            WindowState appWin = this;
            while (appWin.mAttachedWindow != null) {
                appWin = mAttachedWindow;
            }
            WindowToken appToken = appWin.mToken;
            while (appToken.appWindowToken == null) {
                WindowToken parent = mTokenMap.get(appToken.token);
                if (parent == null || appToken == parent) {
                    break;
                }
                appToken = parent;
            }
            mRootToken = appToken;
            mAppToken = appToken.appWindowToken;


WindowState   mAttachedWindow  WindowToken    appWindowToken  

WindowToken       appToken      appWindowToken  

public class WindowManagerService extends IWindowManager.Stub
        implements Watchdog.Monitor {

private final class Session extends IWindowSession.Stub


void windowAddedLocked() {
            if (mSurfaceSession == null) {
                ......
                mSurfaceSession = new SurfaceSession();
                ......
                mSessions.add(this);
            }
            mNumWindow++;
        }

    
    WindowManagerService  IWindowManager.Stub
    
    Session IWindowSession.Stub
    
    mSurfaceSession = new SurfaceSession
    mSessions.add(this);
    
    
static void SurfaceSession_init(JNIEnv* env, jobject clazz)
{
    sp client = new SurfaceComposerClient;
    client->incStrong(clazz);
    env->SetIntField(clazz, sso.client, (int)client.get());
}

sp


struct sso_t {
    jfieldID client;
};
static sso_t sso;

它是一个类型为sso_t的结构体变量,它的成员变量client描述的是SurfaceSession类的成员变量mClient在SurfaceSession类中的偏移量:

void nativeClassInit(JNIEnv* env, jclass clazz)
{
    ......
 
    jclass surfaceSession = env->FindClass("android/view/SurfaceSession");
    sso.client = env->GetFieldID(surfaceSession, "mClient", "I");
 
    ......
}


env->FindClass()    env-GetFieldID surfaceSession mClient
mRootToken   

    至此,我们也分析完成Android应用程序窗口与WindowManagerService服务的连接过程了。从这个连接过程以及前面Android应用程序窗口(Activity)的窗口对象(Window)的创建过程分析和Android应用程序窗口(Activity)的视图对象(View)的创建过程分析这两篇文章,我们就可以知道,为了实现一个Activity组件的UI,无论是应用程序进程,还是WindowManagerService,都做了大量的工作,例如,应用程序进程为它创建一个窗口(Window)对象、一个视图(View)对象、一个ViewRoot对象、一个W对象,WindowManagerService服务为它创建一个AppWindowToken对象和一个WindowState对象。此外,WindowManagerService服务还为一个Activity组件所运行在的应用程序进程创建了一个Session对象。理解这些对象的实现以及作用对我们了解Android应用程序窗口的实现框架以及WindowManagerService服务的实现原理都是非常重要的。

       虽然到目前为止,我们已经为Android应用程序窗口创建了很多对象,但是我们仍然还有一个最重要的对象还没有创建,那就是Android应用程序窗口的绘图表面,即用来渲染UI的Surface还没有创建。从前面Android应用程序与SurfaceFlinger服务的关系概述和学习计划这一系列的文章可以知道,这个Surface是要请求SurfaceFlinger服务来创建的,因此,在接下来的一篇文章中,我们就将继续分析Android应用程序窗口的绘图表面(Surface)的创建过程,敬请关注!


 

        
        
        
        
        
        
        

你可能感兴趣的:(framework)