当前位置:   article > 正文

窗口大小计算之androidp Test_layoutwindowlw

layoutwindowlw

  1. /** {@inheritDoc} */
  2. @Override
  3. public void layoutWindowLw(WindowState win, WindowState attached, DisplayFrames displayFrames) {
  4. // We've already done the navigation bar, status bar, and all screen decor windows. If the
  5. // status bar can receive input, we need to layout it again to accommodate for the IME
  6. // window. //不处理状态栏,NavigationBar,以及mScreenDecorWindows包含的装饰WindowState,因为在begin中已经处理了
  7. if ((win == mStatusBar && !canReceiveInput(win)) || win == mNavigationBar
  8. || mScreenDecorWindows.contains(win)) {
  9. return;
  10. }
  11. Slog.d("layoutWL:", "win =" + win.mDisplayWidth + " =" + win.mDisplayHeight
  12. + " =" + win.mRotation + " =" + win.mRotation);
  13. final WindowManager.LayoutParams attrs = win.getAttrs();
  14. final boolean isDefaultDisplay = win.isDefaultDisplay();
  15. final boolean needsToOffsetInputMethodTarget = isDefaultDisplay &&
  16. (win == mLastInputMethodTargetWindow && mLastInputMethodWindow != null);
  17. if (needsToOffsetInputMethodTarget) {
  18. if (DEBUG_LAYOUT) Slog.i(TAG, "Offset ime target window by the last ime window state");
  19. offsetInputMethodWindowLw(mLastInputMethodWindow, displayFrames);
  20. }
  21. final int type = attrs.type;
  22. final int fl = PolicyControl.getWindowFlags(win, attrs);
  23. final int pfl = attrs.privateFlags;
  24. final int sim = attrs.softInputMode;
  25. final int requestedSysUiFl = PolicyControl.getSystemUiVisibility(null, attrs);
  26. final int sysUiFl = requestedSysUiFl | getImpliedSysUiFlagsForLayout(attrs);
  27. // WindowManager: Compute frame com.coagent.launcher/com.coagent.launcher.MainActivity:
  28. //sim=#120 attach=null type=1 flags=0x89810100 pf=[0,0][1280,480] df=[0,0][1280,480] of=[0,0][1280,480]
  29. //cf=[96,0][1280,480] vf=[96,0][1280,480] dcf=[0,0][1280,480] sf=[96,0][1280,480] osf=null
  30. final Rect pf = mTmpParentFrame; //初始化当前的区域
  31. final Rect df = mTmpDisplayFrame;
  32. final Rect of = mTmpOverscanFrame;
  33. final Rect cf = mTmpContentFrame;
  34. final Rect vf = mTmpVisibleFrame;
  35. final Rect dcf = mTmpDecorFrame;
  36. final Rect sf = mTmpStableFrame;
  37. Rect osf = null;
  38. dcf.setEmpty();
  39. final boolean hasNavBar = (isDefaultDisplay && mHasNavigationBar
  40. && mNavigationBar != null && mNavigationBar.isVisibleLw());
  41. final int adjust = sim & SOFT_INPUT_MASK_ADJUST;
  42. final boolean requestedFullscreen = (fl & FLAG_FULLSCREEN) != 0
  43. || (requestedSysUiFl & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0;
  44. final boolean layoutInScreen = (fl & FLAG_LAYOUT_IN_SCREEN) == FLAG_LAYOUT_IN_SCREEN;
  45. final boolean layoutInsetDecor = (fl & FLAG_LAYOUT_INSET_DECOR) == FLAG_LAYOUT_INSET_DECOR;
  46. sf.set(displayFrames.mStable);
  47. 如果当前是输入法区域,所有区域先设置为输入对应的mDock区域
  48. if (type == TYPE_INPUT_METHOD) {
  49. vf.set(displayFrames.mDock); //mDock=Rect(96, 0 - 1280, 480)
  50. cf.set(displayFrames.mDock);
  51. of.set(displayFrames.mDock);
  52. df.set(displayFrames.mDock);
  53. pf.set(displayFrames.mDock);
  54. // IM dock windows layout below the nav bar...
  55. pf.bottom = df.bottom = of.bottom = displayFrames.mUnrestricted.bottom;
  56. // ...with content insets above the nav bar
  57. cf.bottom = vf.bottom = displayFrames.mStable.bottom;
  58. if (mStatusBar != null && mFocusedWindow == mStatusBar && canReceiveInput(mStatusBar)) {
  59. // The status bar forces the navigation bar while it's visible. Make sure the IME
  60. // avoids the navigation bar in that case. //状态栏上的输入法,需要减去导航在左、右的位置
  61. if (mNavigationBarPosition == NAV_BAR_RIGHT) {
  62. pf.right = df.right = of.right = cf.right = vf.right =
  63. displayFrames.mStable.right;
  64. } else if (mNavigationBarPosition == NAV_BAR_LEFT) {
  65. pf.left = df.left = of.left = cf.left = vf.left = displayFrames.mStable.left;
  66. }
  67. }
  68. // IM dock windows always go to the bottom of the screen.
  69. attrs.gravity = Gravity.BOTTOM;
  70. mDockLayer = win.getSurfaceLayer();
  71. } else if (type == TYPE_VOICE_INTERACTION) {
  72. of.set(displayFrames.mUnrestricted);
  73. df.set(displayFrames.mUnrestricted);
  74. pf.set(displayFrames.mUnrestricted);
  75. if (adjust != SOFT_INPUT_ADJUST_RESIZE) {
  76. cf.set(displayFrames.mDock); // mDock=Rect(96, 0 - 1280, 480)
  77. } else {
  78. cf.set(displayFrames.mContent); //mContent=Rect(96, 0 - 1280, 260)
  79. }
  80. if (adjust != SOFT_INPUT_ADJUST_NOTHING) {
  81. vf.set(displayFrames.mCurrent); //mCurrent=Rect(96, 0 - 1280, 171)
  82. } else {
  83. vf.set(cf);
  84. }
  85. } else if (type == TYPE_WALLPAPER) {
  86. layoutWallpaper(displayFrames, pf, df, of, cf);
  87. } else if (win == mStatusBar) {
  88. of.set(displayFrames.mUnrestricted);
  89. df.set(displayFrames.mUnrestricted);
  90. pf.set(displayFrames.mUnrestricted);
  91. cf.set(displayFrames.mStable);
  92. vf.set(displayFrames.mStable);
  93. if (adjust == SOFT_INPUT_ADJUST_RESIZE) {
  94. cf.bottom = displayFrames.mContent.bottom;
  95. } else {
  96. cf.bottom = displayFrames.mDock.bottom;
  97. vf.bottom = displayFrames.mContent.bottom;
  98. }
  99. } else { //其他(如Activity,Dialog对应的窗口(PhoneWindow),或者启动窗口等等。内容型窗口
  100. dcf.set(displayFrames.mSystem);
  101. final boolean inheritTranslucentDecor =
  102. (attrs.privateFlags & PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR) != 0;
  103. final boolean isAppWindow =
  104. type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW;
  105. final boolean topAtRest =
  106. win == mTopFullscreenOpaqueWindowState && !win.isAnimatingLw();
  107. if (isAppWindow && !inheritTranslucentDecor && !topAtRest) {
  108. if ((sysUiFl & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0
  109. && (fl & FLAG_FULLSCREEN) == 0
  110. && (fl & FLAG_TRANSLUCENT_STATUS) == 0
  111. && (fl & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0 //沉浸式状态栏、导航栏
  112. && (pfl & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND) == 0) {
  113. // Ensure policy decor includes status bar
  114. dcf.top = displayFrames.mStable.top;
  115. }
  116. if ((fl & FLAG_TRANSLUCENT_NAVIGATION) == 0
  117. && (sysUiFl & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0
  118. && (fl & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0) { //非沉浸式状态栏、导航栏
  119. // Ensure policy decor includes navigation bar ,decor包括navicd
  120. dcf.bottom = displayFrames.mStable.bottom; //mStable是不包括状态栏和navi的
  121. dcf.right = displayFrames.mStable.right;
  122. }
  123. }
  124. if (layoutInScreen && layoutInsetDecor) { //非全屏窗口
  125. if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle()
  126. + "): IN_SCREEN, INSET_DECOR");
  127. // This is the case for a normal activity window: we want it to cover all of the
  128. // screen space, and it can take care of moving its contents to account for screen
  129. // decorations that intrude into that space.
  130. if (attached != null) { //win所描述的一个非全屏的Activity窗口附加在其它窗口上,有父窗口
  131. // If this window is attached to another, our display
  132. // frame is the same as the one we are attached to.
  133. setAttachedWindowFrames(win, fl, adjust, attached, true, pf, df, of, cf, vf,
  134. displayFrames);
  135. } else {
  136. if (type == TYPE_STATUS_BAR_PANEL || type == TYPE_STATUS_BAR_SUB_PANEL) {
  137. // Status bar panels are the only windows who can go on top of the status
  138. // bar. They are protected by the STATUS_BAR_SERVICE permission, so they
  139. // have the same privileges as the status bar itself.
  140. //
  141. // However, they should still dodge the navigation bar if it exists.
  142. pf.left = df.left = of.left = hasNavBar
  143. ? displayFrames.mDock.left : displayFrames.mUnrestricted.left;
  144. pf.top = df.top = of.top = displayFrames.mUnrestricted.top; //top,没有Navi在顶部的,只能在左右下
  145. pf.right = df.right = of.right = hasNavBar
  146. ? displayFrames.mRestricted.right
  147. : displayFrames.mUnrestricted.right;
  148. pf.bottom = df.bottom = of.bottom = hasNavBar
  149. ? displayFrames.mRestricted.bottom
  150. : displayFrames.mUnrestricted.bottom;
  151. if (DEBUG_LAYOUT) Slog.v(TAG, String.format(
  152. "Laying out status bar window: (%d,%d - %d,%d)",
  153. pf.left, pf.top, pf.right, pf.bottom));
  154. } else if ((fl & FLAG_LAYOUT_IN_OVERSCAN) != 0
  155. && type >= FIRST_APPLICATION_WINDOW && type <= LAST_SUB_WINDOW) {
  156. // Asking to layout into the overscan region, so give it that pure
  157. // unrestricted area.
  158. of.set(displayFrames.mOverscan);
  159. df.set(displayFrames.mOverscan);
  160. pf.set(displayFrames.mOverscan);
  161. } else if (canHideNavigationBar()
  162. && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
  163. && (type >= FIRST_APPLICATION_WINDOW && type <= LAST_SUB_WINDOW
  164. || type == TYPE_VOLUME_OVERLAY)) {
  165. // Asking for layout as if the nav bar is hidden, lets the application
  166. // extend into the unrestricted overscan screen area. We only do this for
  167. // application windows and certain system windows to ensure no window that
  168. // can be above the nav bar can do this.
  169. df.set(displayFrames.mOverscan);
  170. pf.set(displayFrames.mOverscan);
  171. // We need to tell the app about where the frame inside the overscan is, so
  172. // it can inset its content by that amount -- it didn't ask to actually
  173. // extend itself into the overscan region.
  174. of.set(displayFrames.mUnrestricted);
  175. } else {
  176. df.set(displayFrames.mRestrictedOverscan);
  177. pf.set(displayFrames.mRestrictedOverscan);
  178. // We need to tell the app about where the frame inside the overscan
  179. // is, so it can inset its content by that amount -- it didn't ask
  180. // to actually extend itself into the overscan region.
  181. of.set(displayFrames.mUnrestricted);
  182. }
  183. if ((fl & FLAG_FULLSCREEN) == 0) {
  184. if (win.isVoiceInteraction()) {
  185. cf.set(displayFrames.mVoiceContent);
  186. } else {
  187. if (adjust != SOFT_INPUT_ADJUST_RESIZE) { //不是缩小,要么被IME覆盖,要么向上移动PAN标志时
  188. cf.set(displayFrames.mDock);
  189. } else {
  190. cf.set(displayFrames.mContent);
  191. }
  192. }
  193. } else {
  194. // Full screen windows are always given a layout that is as if the status
  195. // bar and other transient decors are gone. This is to avoid bad states when
  196. // moving from a window that is not hiding the status bar to one that is.
  197. cf.set(displayFrames.mRestricted);
  198. }
  199. applyStableConstraints(sysUiFl, fl, cf, displayFrames);
  200. if (adjust != SOFT_INPUT_ADJUST_NOTHING) {
  201. vf.set(displayFrames.mCurrent);
  202. } else {
  203. vf.set(cf);
  204. }
  205. }
  206. } else if (layoutInScreen || (sysUiFl
  207. & (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
  208. | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)) != 0) {
  209. if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle()
  210. + "): IN_SCREEN");
  211. // A window that has requested to fill the entire screen just
  212. // gets everything, period.
  213. if (type == TYPE_STATUS_BAR_PANEL || type == TYPE_STATUS_BAR_SUB_PANEL) {
  214. cf.set(displayFrames.mUnrestricted);
  215. of.set(displayFrames.mUnrestricted);
  216. df.set(displayFrames.mUnrestricted);
  217. pf.set(displayFrames.mUnrestricted);
  218. if (hasNavBar) {
  219. pf.left = df.left = of.left = cf.left = displayFrames.mDock.left;
  220. pf.right = df.right = of.right = cf.right = displayFrames.mRestricted.right;
  221. pf.bottom = df.bottom = of.bottom = cf.bottom =
  222. displayFrames.mRestricted.bottom;
  223. }
  224. if (DEBUG_LAYOUT) Slog.v(TAG, String.format(
  225. "Laying out IN_SCREEN status bar window: (%d,%d - %d,%d)",
  226. pf.left, pf.top, pf.right, pf.bottom));
  227. } else if (type == TYPE_NAVIGATION_BAR || type == TYPE_NAVIGATION_BAR_PANEL) {
  228. // The navigation bar has Real Ultimate Power.
  229. of.set(displayFrames.mUnrestricted);
  230. df.set(displayFrames.mUnrestricted);
  231. pf.set(displayFrames.mUnrestricted);
  232. if (DEBUG_LAYOUT) Slog.v(TAG, String.format(
  233. "Laying out navigation bar window: (%d,%d - %d,%d)",
  234. pf.left, pf.top, pf.right, pf.bottom));
  235. } else if ((type == TYPE_SECURE_SYSTEM_OVERLAY || type == TYPE_SCREENSHOT)
  236. && ((fl & FLAG_FULLSCREEN) != 0)) {
  237. // Fullscreen secure system overlays get what they ask for. Screenshot region
  238. // selection overlay should also expand to full screen.
  239. cf.set(displayFrames.mOverscan);
  240. of.set(displayFrames.mOverscan);
  241. df.set(displayFrames.mOverscan);
  242. pf.set(displayFrames.mOverscan);
  243. } else if (type == TYPE_BOOT_PROGRESS) {
  244. // Boot progress screen always covers entire display.
  245. cf.set(displayFrames.mOverscan);
  246. of.set(displayFrames.mOverscan);
  247. df.set(displayFrames.mOverscan);
  248. pf.set(displayFrames.mOverscan);
  249. } else if ((fl & FLAG_LAYOUT_IN_OVERSCAN) != 0
  250. && type >= FIRST_APPLICATION_WINDOW && type <= LAST_SUB_WINDOW) {
  251. // Asking to layout into the overscan region, so give it that pure unrestricted
  252. // area.
  253. cf.set(displayFrames.mOverscan);
  254. of.set(displayFrames.mOverscan);
  255. df.set(displayFrames.mOverscan);
  256. pf.set(displayFrames.mOverscan);
  257. } else if (canHideNavigationBar()
  258. && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
  259. && (type == TYPE_STATUS_BAR
  260. || type == TYPE_TOAST
  261. || type == TYPE_DOCK_DIVIDER
  262. || type == TYPE_VOICE_INTERACTION_STARTING
  263. || (type >= FIRST_APPLICATION_WINDOW && type <= LAST_SUB_WINDOW))) {
  264. // Asking for layout as if the nav bar is hidden, lets the
  265. // application extend into the unrestricted screen area. We
  266. // only do this for application windows (or toasts) to ensure no window that
  267. // can be above the nav bar can do this.
  268. // XXX This assumes that an app asking for this will also
  269. // ask for layout in only content. We can't currently figure out
  270. // what the screen would be if only laying out to hide the nav bar.
  271. cf.set(displayFrames.mUnrestricted);
  272. of.set(displayFrames.mUnrestricted);
  273. df.set(displayFrames.mUnrestricted);
  274. pf.set(displayFrames.mUnrestricted);
  275. } else if ((sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) != 0) {
  276. of.set(displayFrames.mRestricted);
  277. df.set(displayFrames.mRestricted);
  278. pf.set(displayFrames.mRestricted);
  279. if (adjust != SOFT_INPUT_ADJUST_RESIZE) {
  280. cf.set(displayFrames.mDock);
  281. } else {
  282. }
  283. } else {
  284. cf.set(displayFrames.mRestricted);
  285. of.set(displayFrames.mRestricted);
  286. df.set(displayFrames.mRestricted);
  287. pf.set(displayFrames.mRestricted);
  288. }
  289. applyStableConstraints(sysUiFl, fl, cf,displayFrames);
  290. if (adjust != SOFT_INPUT_ADJUST_NOTHING) {
  291. vf.set(displayFrames.mCurrent);
  292. } else {
  293. vf.set(cf);
  294. }
  295. } else if (attached != null) {
  296. if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle()
  297. + "): attached to " + attached);
  298. // A child window should be placed inside of the same visible
  299. // frame that its parent had.
  300. setAttachedWindowFrames(win, fl, adjust, attached, false, pf, df, of, cf, vf,
  301. displayFrames);
  302. } else {
  303. if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle() +
  304. "): normal window");
  305. // Otherwise, a normal window must be placed inside the content
  306. // of all screen decorations.
  307. if (type == TYPE_STATUS_BAR_PANEL) {
  308. // Status bar panels can go on
  309. // top of the status bar. They are protected by the STATUS_BAR_SERVICE
  310. // permission, so they have the same privileges as the status bar itself.
  311. cf.set(displayFrames.mRestricted);
  312. of.set(displayFrames.mRestricted);
  313. df.set(displayFrames.mRestricted);
  314. pf.set(displayFrames.mRestricted);
  315. } else if (type == TYPE_TOAST || type == TYPE_SYSTEM_ALERT) {
  316. // These dialogs are stable to interim decor changes.
  317. cf.set(displayFrames.mStable);
  318. of.set(displayFrames.mStable);
  319. df.set(displayFrames.mStable);
  320. pf.set(displayFrames.mStable);
  321. } else {
  322. pf.set(displayFrames.mContent);
  323. if (win.isVoiceInteraction()) {
  324. cf.set(displayFrames.mVoiceContent);
  325. of.set(displayFrames.mVoiceContent);
  326. df.set(displayFrames.mVoiceContent);
  327. } else if (adjust != SOFT_INPUT_ADJUST_RESIZE
  328. cf.set(displayFrames.mContent);) {
  329. cf.set(displayFrames.mDock);
  330. of.set(displayFrames.mDock); //包括IME区域,以被IME遮挡
  331. df.set(displayFrames.mDock);
  332. } else {
  333. cf.set(displayFrames.mContent);
  334. of.set(displayFrames.mContent);
  335. df.set(displayFrames.mContent);
  336. }
  337. if (adjust != SOFT_INPUT_ADJUST_NOTHING) {
  338. vf.set(displayFrames.mCurrent); //不包括IME
  339. } else {
  340. vf.set(cf);
  341. }
  342. }
  343. }
  344. }
  345. boolean parentFrameWasClippedByDisplayCutout = false;
  346. final int cutoutMode = attrs.layoutInDisplayCutoutMode;
  347. final boolean attachedInParent = attached != null && !layoutInScreen;
  348. final boolean requestedHideNavigation =
  349. (requestedSysUiFl & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0;
  350. // TYPE_BASE_APPLICATION windows are never considered floating here because they don't get
  351. // cropped / shifted to the displayFrame in WindowState.
  352. final boolean floatingInScreenWindow = !attrs.isFullscreen() && layoutInScreen
  353. && type != TYPE_BASE_APPLICATION;
  354. // Ensure that windows with a DEFAULT or NEVER display cutout mode are laid out in
  355. // the cutout safe zone.
  356. if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS) {
  357. final Rect displayCutoutSafeExceptMaybeBars = mTmpDisplayCutoutSafeExceptMaybeBarsRect;
  358. displayCutoutSafeExceptMaybeBars.set(displayFrames.mDisplayCutoutSafe);
  359. if (layoutInScreen && layoutInsetDecor && !requestedFullscreen
  360. && cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT) {
  361. // At the top we have the status bar, so apps that are
  362. // LAYOUT_IN_SCREEN | LAYOUT_INSET_DECOR but not FULLSCREEN
  363. // already expect that there's an inset there and we don't need to exclude
  364. // the window from that area.
  365. displayCutoutSafeExceptMaybeBars.top = Integer.MIN_VALUE;
  366. }
  367. if (layoutInScreen && layoutInsetDecor && !requestedHideNavigation
  368. && cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT) {
  369. // Same for the navigation bar.
  370. switch (mNavigationBarPosition) {
  371. case NAV_BAR_BOTTOM:
  372. displayCutoutSafeExceptMaybeBars.bottom = Integer.MAX_VALUE;
  373. break;
  374. case NAV_BAR_RIGHT:
  375. displayCutoutSafeExceptMaybeBars.right = Integer.MAX_VALUE;
  376. break;
  377. case NAV_BAR_LEFT:
  378. displayCutoutSafeExceptMaybeBars.left = Integer.MIN_VALUE;
  379. break;
  380. }
  381. }
  382. if (type == TYPE_INPUT_METHOD && mNavigationBarPosition == NAV_BAR_BOTTOM) {
  383. // The IME can always extend under the bottom cutout if the navbar is there.
  384. displayCutoutSafeExceptMaybeBars.bottom = Integer.MAX_VALUE;
  385. }
  386. // Windows that are attached to a parent and laid out in said parent already avoid
  387. // the cutout according to that parent and don't need to be further constrained.
  388. // Floating IN_SCREEN windows get what they ask for and lay out in the full screen.
  389. // They will later be cropped or shifted using the displayFrame in WindowState,
  390. // which prevents overlap with the DisplayCutout.
  391. if (!attachedInParent && !floatingInScreenWindow) {
  392. mTmpRect.set(pf);
  393. pf.intersectUnchecked(displayCutoutSafeExceptMaybeBars);
  394. parentFrameWasClippedByDisplayCutout |= !mTmpRect.equals(pf);
  395. }
  396. // Make sure that NO_LIMITS windows clipped to the display don't extend under the
  397. // cutout.
  398. df.intersectUnchecked(displayCutoutSafeExceptMaybeBars);
  399. }
  400. // Content should never appear in the cutout.
  401. cf.intersectUnchecked(displayFrames.mDisplayCutoutSafe);
  402. // TYPE_SYSTEM_ERROR is above the NavigationBar so it can't be allowed to extend over it.
  403. // Also, we don't allow windows in multi-window mode to extend out of the screen.
  404. if ((fl & FLAG_LAYOUT_NO_LIMITS) != 0 && type != TYPE_SYSTEM_ERROR //范围无限制FLAG_LAYOUT_NO_LIMITS
  405. && !win.isInMultiWindowMode()) {
  406. df.left = df.top = -10000;
  407. df.right = df.bottom = 10000;
  408. if (type != TYPE_WALLPAPER) {
  409. of.left = of.top = cf.left = cf.top = vf.left = vf.top = -10000;
  410. of.right = of.bottom = cf.right = cf.bottom = vf.right = vf.bottom = 10000;
  411. }
  412. }
  413. // If the device has a chin (e.g. some watches), a dead area at the bottom of the screen we
  414. // need to provide information to the clients that want to pretend that you can draw there.
  415. // We only want to apply outsets to certain types of windows. For example, we never want to
  416. // apply the outsets to floating dialogs, because they wouldn't make sense there.
  417. final boolean useOutsets = shouldUseOutsets(attrs, fl);
  418. if (isDefaultDisplay && useOutsets) {
  419. osf = mTmpOutsetFrame;
  420. osf.set(cf.left, cf.top, cf.right, cf.bottom);
  421. int outset = ScreenShapeHelper.getWindowOutsetBottomPx(mContext.getResources());
  422. if (outset > 0) {
  423. int rotation = displayFrames.mRotation;
  424. if (rotation == Surface.ROTATION_0) {
  425. osf.bottom += outset;
  426. } else if (rotation == Surface.ROTATION_90) {
  427. osf.right += outset;
  428. } else if (rotation == Surface.ROTATION_180) {
  429. osf.top -= outset;
  430. } else if (rotation == Surface.ROTATION_270) {
  431. osf.left -= outset;
  432. }
  433. if (DEBUG_LAYOUT) Slog.v(TAG, "applying bottom outset of " + outset
  434. + " with rotation " + rotation + ", result: " + osf);
  435. }
  436. }
  437. //logcat | grep -e mNavigationBar -e "Status bar" -e "mDock rect" -e "Compute frame"
  438. Printer printer = new LogPrinter(Log.ERROR, “tag”);
  439. displayFrames.dump("layoutWL:", printer);
  440. if (DEBUG_LAYOUT) Slog.v(TAG, "Compute frame " + attrs.getTitle()
  441. + ": sim=#" + Integer.toHexString(sim)
  442. + " attach=" + attached + " type=" + type
  443. + String.format(" flags=0x%08x", fl)
  444. + " pf=" + pf.toShortString() + " df=" + df.toShortString()
  445. + " of=" + of.toShortString()
  446. + " cf=" + cf.toShortString() + " vf=" + vf.toShortString()
  447. + " dcf=" + dcf.toShortString()
  448. + " sf=" + sf.toShortString()
  449. + " osf=" + (osf == null ? "null" : osf.toShortString()));
  450. win.computeFrameLw(pf, df, of, cf, vf, dcf, sf, osf, displayFrames.mDisplayCutout,
  451. parentFrameWasClippedByDisplayCutout);
  452. // Dock windows carve out the bottom of the screen, so normal windows
  453. // can't appear underneath them.
  454. if (type == TYPE_INPUT_METHOD && win.isVisibleLw()
  455. && !win.getGivenInsetsPendingLw()) { //不是正在addWindow IME没有更新setInsetWindow
  456. setLastInputMethodWindowLw(null, null);
  457. offsetInputMethodWindowLw(win, displayFrames);
  458. }
  459. if (type == TYPE_VOICE_INTERACTION && win.isVisibleLw()
  460. && !win.getGivenInsetsPendingLw()) {
  461. offsetVoiceInputWindowLw(win, displayFrames);
  462. }
  463. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/327118
推荐阅读
相关标签
  

闽ICP备14008679号