android display 笔记(三)WMS

用来记录学习wms,后续会一点一点更新。。。。。。
代码:android14

WMS是在SystemServer进程中启动的

在SystemServer中的main方法中,调用run方法。
在这里插入图片描述

private void run() {
// Initialize native services.初始化服务,加载android_servers so库
870              System.loadLibrary("android_servers");
// Create the system service manager.创建SystemServiceManager
895              mSystemServiceManager = new SystemServiceManager(mSystemContext);

942              startOtherServices(t);//android14在startOtherServices中启动WindowManagerService

android14中,在startOtherServices中启动WindowManagerService

1606              wm = WindowManagerService.main(context, inputManager, !mFirstBoot,
1607                      new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);

该代码执行了WMS的main方法,会在内部创建一个WMS。其中有一个参数inputManager也是在startOtherServices中创建的,如下。

1589              t.traceBegin("StartInputManagerService");
1590              inputManager = new InputManagerService(context);

总结,WMS的main方法在startOtherServices中,而startOtherServices在SystemServer的run方法中,运行在system_server线程中。

1608              ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
1609                      DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
1610              ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
1611                      /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);

上述代码将WMS和IMS注册到ServerManager中。
回到上述的WindowManagerService main中。
/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

1137      public static WindowManagerService main(final Context context, final InputManagerService im,
1138              final boolean showBootMsgs, WindowManagerPolicy policy, ActivityTaskManagerService atm,
1139              DisplayWindowSettingsProvider displayWindowSettingsProvider,
1140              Supplier<SurfaceControl.Transaction> transactionFactory,
1141              Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) {
1142          final WindowManagerService[] wms = new WindowManagerService[1];
1143          DisplayThread.getHandler().runWithScissors(() ->
1144                  wms[0] = new WindowManagerService(context, im, showBootMsgs, policy, atm,
1145                          displayWindowSettingsProvider, transactionFactory,
1146                          surfaceControlFactory), 0);
1147          return wms[0];
1148      }

DisplayThread.getHandler().runWithScissors调用DisplayThread的getHandler方法,获得DisplayThread的handler实例。
可以用来处理需要低延时显示的相关操作。

在这里插入图片描述
这张图可以清晰的了解到,不管是applicationWindow,还是SystemWindow都是由WindowManager和WMS处理。

addwindow

 public int addWindow(Session session, IWindow client, LayoutParams attrs, int viewVisibility,
1432              int displayId, int requestUserId, @InsetsType int requestedVisibleTypes,
1433              InputChannel outInputChannel, InsetsState outInsetsState,
1434              InsetsSourceControl.Array outActiveControls, Rect outAttachedFrame,
1435              float[] outSizeCompatScale) {

int res = mPolicy.checkAddPermission(attrs.type, isRoundedCornerOverlay, attrs.packageName,
1441                  appOp);

上述通过checkAddpermission方法来检测权限,如果没有权限则不会执行后续代码。

1457              final DisplayContent displayContent = getDisplayContentOrCreate(displayId, attrs.token);

上述代码中有一个参数:displayId,该参数获得窗口添加到哪个DisplayContent上。

 if (displayContent == null) {
1460                  ProtoLog.w(WM_ERROR, "Attempted to add window to a display that does "
1461                          + "not exist: %d. Aborting.", displayId);
1462                  return WindowManagerGlobal.ADD_INVALID_DISPLAY;
1463              }

如果displatContent等于null,则会返回一个ADD_INVALID_DISPLAY无效的状态,类似的还有成功的状态,这些状态都在WindowManagerGlobal中被定义。在这里插入图片描述

  if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) {
1478                  parentWindow = windowForClientLocked(null, attrs.token, false);
1479                  if (parentWindow == null) {
1480                      ProtoLog.w(WM_ERROR, "Attempted to add window with token that is not a window: "
1481                              + "%s.  Aborting.", attrs.token);
1482                      return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
1483                  }

上述的一个判断,type代码窗口类型,它介于FIRST_SUB_WINDOW和LAST_SUB_WINDOW之间,FIRST_SUB_WINDOW和LAST_SUB_WINDOW值定义在windowmanger中
在这里插入图片描述

通常Window有三种类型,以及它们的值范围分别是:
Application Window(应用窗口) 1-99
Sub Window(子窗口)1000-1999
System Window(系统窗口)2000-2999

所以上述可以看出上述窗口是一个子窗口。

1478                  parentWindow = windowForClientLocked(null, attrs.token, false);

看一下windowforclientLocked方法

6033      final WindowState windowForClientLocked(Session session, IWindow client, boolean throwOnError) {
6034          return windowForClientLocked(session, client.asBinder(), throwOnError);
6035      }
6036  
6037      final WindowState windowForClientLocked(Session session, IBinder client, boolean throwOnError) {
6038          WindowState win = mWindowMap.get(client);
6039          if (DEBUG) Slog.v(TAG_WM, "Looking up client " + client + ": " + win);
6040          if (win == null) {
6041              if (throwOnError) {
6042                  throw new IllegalArgumentException(
6043                          "Requested window " + client + " does not exist");
6044              }
6045              ProtoLog.w(WM_ERROR, "Failed looking up window session=%s callers=%s", session,
6046                      Debug.getCallers(3));
6047              return null;
6048          }
6049          if (session != null && win.mSession != session) {
6050              if (throwOnError) {
6051                  throw new IllegalArgumentException("Requested window " + client + " is in session "
6052                          + win.mSession + ", not " + session);
6053              }
6054              ProtoLog.w(WM_ERROR, "Failed looking up window session=%s callers=%s", session,
6055                      Debug.getCallers(3));
6056              return null;
6057          }
6058  
6059          return win;
6060      }

根据attrs.token作为key值从mWindowMap中得到该子窗口的父窗口,如果win父类窗口等于null会返回错误。

 WindowToken token = displayContent.getWindowToken(
1525                      hasParent ? parentWindow.mAttrs.token : attrs.token);

通过displayContent的getWindowToken方法获得WindowToken

 if (token == null) {
1535                  if (!unprivilegedAppCanCreateTokenWith(parentWindow, callingUid, type,
1536                          rootType, attrs.token, attrs.packageName)) {
1537                      return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
1538                  }

......

1585              } else if (rootType == TYPE_INPUT_METHOD) {
1586                  if (token.windowType != TYPE_INPUT_METHOD) {
1587                      ProtoLog.w(WM_ERROR, "Attempted to add input method window with bad token "
1588                              + "%s.  Aborting.", attrs.token);
1589                      return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
1590                  }
                  } else if (rootType == TYPE_VOICE_INTERACTION) {
1592                  if (token.windowType != TYPE_VOICE_INTERACTION) {
1593                      ProtoLog.w(WM_ERROR, "Attempted to add voice interaction window with bad token "
1594                              + "%s.  Aborting.", attrs.token);
1595                      return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
1596                  }
1597              } else if (rootType == TYPE_WALLPAPER) {
1598                  if (token.windowType != TYPE_WALLPAPER) {
1599                      ProtoLog.w(WM_ERROR, "Attempted to add wallpaper window with bad token "
1600                              + "%s.  Aborting.", attrs.token);
1601                      return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
1602                  }
1603              } else if (rootType == TYPE_ACCESSIBILITY_OVERLAY) {
1604                  if (token.windowType != TYPE_ACCESSIBILITY_OVERLAY) {
1605                      ProtoLog.w(WM_ERROR,
1606                              "Attempted to add Accessibility overlay window with bad token "
1607                                      + "%s.  Aborting.", attrs.token);
1608                      return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
1609                  }

如果token为空,则做些判断,如果rootType等于TYPE_INPUT_METHOD等时,会返回ADD_BAD_APP_TOKEN状态值。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

那天的烟花雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值