WMS:概述

2016-12-05  本文已影响305人  81bad73e9053

1.WMS的启动

wm = WindowManagerService.main(context, power, display, inputManager,
        uiHandler, wmHandler,
        factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,
        !firstBoot, onlyCore);
//把自己注册到ServiceManager里        
ServiceManager.addService(Context.WINDOW_SERVICE, wm);

2.WMS的基础功能概览

interface IWindowManager
{ 
    // This is used for debugging
    boolean startViewServer(int port);   // Transaction #1
    boolean stopViewServer();            // Transaction #2
    boolean isViewServerRunning();       // Transaction #3
    //openSession
    IWindowSession openSession(in IInputMethodClient client,
            in IInputContext inputContext);
    boolean inputMethodClientHasFocus(IInputMethodClient client);
    //display相关
    void getInitialDisplaySize(int displayId, out Point size);
    void getBaseDisplaySize(int displayId, out Point size);
    void setForcedDisplaySize(int displayId, int width, int height);
    void clearForcedDisplaySize(int displayId);
    int getInitialDisplayDensity(int displayId);
    int getBaseDisplayDensity(int displayId);
    void setForcedDisplayDensity(int displayId, int density);
    void clearForcedDisplayDensity(int displayId); 
    void setOverscan(int displayId, int left, int top, int right, int bottom);

    // Is the device configured to have a full system bar for larger screens?
    boolean hasSystemNavBar(); 
    void pauseKeyDispatching(IBinder token);
    void resumeKeyDispatching(IBinder token);
    void setEventDispatching(boolean enabled);
    void addWindowToken(IBinder token, int type);
    void removeWindowToken(IBinder token);
    //AppToken
    void addAppToken(int addPos, IApplicationToken token,
            int groupId, int requestedOrientation, boolean fullscreen, boolean showWhenLocked);
    void setAppGroupId(IBinder token, int groupId);
    void setAppOrientation(IApplicationToken token, int requestedOrientation);
    int getAppOrientation(IApplicationToken token);
    void setFocusedApp(IBinder token, boolean moveFocusNow);
    void prepareAppTransition(int transit, boolean alwaysKeepCurrent);
    int getPendingAppTransition();
    void overridePendingAppTransition(String packageName, int enterAnim, int exitAnim,
            IRemoteCallback startedCallback);
    void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
            int startHeight);
    void overridePendingAppTransitionThumb(in Bitmap srcThumb, int startX, int startY,
            IRemoteCallback startedCallback, boolean scaleUp);
    void executeAppTransition();
    void setAppStartingWindow(IBinder token, String pkg, int theme,
            in CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
            int icon, int windowFlags, IBinder transferFrom, boolean createIfNeeded);
    void setAppWillBeHidden(IBinder token);
    void setAppVisibility(IBinder token, boolean visible);
    void startAppFreezingScreen(IBinder token, int configChanges);
    void stopAppFreezingScreen(IBinder token, boolean force);
    void removeAppToken(IBinder token);
    void moveAppToken(int index, IBinder token);
    void moveAppTokensToTop(in List<IBinder> tokens);
    void moveAppTokensToBottom(in List<IBinder> tokens);

    // Re-evaluate the current orientation from the caller's state.
    // If there is a change, the new Configuration is returned and the
    // caller must call setNewConfiguration() sometime later.
    Configuration updateOrientationFromAppTokens(in Configuration currentConfig,
            IBinder freezeThisOneIfNeeded);
    void setNewConfiguration(in Configuration config);

    void startFreezingScreen(int exitAnim, int enterAnim);
    void stopFreezingScreen();

    // these require DISABLE_KEYGUARD permission
    void disableKeyguard(IBinder token, String tag);
    void reenableKeyguard(IBinder token);
    void exitKeyguardSecurely(IOnKeyguardExitResult callback);
    boolean isKeyguardLocked();
    boolean isKeyguardSecure();
    boolean inKeyguardRestrictedInputMode();
    void dismissKeyguard();
    void closeSystemDialogs(String reason);
    // These can only be called with the SET_ANIMATON_SCALE permission.
    float getAnimationScale(int which);
    float[] getAnimationScales();
    void setAnimationScale(int which, float scale);
    void setAnimationScales(in float[] scales);
    void setInTouchMode(boolean showFocus);
    void showStrictModeViolation(boolean on);
    void setStrictModeVisualIndicatorPreference(String enabled);
    // These can only be called with the SET_ORIENTATION permission.
    void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout);
    //rotation 
    int getRotation(); 
    int watchRotation(IRotationWatcher watcher); 
    void removeRotationWatcher(IRotationWatcher watcher); 
    int getPreferredOptionsPanelGravity(); 
    void freezeRotation(int rotation); 
    void thawRotation();
    boolean isRotationFrozen();
     //屏幕截图
    Bitmap screenshotApplications(IBinder appToken, int displayId, int maxWidth, int maxHeight);
    //statusbar可见性变化通知wms
    void statusBarVisibilityChanged(int visibility);
    boolean waitForWindowDrawn(IBinder token, in IRemoteCallback callback);    
    boolean hasNavigationBar();    
    void lockNow(in Bundle options);  
    IBinder getFocusedWindowToken();   
    void setInputFilter(in IInputFilter filter);  
    void getWindowFrame(IBinder token, out Rect outFrame);   
    boolean isSafeModeEnabled(); 
    void showAssistant();   
    void setMagnificationCallbacks(IMagnificationCallbacks callbacks);    
    void setMagnificationSpec(in MagnificationSpec spec);  
    MagnificationSpec getCompatibleMagnificationSpecForWindow(in IBinder windowToken);
}

3.WMS的工作方式

TU 10-2WMS工作方式简图

4.WMS AMS与Activity之间的关系

4.1IPC通信

Activity和AMS之间属于进程间通信
WMS和AMS实际上驻留在同一个进程中,所以理论上市可以进行直接函数调用的。

应用程序访问WMS###

应用程序访问WMS先通过ServiceManager,因为WMS是一个实名BinderServer,此外,WMS还针对每个Activity提供一种匿名的实现IWindowSession(类似SurfaceFlinger的Client)。

WMS和SurfaceFlinger是面向系统中所有应用程序服务的,如果客户的任何小请求都需要直接反应给他们,那么无疑会增加两者的负担,进而影响到系统的整体响应速度,所以WMS通过IWindowManager::openSession()向外界开放一个打开session的接口,(ISession在Server端的实现是Session)然后客户一些琐碎的杂事就找Session解决了,如ViewRoot的构造

public ViewRootImpl(Context context, Display display) { 
    mWindowSession = WindowManagerGlobal.getWindowSession();

    public static IWindowSession getWindowSession() {
        synchronized (WindowManagerGlobal.class) {
            if (sWindowSession == null) {
                try {
                    InputMethodManager imm = InputMethodManager.getInstance();
                    IWindowManager windowManager = getWindowManagerService();
                    sWindowSession = windowManager.openSession(
                            imm.getClient(), imm.getInputContext());
                    float animatorScale = windowManager.getAnimationScale(2);
                    ValueAnimator.setDurationScale(animatorScale);
                } catch (RemoteException e) { 

                }
            }
            return sWindowSession;
        }
    }

WMS访问应用程序###

WMS对应用程序的访问通过匿名Binder来完成;
在应用程序进程中通过openSession来建立与WMS的私有链接;
紧接着它会调用IWindowSession::relayout(IWindow window...),这个函数的第一个参数就是由应用程序提供的用于WMS回访应用程序的匿名BinderServer,IWindow在应用程序中的实现是W类

static class W extends IWindow.Stub{
    //......
}

W提供了包括resized,dispatchAppVisibility,dispatchScreenState在内的一系列回调接口,用于WMS实时通知应用进程界面上的变化。

4.2内部组织方式

TU 10-4 Activity在AMS和WMS中的组织和管理

当一个新的Activity被启动时,首先需要在AMS中注册,此时AMS会在内部生成一个ActivityRecord来记录这个Activity;WMS则会用AppWindowToken来对应AMS中的一个ActivityRecord
另外,因为Activity是专门用于UI显示的,所以WMS也会用WindowState对Activity相关的窗口信息进行记录。

上一篇下一篇

猜你喜欢

热点阅读