blob: c816ba3fa79692cf1d8b61ad6fb0ab1133f84f1f [file] [log] [blame]
Jorim Jaggi02886a82016-12-06 09:10:06 -08001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.server.wm;
18
Jorim Jaggi30d64f32017-04-07 16:33:17 +020019import static android.graphics.Color.WHITE;
20import static android.graphics.Color.alpha;
21import static android.view.SurfaceControl.HIDDEN;
22import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
23import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
24import static android.view.WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES;
25import static android.view.WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE;
Jorim Jaggi02886a82016-12-06 09:10:06 -080026import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
27import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
Jorim Jaggi30d64f32017-04-07 16:33:17 +020028import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
29import static android.view.WindowManager.LayoutParams.FLAG_SCALED;
30import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
31import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY;
32import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
33import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
34import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
Jorim Jaggi02886a82016-12-06 09:10:06 -080035import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TASK_SNAPSHOT;
36import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
Jorim Jaggi30d64f32017-04-07 16:33:17 +020037import static com.android.internal.policy.DecorView.NAVIGATION_BAR_COLOR_VIEW_ATTRIBUTES;
38import static com.android.internal.policy.DecorView.STATUS_BAR_COLOR_VIEW_ATTRIBUTES;
39import static com.android.internal.policy.DecorView.getColorViewLeftInset;
40import static com.android.internal.policy.DecorView.getColorViewTopInset;
41import static com.android.internal.policy.DecorView.getNavigationBarRect;
Jorim Jaggi02886a82016-12-06 09:10:06 -080042import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
43import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
44
Jorim Jaggi829b9cd2017-01-23 16:20:53 +010045import android.app.ActivityManager.TaskDescription;
Jorim Jaggi30d64f32017-04-07 16:33:17 +020046import android.app.ActivityManager.TaskSnapshot;
Jorim Jaggi02886a82016-12-06 09:10:06 -080047import android.graphics.Canvas;
48import android.graphics.GraphicBuffer;
Jorim Jaggi829b9cd2017-01-23 16:20:53 +010049import android.graphics.Paint;
Jorim Jaggi02886a82016-12-06 09:10:06 -080050import android.graphics.Rect;
51import android.os.Handler;
Jorim Jaggi829b9cd2017-01-23 16:20:53 +010052import android.os.Looper;
Jorim Jaggi02886a82016-12-06 09:10:06 -080053import android.os.Message;
54import android.os.RemoteException;
Jorim Jaggi30d64f32017-04-07 16:33:17 +020055import android.os.SystemClock;
Andrii Kulian44607962017-03-16 11:06:24 -070056import android.util.MergedConfiguration;
Jorim Jaggi02886a82016-12-06 09:10:06 -080057import android.util.Slog;
Jorim Jaggi02886a82016-12-06 09:10:06 -080058import android.view.IWindowSession;
59import android.view.Surface;
Jorim Jaggi30d64f32017-04-07 16:33:17 +020060import android.view.SurfaceControl;
61import android.view.SurfaceSession;
Jorim Jaggi02886a82016-12-06 09:10:06 -080062import android.view.View;
63import android.view.ViewGroup.LayoutParams;
64import android.view.WindowManager;
65import android.view.WindowManagerGlobal;
66import android.view.WindowManagerPolicy.StartingSurface;
67
Jorim Jaggi30d64f32017-04-07 16:33:17 +020068import com.android.internal.R;
Jorim Jaggi829b9cd2017-01-23 16:20:53 +010069import com.android.internal.annotations.VisibleForTesting;
Jorim Jaggi30d64f32017-04-07 16:33:17 +020070import com.android.internal.policy.DecorView;
Jorim Jaggi02886a82016-12-06 09:10:06 -080071import com.android.internal.view.BaseIWindow;
72
73/**
74 * This class represents a starting window that shows a snapshot.
75 * <p>
76 * DO NOT HOLD THE WINDOW MANAGER LOCK WHEN CALLING METHODS OF THIS CLASS!
77 */
78class TaskSnapshotSurface implements StartingSurface {
79
Jorim Jaggi30d64f32017-04-07 16:33:17 +020080 private static final long SIZE_MISMATCH_MINIMUM_TIME_MS = 450;
81
82 /**
83 * When creating the starting window, we use the exact same layout flags such that we end up
84 * with a window with the exact same dimensions etc. However, these flags are not used in layout
85 * and might cause other side effects so we exclude them.
86 */
87 private static final int FLAG_INHERIT_EXCLUDES = FLAG_NOT_FOCUSABLE
88 | FLAG_NOT_TOUCHABLE
89 | FLAG_NOT_TOUCH_MODAL
90 | FLAG_ALT_FOCUSABLE_IM
91 | FLAG_NOT_FOCUSABLE
92 | FLAG_HARDWARE_ACCELERATED
93 | FLAG_IGNORE_CHEEK_PRESSES
94 | FLAG_LOCAL_FOCUS_MODE
95 | FLAG_SLIPPERY
96 | FLAG_WATCH_OUTSIDE_TOUCH
97 | FLAG_SPLIT_TOUCH
98 | FLAG_SCALED
99 | FLAG_SECURE;
100
Jorim Jaggi02886a82016-12-06 09:10:06 -0800101 private static final String TAG = TAG_WITH_CLASS_NAME ? "SnapshotStartingWindow" : TAG_WM;
102 private static final int MSG_REPORT_DRAW = 0;
103 private static final String TITLE_FORMAT = "SnapshotStartingWindow for taskId=%s";
104 private final Window mWindow;
105 private final Surface mSurface;
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200106 private SurfaceControl mChildSurfaceControl;
Jorim Jaggi02886a82016-12-06 09:10:06 -0800107 private final IWindowSession mSession;
108 private final WindowManagerService mService;
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200109 private final Rect mTaskBounds;
110 private final Rect mStableInsets = new Rect();
111 private final Rect mContentInsets = new Rect();
112 private final Rect mFrame = new Rect();
113 private final TaskSnapshot mSnapshot;
114 private final CharSequence mTitle;
Jorim Jaggi02886a82016-12-06 09:10:06 -0800115 private boolean mHasDrawn;
116 private boolean mReportNextDraw;
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200117 private long mShownTime;
118 private final Handler mHandler;
119 private boolean mSizeMismatch;
120 private final Paint mBackgroundPaint = new Paint();
121 private final Paint mStatusBarPaint = new Paint();
122 private final Paint mNavigationBarPaint = new Paint();
123 private final int mStatusBarColor;
124 private final int mNavigationBarColor;
125 private final int mSysUiVis;
126 private final int mWindowFlags;
127 private final int mWindowPrivateFlags;
Jorim Jaggi02886a82016-12-06 09:10:06 -0800128
129 static TaskSnapshotSurface create(WindowManagerService service, AppWindowToken token,
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200130 TaskSnapshot snapshot) {
Jorim Jaggi02886a82016-12-06 09:10:06 -0800131
132 final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
133 final Window window = new Window();
134 final IWindowSession session = WindowManagerGlobal.getWindowSession();
135 window.setSession(session);
136 final Surface surface = new Surface();
137 final Rect tmpRect = new Rect();
138 final Rect tmpFrame = new Rect();
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200139 final Rect taskBounds;
140 final Rect tmpContentInsets = new Rect();
141 final Rect tmpStableInsets = new Rect();
Andrii Kulian44607962017-03-16 11:06:24 -0700142 final MergedConfiguration tmpMergedConfiguration = new MergedConfiguration();
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200143 int backgroundColor = WHITE;
144 int statusBarColor = 0;
145 int navigationBarColor = 0;
146 final int sysUiVis;
147 final int windowFlags;
148 final int windowPrivateFlags;
Jorim Jaggi02886a82016-12-06 09:10:06 -0800149 synchronized (service.mWindowMap) {
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200150 final WindowState mainWindow = token.findMainWindow();
151 if (mainWindow == null) {
152 Slog.w(TAG, "TaskSnapshotSurface.create: Failed to find main window for token="
153 + token);
154 return null;
155 }
156 sysUiVis = mainWindow.getSystemUiVisibility();
157 windowFlags = mainWindow.getAttrs().flags;
158 windowPrivateFlags = mainWindow.getAttrs().privateFlags;
159
Jorim Jaggi02886a82016-12-06 09:10:06 -0800160 layoutParams.type = TYPE_APPLICATION_STARTING;
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200161 layoutParams.format = snapshot.getSnapshot().getFormat();
162 layoutParams.flags = (windowFlags & ~FLAG_INHERIT_EXCLUDES)
Jorim Jaggi02886a82016-12-06 09:10:06 -0800163 | FLAG_NOT_FOCUSABLE
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200164 | FLAG_NOT_TOUCHABLE;
Jorim Jaggi02886a82016-12-06 09:10:06 -0800165 layoutParams.privateFlags = PRIVATE_FLAG_TASK_SNAPSHOT;
166 layoutParams.token = token.token;
167 layoutParams.width = LayoutParams.MATCH_PARENT;
168 layoutParams.height = LayoutParams.MATCH_PARENT;
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200169 layoutParams.systemUiVisibility = sysUiVis;
Bryce Lee6d410262017-02-28 15:30:17 -0800170 final Task task = token.getTask();
171 if (task != null) {
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200172 layoutParams.setTitle(String.format(TITLE_FORMAT, task.mTaskId));
Bryce Lee6d410262017-02-28 15:30:17 -0800173
174 final TaskDescription taskDescription = task.getTaskDescription();
Jorim Jaggi829b9cd2017-01-23 16:20:53 +0100175 if (taskDescription != null) {
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200176 backgroundColor = taskDescription.getBackgroundColor();
177 statusBarColor = taskDescription.getStatusBarColor();
178 navigationBarColor = taskDescription.getNavigationBarColor();
Jorim Jaggi829b9cd2017-01-23 16:20:53 +0100179 }
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200180 taskBounds = new Rect();
181 task.getBounds(taskBounds);
182 } else {
183 taskBounds = null;
Jorim Jaggi829b9cd2017-01-23 16:20:53 +0100184 }
Jorim Jaggi02886a82016-12-06 09:10:06 -0800185 }
186 try {
187 final int res = session.addToDisplay(window, window.mSeq, layoutParams,
188 View.VISIBLE, token.getDisplayContent().getDisplayId(), tmpRect, tmpRect,
189 tmpRect, null);
190 if (res < 0) {
191 Slog.w(TAG, "Failed to add snapshot starting window res=" + res);
192 return null;
193 }
194 } catch (RemoteException e) {
195 // Local call.
196 }
197 final TaskSnapshotSurface snapshotSurface = new TaskSnapshotSurface(service, window,
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200198 surface, snapshot, layoutParams.getTitle(), backgroundColor, statusBarColor,
199 navigationBarColor, sysUiVis, windowFlags, windowPrivateFlags, taskBounds);
Jorim Jaggi02886a82016-12-06 09:10:06 -0800200 window.setOuter(snapshotSurface);
201 try {
202 session.relayout(window, window.mSeq, layoutParams, -1, -1, View.VISIBLE, 0, tmpFrame,
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200203 tmpRect, tmpContentInsets, tmpRect, tmpStableInsets, tmpRect, tmpRect,
204 tmpMergedConfiguration, surface);
Jorim Jaggi02886a82016-12-06 09:10:06 -0800205 } catch (RemoteException e) {
206 // Local call.
207 }
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200208 snapshotSurface.setFrames(tmpFrame, tmpContentInsets, tmpStableInsets);
209 snapshotSurface.drawSnapshot();
Jorim Jaggi02886a82016-12-06 09:10:06 -0800210 return snapshotSurface;
211 }
212
Jorim Jaggi829b9cd2017-01-23 16:20:53 +0100213 @VisibleForTesting
214 TaskSnapshotSurface(WindowManagerService service, Window window, Surface surface,
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200215 TaskSnapshot snapshot, CharSequence title, int backgroundColor, int statusBarColor,
216 int navigationBarColor, int sysUiVis, int windowFlags, int windowPrivateFlags,
217 Rect taskBounds) {
Jorim Jaggi02886a82016-12-06 09:10:06 -0800218 mService = service;
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200219 mHandler = new Handler(mService.mH.getLooper());
Jorim Jaggi02886a82016-12-06 09:10:06 -0800220 mSession = WindowManagerGlobal.getWindowSession();
221 mWindow = window;
222 mSurface = surface;
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200223 mSnapshot = snapshot;
224 mTitle = title;
225 mBackgroundPaint.setColor(backgroundColor != 0 ? backgroundColor : WHITE);
226 mTaskBounds = taskBounds;
227 mSysUiVis = sysUiVis;
228 mWindowFlags = windowFlags;
229 mWindowPrivateFlags = windowPrivateFlags;
230 mStatusBarColor = DecorView.calculateStatusBarColor(windowFlags,
231 service.mContext.getColor(R.color.system_bar_background_semi_transparent),
232 statusBarColor);
233 mNavigationBarColor = navigationBarColor;
234 mStatusBarPaint.setColor(mStatusBarColor);
235 mNavigationBarPaint.setColor(navigationBarColor);
Jorim Jaggi02886a82016-12-06 09:10:06 -0800236 }
237
238 @Override
239 public void remove() {
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200240 synchronized (mService.mWindowMap) {
241 final long now = SystemClock.uptimeMillis();
242 if (mSizeMismatch && now - mShownTime < SIZE_MISMATCH_MINIMUM_TIME_MS) {
243 mHandler.postAtTime(this::remove, mShownTime + SIZE_MISMATCH_MINIMUM_TIME_MS);
244 return;
245 }
246 }
Jorim Jaggi02886a82016-12-06 09:10:06 -0800247 try {
248 mSession.remove(mWindow);
249 } catch (RemoteException e) {
250 // Local call.
251 }
252 }
253
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200254 @VisibleForTesting
255 void setFrames(Rect frame, Rect contentInsets, Rect stableInsets) {
256 mFrame.set(frame);
257 mContentInsets.set(contentInsets);
258 mStableInsets.set(stableInsets);
259 mSizeMismatch = (mFrame.width() != mSnapshot.getSnapshot().getWidth()
260 || mFrame.height() != mSnapshot.getSnapshot().getHeight());
261 }
262
263 private void drawSnapshot() {
264 final GraphicBuffer buffer = mSnapshot.getSnapshot();
265 if (mSizeMismatch) {
266 // The dimensions of the buffer and the window don't match, so attaching the buffer
267 // will fail. Better create a child window with the exact dimensions and fill the parent
268 // window with the background color!
269 drawSizeMismatchSnapshot(buffer);
270 } else {
271 drawSizeMatchSnapshot(buffer);
272 }
Jorim Jaggi39367cf2017-03-13 16:41:13 +0100273 final boolean reportNextDraw;
274 synchronized (mService.mWindowMap) {
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200275 mShownTime = SystemClock.uptimeMillis();
Jorim Jaggi39367cf2017-03-13 16:41:13 +0100276 mHasDrawn = true;
277 reportNextDraw = mReportNextDraw;
278 }
279 if (reportNextDraw) {
280 reportDrawn();
281 }
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200282 }
283
284 private void drawSizeMatchSnapshot(GraphicBuffer buffer) {
285 mSurface.attachAndQueueBuffer(buffer);
286 mSurface.release();
287 }
288
289 private void drawSizeMismatchSnapshot(GraphicBuffer buffer) {
290 final SurfaceSession session = new SurfaceSession(mSurface);
291
292 // Keep a reference to it such that it doesn't get destroyed when finalized.
293 mChildSurfaceControl = new SurfaceControl(session,
294 mTitle + " - task-snapshot-surface",
295 buffer.getWidth(), buffer.getHeight(), buffer.getFormat(), HIDDEN);
296 Surface surface = new Surface();
297 surface.copyFrom(mChildSurfaceControl);
298
299 // Clip off ugly navigation bar.
300 final Rect crop = calculateSnapshotCrop();
301 final Rect frame = calculateSnapshotFrame(crop);
302 SurfaceControl.openTransaction();
303 try {
304 // We can just show the surface here as it will still be hidden as the parent is
305 // still hidden.
306 mChildSurfaceControl.show();
307 mChildSurfaceControl.setWindowCrop(crop);
308 mChildSurfaceControl.setPosition(frame.left, frame.top);
309 } finally {
310 SurfaceControl.closeTransaction();
311 }
312 surface.attachAndQueueBuffer(buffer);
313 surface.release();
314
315 final Canvas c = mSurface.lockCanvas(null);
316 drawBackgroundAndBars(c, frame);
317 mSurface.unlockCanvasAndPost(c);
Jorim Jaggi2f24b652017-01-18 02:17:37 +0100318 mSurface.release();
Jorim Jaggi02886a82016-12-06 09:10:06 -0800319 }
320
Jorim Jaggi829b9cd2017-01-23 16:20:53 +0100321 @VisibleForTesting
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200322 Rect calculateSnapshotCrop() {
323 final Rect rect = new Rect();
324 rect.set(0, 0, mSnapshot.getSnapshot().getWidth(), mSnapshot.getSnapshot().getHeight());
325 final Rect insets = mSnapshot.getContentInsets();
326
327 // Let's remove all system decorations except the status bar, but only if the task is at the
328 // very top of the screen.
329 rect.inset(insets.left, mTaskBounds.top != 0 ? insets.top : 0, insets.right, insets.bottom);
330 return rect;
331 }
332
333 @VisibleForTesting
334 Rect calculateSnapshotFrame(Rect crop) {
335 final Rect frame = new Rect(crop);
336
337 // By default, offset it to to top/left corner
338 frame.offsetTo(-crop.left, -crop.top);
339
340 // However, we also need to make space for the navigation bar on the left side.
341 final int colorViewLeftInset = getColorViewLeftInset(mStableInsets.left,
342 mContentInsets.left);
343 frame.offset(colorViewLeftInset, 0);
344 return frame;
345 }
346
347 @VisibleForTesting
348 void drawBackgroundAndBars(Canvas c, Rect frame) {
349 final int statusBarHeight = getStatusBarColorViewHeight();
350 final boolean fillHorizontally = c.getWidth() > frame.right;
351 final boolean fillVertically = c.getHeight() > frame.bottom;
Jorim Jaggi829b9cd2017-01-23 16:20:53 +0100352 if (fillHorizontally) {
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200353 c.drawRect(frame.right, alpha(mStatusBarColor) == 0xFF ? statusBarHeight : 0,
354 c.getWidth(), fillVertically
355 ? frame.bottom
356 : c.getHeight(),
357 mBackgroundPaint);
Jorim Jaggi829b9cd2017-01-23 16:20:53 +0100358 }
359 if (fillVertically) {
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200360 c.drawRect(0, frame.bottom, c.getWidth(), c.getHeight(), mBackgroundPaint);
361 }
362 drawStatusBarBackground(c, frame, statusBarHeight);
363 drawNavigationBarBackground(c);
364 }
365
366 private int getStatusBarColorViewHeight() {
367 final boolean forceStatusBarBackground =
368 (mWindowPrivateFlags & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND) != 0;
369 if (STATUS_BAR_COLOR_VIEW_ATTRIBUTES.isVisible(
370 mSysUiVis, mStatusBarColor, mWindowFlags, forceStatusBarBackground)) {
371 return getColorViewTopInset(mStableInsets.top, mContentInsets.top);
372 } else {
373 return 0;
374 }
375 }
376
377 private boolean isNavigationBarColorViewVisible() {
378 return NAVIGATION_BAR_COLOR_VIEW_ATTRIBUTES.isVisible(
379 mSysUiVis, mNavigationBarColor, mWindowFlags, false /* force */);
380 }
381
382 @VisibleForTesting
383 void drawStatusBarBackground(Canvas c, Rect frame, int statusBarHeight) {
384 if (statusBarHeight > 0 && c.getWidth() > frame.right) {
385 final int rightInset = DecorView.getColorViewRightInset(mStableInsets.right,
386 mContentInsets.right);
387 c.drawRect(frame.right, 0, c.getWidth() - rightInset, statusBarHeight, mStatusBarPaint);
388 }
389 }
390
391 @VisibleForTesting
392 void drawNavigationBarBackground(Canvas c) {
393 final Rect navigationBarRect = new Rect();
394 getNavigationBarRect(c.getWidth(), c.getHeight(), mStableInsets, mContentInsets,
395 navigationBarRect);
396 final boolean visible = isNavigationBarColorViewVisible();
397 if (visible && !navigationBarRect.isEmpty()) {
398 c.drawRect(navigationBarRect, mNavigationBarPaint);
Jorim Jaggi829b9cd2017-01-23 16:20:53 +0100399 }
400 }
401
Jorim Jaggi02886a82016-12-06 09:10:06 -0800402 private void reportDrawn() {
403 synchronized (mService.mWindowMap) {
404 mReportNextDraw = false;
405 }
406 try {
407 mSession.finishDrawing(mWindow);
408 } catch (RemoteException e) {
409 // Local call.
410 }
411 }
412
Jorim Jaggi829b9cd2017-01-23 16:20:53 +0100413 private static Handler sHandler = new Handler(Looper.getMainLooper()) {
Jorim Jaggi02886a82016-12-06 09:10:06 -0800414
415 @Override
416 public void handleMessage(Message msg) {
417 switch (msg.what) {
418 case MSG_REPORT_DRAW:
419 final boolean hasDrawn;
420 final TaskSnapshotSurface surface = (TaskSnapshotSurface) msg.obj;
421 synchronized (surface.mService.mWindowMap) {
422 hasDrawn = surface.mHasDrawn;
423 if (!hasDrawn) {
424 surface.mReportNextDraw = true;
425 }
426 }
427 if (hasDrawn) {
428 surface.reportDrawn();
429 }
430 break;
431 }
432 }
433 };
434
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200435 @VisibleForTesting
436 static class Window extends BaseIWindow {
Jorim Jaggi02886a82016-12-06 09:10:06 -0800437
438 private TaskSnapshotSurface mOuter;
Jorim Jaggi02886a82016-12-06 09:10:06 -0800439 public void setOuter(TaskSnapshotSurface outer) {
440 mOuter = outer;
441 }
442
443 @Override
444 public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets,
Andrii Kulian44607962017-03-16 11:06:24 -0700445 Rect stableInsets, Rect outsets, boolean reportDraw,
446 MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout,
447 boolean alwaysConsumeNavBar, int displayId) {
Jorim Jaggi02886a82016-12-06 09:10:06 -0800448 if (reportDraw) {
449 sHandler.obtainMessage(MSG_REPORT_DRAW, mOuter).sendToTarget();
450 }
451 }
452 }
453}