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