美文网首页
WMS:概述

WMS:概述

作者: 81bad73e9053 | 来源:发表于2016-12-05 20:51 被阅读305次

    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相关的窗口信息进行记录。

    相关文章

      网友评论

          本文标题:WMS:概述

          本文链接:https://www.haomeiwen.com/subject/pydlmttx.html