Communication Process between Android applications and WMS services

Source: Internet
Author: User

We know that the WindowManagerService is running in the SystemServer process. When an application starts an Activity, WMS needs to request WMS to create a corresponding window for the Activity to be started, and WMS is also responsible for modifying window properties, therefore, cross-process interaction between application processes and WMS services is involved. We have introduced the Binder communication mechanism in Android. The application process interacts with the SystemServer process by using the Binder communication method.


Every Activity started in an application process has a ViewRootImpl object:

Frameworks \ base \ core \ java \ android \ view \ ViewRootImpl. java

<喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4KPHByZSBjbGFzcz0 = "brush: java;"> public ViewRootImpl (Context context, Display display) {// create a Session Binder object in WMS, at the same time, return the Binder proxy object to the current application process and save it to the member variable mWindowSession = WindowManagerGlobal in ViewRootImpl. getWindowSession ();... // create a W Binder object for each ViewRootImpl object for the WMS service to access the corresponding ActivitymWindow = new W (this );... mAttachInfo = new View. attachInfo (mWindowSession, mWindow, display, this, mHandler, this );... mChoreographer = Choreographer. getInstance ();... loadSystemProperties ();}


1. establish a connection between the application and the WMS Service
As shown in the figure above, to enable the application process to request the WMS service, you must create a Session-Type Binder local object on the WMS Service side, at the same time, the application obtains the Session proxy object, through which the application process can request the WMS service. Frameworks \ base \ core \ java \ android \ view \ WindowManagerGlobal. java
Public static IWindowSession getWindowSession () {synchronized (WindowManagerGlobal. class) {if (sWindowSession = null) {try {InputMethodManager imm = InputMethodManager. getInstance (); // obtain the proxy object IWindowManager windowManager = getWindowManagerService () of the WindowManagerService service. // you can use the WindowManagerService proxy object request to create a Session local object sWindowSession = windowManager in WMS. openSession (imm. getClient (), imm. getInputContext (); float animatorScale = windowManager. getAnimationScale (2); ValueAnimator. setDurationScale (animatorScale);} catch (RemoteException e) {Log. e (TAG, "Failed to open window session", e) ;}} return sWindowSession ;}}
The function first obtains the proxy object of the WMS service through getWindowManagerService. Because the WMS service is a famous Binder object, it has been registered to the ServiceManager process, therefore, you can query the service to obtain the WMS proxy object.
public static IWindowManager getWindowManagerService() {synchronized (WindowManagerGlobal.class) {if (sWindowManagerService == null) {sWindowManagerService = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));}return sWindowManagerService;}}
After obtaining the proxy object of the WMS service, you can request the WMS service to create a Session Binder local object, which is used by the application process to access the WMS service. This section does not describe how the application process uses the WMS proxy object to request WMS to create a Session. This is a remote function call process in the Binder communication mechanism. After calling the openSession function of the WMS proxy object, the openSession function of WMS is implemented as follows: frameworks \ base \ services \ java \ com \ android \ server \ wm \ WindowManagerService. java
public IWindowSession openSession(IInputMethodClient client,IInputContext inputContext) {if (client == null) throw new IllegalArgumentException("null client");if (inputContext == null) throw new IllegalArgumentException("null inputContext");Session session = new Session(this, client, inputContext);return session;}
A Session object is constructed and returned to the application process. In this way, the Session proxy IWindowSession can be obtained from the application. proxy and save it in the member variable mWindowSession of the ViewRootImpl object.
2. establish a connection between the WMS service and the application process
The connection process between the application process and the WMS service is introduced earlier. Although the ViewRootImpl object in the application process has obtained the proxy object of the Session in the WMS service, that is to say, the application process can request the WMS service, but the WMS service still cannot request the application process. How can we establish a bidirectional connection between the application process and the WMS service? In the previous ViewRootImpl constructor, a W-type object is created, and W implements the IWindow interface. WMS requests the application process through the proxy object of W. How does the WMS service obtain the proxy object of W? Frameworks \ base \ core \ java \ android \ view \ ViewRootImpl. java
Public void setView (View view, WindowManager. layoutParams attrs, View panelParentView) {synchronized (this) {if (mView = null) {mView = view ;... // mWindow is W local object res = mWindowSession. addToDisplay (mWindow, mSeq, m1_wattributes, getHostVisibility (), mDisplay. getDisplayId (), mAttachInfo. mContentInsets, mInputChannel );... if (mInputChannel! = Null) {if (mInputQueueCallback! = Null) {mInputQueue = new InputQueue (); queue. Queue (mInputQueue);} mInputEventReceiver = new queue winputeventreceiver (mInputChannel, loput. myLooper ());}...}}}
As described in the previous section, the member variable mWindowSession of the ViewRootImpl object saves the Session proxy object. The first parameter passed to the addToDisplay function is the member variable mWindow, the mWindow stores the W-Type Binder local object, so the W proxy object can be passed to the WMS service through the addToDisplay function. Frameworks \ base \ services \ java \ com \ android \ server \ wm \ Session. java
public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,int viewVisibility, int displayId, Rect outContentInsets,InputChannel outInputChannel) {return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId,outContentInsets, outInputChannel);}
Session receives a function call request from an application process and transfers the request to WMS. The relationship between sessions and WMS services is as follows: frameworks \ base \ services \ java \ com \ android \ server \ wm \ WindowManagerService. java
Public int addWindow (Session session, IWindow client, int seq, WindowManager. layoutParams attrs, int viewVisibility, int displayId, Rect outContentInsets, InputChannel outInputChannel ){... windowToken token = mTokenMap. get (attrs. token); if (token = null ){... token = new WindowToken (this, attrs. token,-1, false); addToken = true; // application window} else if (type> = FIRST_APPLICATION_WINDOW & type <= LAST_APPLIC ATION_WINDOW) {AppWindowToken atoken = token. appWindowToken ;... // Input Method window} else if (type = TYPE_INPUT_METHOD ){... // wallpaper window} else if (type = TYPE_WALLPAPER ){...} else if (type = TYPE_DREAM ){...} // create the WindowState object win = new WindowState (this, session, client, token, attachedWindow, appOp [0], seq, attrs, viewVisibility, displayContent );... win. setShowToOwnerOnlyLocked (mPolicy. checkShowToOwnerOnl Y (attrs); res = mPolicy. prepareAddWindowLw (win, attrs);... if (outInputChannel! = Null & (attrs. inputFeatures & WindowManager. layoutParams. INPUT_FEATURE_NO_INPUT_CHANNEL) = 0) {String name = win. makeInputChannelName (); InputChannel [] inputChannels = InputChannel. openInputChannelPair (name); win. setInputChannel (inputChannels [0]); inputChannels [1]. transferTo (outInputChannel); mInputManager. registerInputChannel (win. mInputChannel, win. minput?whandle );}... if (addToken) {// The mTokenMap hash table stores all WindowToken objects mTokenMap. put (attrs. token, token);} win. attach (); // The mWindowMap hash table stores all WindowState objects and W proxy objects as key-value pairs:
 
  
MWindowMap. put (client. asBinder (), win); if (win. mAppOp! = AppOpsManager. OP_NONE) {if (mAppOps. startOpNoThrow (win. mAppOp, win. getOwningUid (), win. getOwningPackage ())! = AppOpsManager. MODE_ALLOWED) {win. setAppOpVisibilityLw (false );}}...}...}
 
This function first creates the corresponding WindowState object for the window added by the application process in the WMS service, and receives the Session of the application process in WMS, the W proxy object in the application process is saved to WindowState.
WindowState (WindowManagerService service, Session s, IWindow c, WindowToken token, WindowState attachedWindow, int appOp, int seq, WindowManager. layoutParams a, int viewVisibility, final DisplayContent displayContent) {mService = service; // identifies WMS service mSession = s; // identifies the local Session Object mClient = c of the process that receives the application; // W proxy object mAppOp = appOp; mToken = token; // TokenmOwnerUid = s that identifies the window layout parameters in the application process. mUid; mWindowId = new IWindowId. stub () {@ Overridepublic void registerFocusObserver (IWindowFocusObserver observer) {WindowState. this. registerFocusObserver (observer) ;}@ Overridepublic void unregisterFocusObserver (IWindowFocusObserver observer) {WindowState. this. unregisterFocusObserver (observer) ;}@ Overridepublic boolean isFocused () {return WindowState. this. isFocused ();}};...}
When constructing a WindowState object, an IWindowId local object is created to identify the specified window. Therefore, the application process will surely obtain the proxy object of the object. The IWindowId proxy object acquisition process is analyzed later. After creating the corresponding WindowState object for the specified window in the application process in WMS, call the attach () function of the object: frameworks \ base \ services \ java \ com \ android \ server \ wm \ WindowState. java
void attach() {if (WindowManagerService.localLOGV) Slog.v(TAG, "Attaching " + this + " token=" + mToken+ ", list=" + mToken.windows);mSession.windowAddedLocked();}
When constructing a WindowState object, save the local Session object used to receive application process requests in the mSession member variable of WindowState. The windowAddedLocked () of the Session is called here () creates a SurfaceSession object that requests SurfaceFlinger, and saves the Session that receives the application process request to the mSessions array of WMS.
Frameworks \ base \ services \ java \ com \ android \ server \ wm \ Session. java
void windowAddedLocked() {if (mSurfaceSession == null) {mSurfaceSession = new SurfaceSession();mService.mSessions.add(this);}mNumWindow++;}

3. IWindowId proxy object acquisition process
During the construction of the WindowState object, an IWindowId local object is created and saved in the mWindowId member variable of WindowState. Therefore, the application process also obtains the IWindowId proxy object used to identify each window object. Frameworks \ base \ core \ java \ android \ view \ View. java
Public WindowId getWindowId () {if (mAttachInfo = null) {return null;} if (mAttachInfo. mWindowId = null) {try {/** get the IWindowId proxy object of the WMS server. mAttachInfo creates * mWindow = new W (this) when creating the ViewRootImpl object ); * mAttachInfo = new View. attachInfo (mWindowSession, mWindow, display, this, mHandler, this); * in the constructor of AttachInfo: * mWindow = window; * mWindowToken = window. asBinder (); * therefore, the member variables mWindow and mWindowToken of AttachInfo reference the same object. This object is a local binder object of type W. * The following uses the local binder object W, to obtain the proxy object of the IWindowId of the AMS server */mAttachInfo. mIWindowId = mAttachInfo. mSession. getWindowId (mAttachInfo. mWindowToken); The WindowId class is defined to facilitate the transmission of IWindowId Binder object mAttachInfo between processes. mWindowId = new WindowId (mAttachInfo. mIWindowId);} catch (RemoteException e) {}} return mAttachInfo. mWindowId ;}
The application process obtains the IWindowId proxy object through the Session proxy object. The parameter window is the local binder object W on the application process side. After the Binder is transmitted to the WMS service process, it is converted to the binder proxy object of W. Frameworks \ base \ services \ java \ com \ android \ server \ wm \ Session. java
public IWindowId getWindowId(IBinder window) {return mService.getWindowId(window);}
The Session local object in the WMS Service sends the IWindowId object search process to the WMS service. Frameworks \ base \ services \ java \ com \ android \ server \ wm \ WindowManagerService. java
Public IWindowId getWindowId (IBinder token) {synchronized (mWindowMap) {// find the corresponding WindowState object from the mWindowMap hash table through the binder proxy object of W. WindowState window = mWindowMap. get (token); return window! = Null? Window. mWindowId: null ;}}
Find the WindowState object corresponding to the window in WMS based on W's binder proxy object token, and then return the IWindowId Binder local object created in the window in the WindowState object. In this way, the client process can obtain the proxy object of the Binder.

The search process is as follows:
Through the above introduction, we can know that the interaction between application processes and WMS services is mainly completed through three interfaces: IWindowSession, Iwindow, and IWindowId, IWindowSession implements communication between application processes and WMS services, while Iwindow and IWindowId implement communication between WMS services and application processes.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.