TaskSnapshotSurface.java revision 02886a82d876aa5e31a92444fec70208599c509c
102886a82d876aa5e31a92444fec70208599c509cJorim Jaggi/* 202886a82d876aa5e31a92444fec70208599c509cJorim Jaggi * Copyright (C) 2016 The Android Open Source Project 302886a82d876aa5e31a92444fec70208599c509cJorim Jaggi * 402886a82d876aa5e31a92444fec70208599c509cJorim Jaggi * Licensed under the Apache License, Version 2.0 (the "License"); 502886a82d876aa5e31a92444fec70208599c509cJorim Jaggi * you may not use this file except in compliance with the License. 602886a82d876aa5e31a92444fec70208599c509cJorim Jaggi * You may obtain a copy of the License at 702886a82d876aa5e31a92444fec70208599c509cJorim Jaggi * 802886a82d876aa5e31a92444fec70208599c509cJorim Jaggi * http://www.apache.org/licenses/LICENSE-2.0 902886a82d876aa5e31a92444fec70208599c509cJorim Jaggi * 1002886a82d876aa5e31a92444fec70208599c509cJorim Jaggi * Unless required by applicable law or agreed to in writing, software 1102886a82d876aa5e31a92444fec70208599c509cJorim Jaggi * distributed under the License is distributed on an "AS IS" BASIS, 1202886a82d876aa5e31a92444fec70208599c509cJorim Jaggi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1302886a82d876aa5e31a92444fec70208599c509cJorim Jaggi * See the License for the specific language governing permissions and 1402886a82d876aa5e31a92444fec70208599c509cJorim Jaggi * limitations under the License 1502886a82d876aa5e31a92444fec70208599c509cJorim Jaggi */ 1602886a82d876aa5e31a92444fec70208599c509cJorim Jaggi 1702886a82d876aa5e31a92444fec70208599c509cJorim Jaggipackage com.android.server.wm; 1802886a82d876aa5e31a92444fec70208599c509cJorim Jaggi 1902886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; 2002886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; 2102886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; 2202886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 2302886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 2402886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TASK_SNAPSHOT; 2502886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; 2602886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; 2702886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; 2802886a82d876aa5e31a92444fec70208599c509cJorim Jaggi 2902886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport android.content.res.Configuration; 3002886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport android.graphics.Bitmap; 3102886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport android.graphics.Canvas; 3202886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport android.graphics.GraphicBuffer; 3302886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport android.graphics.Rect; 3402886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport android.os.Handler; 3502886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport android.os.Message; 3602886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport android.os.RemoteException; 3702886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport android.util.Slog; 3802886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport android.view.Display; 3902886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport android.view.IWindowSession; 4002886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport android.view.Surface; 4102886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport android.view.View; 4202886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport android.view.ViewGroup.LayoutParams; 4302886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport android.view.WindowManager; 4402886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport android.view.WindowManagerGlobal; 4502886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport android.view.WindowManagerPolicy.StartingSurface; 4602886a82d876aa5e31a92444fec70208599c509cJorim Jaggi 4702886a82d876aa5e31a92444fec70208599c509cJorim Jaggiimport com.android.internal.view.BaseIWindow; 4802886a82d876aa5e31a92444fec70208599c509cJorim Jaggi 4902886a82d876aa5e31a92444fec70208599c509cJorim Jaggi/** 5002886a82d876aa5e31a92444fec70208599c509cJorim Jaggi * This class represents a starting window that shows a snapshot. 5102886a82d876aa5e31a92444fec70208599c509cJorim Jaggi * <p> 5202886a82d876aa5e31a92444fec70208599c509cJorim Jaggi * DO NOT HOLD THE WINDOW MANAGER LOCK WHEN CALLING METHODS OF THIS CLASS! 5302886a82d876aa5e31a92444fec70208599c509cJorim Jaggi */ 5402886a82d876aa5e31a92444fec70208599c509cJorim Jaggiclass TaskSnapshotSurface implements StartingSurface { 5502886a82d876aa5e31a92444fec70208599c509cJorim Jaggi 5602886a82d876aa5e31a92444fec70208599c509cJorim Jaggi private static final String TAG = TAG_WITH_CLASS_NAME ? "SnapshotStartingWindow" : TAG_WM; 5702886a82d876aa5e31a92444fec70208599c509cJorim Jaggi private static final int MSG_REPORT_DRAW = 0; 5802886a82d876aa5e31a92444fec70208599c509cJorim Jaggi private static final String TITLE_FORMAT = "SnapshotStartingWindow for taskId=%s"; 5902886a82d876aa5e31a92444fec70208599c509cJorim Jaggi private final Window mWindow; 6002886a82d876aa5e31a92444fec70208599c509cJorim Jaggi private final Surface mSurface; 6102886a82d876aa5e31a92444fec70208599c509cJorim Jaggi private final IWindowSession mSession; 6202886a82d876aa5e31a92444fec70208599c509cJorim Jaggi private final WindowManagerService mService; 6302886a82d876aa5e31a92444fec70208599c509cJorim Jaggi private boolean mHasDrawn; 6402886a82d876aa5e31a92444fec70208599c509cJorim Jaggi private boolean mReportNextDraw; 6502886a82d876aa5e31a92444fec70208599c509cJorim Jaggi 6602886a82d876aa5e31a92444fec70208599c509cJorim Jaggi static TaskSnapshotSurface create(WindowManagerService service, AppWindowToken token, 6702886a82d876aa5e31a92444fec70208599c509cJorim Jaggi GraphicBuffer snapshot) { 6802886a82d876aa5e31a92444fec70208599c509cJorim Jaggi 6902886a82d876aa5e31a92444fec70208599c509cJorim Jaggi final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(); 7002886a82d876aa5e31a92444fec70208599c509cJorim Jaggi final Window window = new Window(); 7102886a82d876aa5e31a92444fec70208599c509cJorim Jaggi final IWindowSession session = WindowManagerGlobal.getWindowSession(); 7202886a82d876aa5e31a92444fec70208599c509cJorim Jaggi window.setSession(session); 7302886a82d876aa5e31a92444fec70208599c509cJorim Jaggi final Surface surface = new Surface(); 7402886a82d876aa5e31a92444fec70208599c509cJorim Jaggi final Rect tmpRect = new Rect(); 7502886a82d876aa5e31a92444fec70208599c509cJorim Jaggi final Rect tmpFrame = new Rect(); 7602886a82d876aa5e31a92444fec70208599c509cJorim Jaggi final Configuration tmpConfiguration = new Configuration(); 7702886a82d876aa5e31a92444fec70208599c509cJorim Jaggi synchronized (service.mWindowMap) { 7802886a82d876aa5e31a92444fec70208599c509cJorim Jaggi layoutParams.type = TYPE_APPLICATION_STARTING; 7902886a82d876aa5e31a92444fec70208599c509cJorim Jaggi layoutParams.format = snapshot.getFormat(); 8002886a82d876aa5e31a92444fec70208599c509cJorim Jaggi layoutParams.flags = FLAG_LAYOUT_INSET_DECOR 8102886a82d876aa5e31a92444fec70208599c509cJorim Jaggi | FLAG_LAYOUT_IN_SCREEN 8202886a82d876aa5e31a92444fec70208599c509cJorim Jaggi | FLAG_NOT_FOCUSABLE 8302886a82d876aa5e31a92444fec70208599c509cJorim Jaggi | FLAG_NOT_TOUCHABLE 8402886a82d876aa5e31a92444fec70208599c509cJorim Jaggi | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; 8502886a82d876aa5e31a92444fec70208599c509cJorim Jaggi layoutParams.privateFlags = PRIVATE_FLAG_TASK_SNAPSHOT; 8602886a82d876aa5e31a92444fec70208599c509cJorim Jaggi layoutParams.token = token.token; 8702886a82d876aa5e31a92444fec70208599c509cJorim Jaggi layoutParams.width = LayoutParams.MATCH_PARENT; 8802886a82d876aa5e31a92444fec70208599c509cJorim Jaggi layoutParams.height = LayoutParams.MATCH_PARENT; 8902886a82d876aa5e31a92444fec70208599c509cJorim Jaggi 9002886a82d876aa5e31a92444fec70208599c509cJorim Jaggi // TODO: Inherit behavior whether to draw behind status bar/nav bar. 9102886a82d876aa5e31a92444fec70208599c509cJorim Jaggi layoutParams.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 9202886a82d876aa5e31a92444fec70208599c509cJorim Jaggi | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; 9302886a82d876aa5e31a92444fec70208599c509cJorim Jaggi layoutParams.setTitle(String.format(TITLE_FORMAT, token.mTask.mTaskId)); 9402886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } 9502886a82d876aa5e31a92444fec70208599c509cJorim Jaggi try { 9602886a82d876aa5e31a92444fec70208599c509cJorim Jaggi final int res = session.addToDisplay(window, window.mSeq, layoutParams, 9702886a82d876aa5e31a92444fec70208599c509cJorim Jaggi View.VISIBLE, token.getDisplayContent().getDisplayId(), tmpRect, tmpRect, 9802886a82d876aa5e31a92444fec70208599c509cJorim Jaggi tmpRect, null); 9902886a82d876aa5e31a92444fec70208599c509cJorim Jaggi if (res < 0) { 10002886a82d876aa5e31a92444fec70208599c509cJorim Jaggi Slog.w(TAG, "Failed to add snapshot starting window res=" + res); 10102886a82d876aa5e31a92444fec70208599c509cJorim Jaggi return null; 10202886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } 10302886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } catch (RemoteException e) { 10402886a82d876aa5e31a92444fec70208599c509cJorim Jaggi // Local call. 10502886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } 10602886a82d876aa5e31a92444fec70208599c509cJorim Jaggi final TaskSnapshotSurface snapshotSurface = new TaskSnapshotSurface(service, window, 10702886a82d876aa5e31a92444fec70208599c509cJorim Jaggi surface); 10802886a82d876aa5e31a92444fec70208599c509cJorim Jaggi window.setOuter(snapshotSurface); 10902886a82d876aa5e31a92444fec70208599c509cJorim Jaggi try { 11002886a82d876aa5e31a92444fec70208599c509cJorim Jaggi session.relayout(window, window.mSeq, layoutParams, -1, -1, View.VISIBLE, 0, tmpFrame, 11102886a82d876aa5e31a92444fec70208599c509cJorim Jaggi tmpRect, tmpRect, tmpRect, tmpRect, tmpRect, tmpRect, tmpConfiguration, 11202886a82d876aa5e31a92444fec70208599c509cJorim Jaggi surface); 11302886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } catch (RemoteException e) { 11402886a82d876aa5e31a92444fec70208599c509cJorim Jaggi // Local call. 11502886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } 11602886a82d876aa5e31a92444fec70208599c509cJorim Jaggi snapshotSurface.drawSnapshot(snapshot); 11702886a82d876aa5e31a92444fec70208599c509cJorim Jaggi return snapshotSurface; 11802886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } 11902886a82d876aa5e31a92444fec70208599c509cJorim Jaggi 12002886a82d876aa5e31a92444fec70208599c509cJorim Jaggi private TaskSnapshotSurface(WindowManagerService service, Window window, Surface surface) { 12102886a82d876aa5e31a92444fec70208599c509cJorim Jaggi mService = service; 12202886a82d876aa5e31a92444fec70208599c509cJorim Jaggi mSession = WindowManagerGlobal.getWindowSession(); 12302886a82d876aa5e31a92444fec70208599c509cJorim Jaggi mWindow = window; 12402886a82d876aa5e31a92444fec70208599c509cJorim Jaggi mSurface = surface; 12502886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } 12602886a82d876aa5e31a92444fec70208599c509cJorim Jaggi 12702886a82d876aa5e31a92444fec70208599c509cJorim Jaggi @Override 12802886a82d876aa5e31a92444fec70208599c509cJorim Jaggi public void remove() { 12902886a82d876aa5e31a92444fec70208599c509cJorim Jaggi try { 13002886a82d876aa5e31a92444fec70208599c509cJorim Jaggi mSession.remove(mWindow); 13102886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } catch (RemoteException e) { 13202886a82d876aa5e31a92444fec70208599c509cJorim Jaggi // Local call. 13302886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } 13402886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } 13502886a82d876aa5e31a92444fec70208599c509cJorim Jaggi 13602886a82d876aa5e31a92444fec70208599c509cJorim Jaggi private void drawSnapshot(GraphicBuffer snapshot) { 13702886a82d876aa5e31a92444fec70208599c509cJorim Jaggi 13802886a82d876aa5e31a92444fec70208599c509cJorim Jaggi // TODO: Just wrap the buffer here without any copying. 13902886a82d876aa5e31a92444fec70208599c509cJorim Jaggi final Canvas c = mSurface.lockHardwareCanvas(); 14002886a82d876aa5e31a92444fec70208599c509cJorim Jaggi c.drawBitmap(Bitmap.createHardwareBitmap(snapshot), 0, 0, null); 14102886a82d876aa5e31a92444fec70208599c509cJorim Jaggi mSurface.unlockCanvasAndPost(c); 14202886a82d876aa5e31a92444fec70208599c509cJorim Jaggi final boolean reportNextDraw; 14302886a82d876aa5e31a92444fec70208599c509cJorim Jaggi synchronized (mService.mWindowMap) { 14402886a82d876aa5e31a92444fec70208599c509cJorim Jaggi mHasDrawn = true; 14502886a82d876aa5e31a92444fec70208599c509cJorim Jaggi reportNextDraw = mReportNextDraw; 14602886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } 14702886a82d876aa5e31a92444fec70208599c509cJorim Jaggi if (reportNextDraw) { 14802886a82d876aa5e31a92444fec70208599c509cJorim Jaggi reportDrawn(); 14902886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } 15002886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } 15102886a82d876aa5e31a92444fec70208599c509cJorim Jaggi 15202886a82d876aa5e31a92444fec70208599c509cJorim Jaggi private void reportDrawn() { 15302886a82d876aa5e31a92444fec70208599c509cJorim Jaggi synchronized (mService.mWindowMap) { 15402886a82d876aa5e31a92444fec70208599c509cJorim Jaggi mReportNextDraw = false; 15502886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } 15602886a82d876aa5e31a92444fec70208599c509cJorim Jaggi try { 15702886a82d876aa5e31a92444fec70208599c509cJorim Jaggi mSession.finishDrawing(mWindow); 15802886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } catch (RemoteException e) { 15902886a82d876aa5e31a92444fec70208599c509cJorim Jaggi // Local call. 16002886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } 16102886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } 16202886a82d876aa5e31a92444fec70208599c509cJorim Jaggi 16302886a82d876aa5e31a92444fec70208599c509cJorim Jaggi private static Handler sHandler = new Handler() { 16402886a82d876aa5e31a92444fec70208599c509cJorim Jaggi 16502886a82d876aa5e31a92444fec70208599c509cJorim Jaggi @Override 16602886a82d876aa5e31a92444fec70208599c509cJorim Jaggi public void handleMessage(Message msg) { 16702886a82d876aa5e31a92444fec70208599c509cJorim Jaggi switch (msg.what) { 16802886a82d876aa5e31a92444fec70208599c509cJorim Jaggi case MSG_REPORT_DRAW: 16902886a82d876aa5e31a92444fec70208599c509cJorim Jaggi final boolean hasDrawn; 17002886a82d876aa5e31a92444fec70208599c509cJorim Jaggi final TaskSnapshotSurface surface = (TaskSnapshotSurface) msg.obj; 17102886a82d876aa5e31a92444fec70208599c509cJorim Jaggi synchronized (surface.mService.mWindowMap) { 17202886a82d876aa5e31a92444fec70208599c509cJorim Jaggi hasDrawn = surface.mHasDrawn; 17302886a82d876aa5e31a92444fec70208599c509cJorim Jaggi if (!hasDrawn) { 17402886a82d876aa5e31a92444fec70208599c509cJorim Jaggi surface.mReportNextDraw = true; 17502886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } 17602886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } 17702886a82d876aa5e31a92444fec70208599c509cJorim Jaggi if (hasDrawn) { 17802886a82d876aa5e31a92444fec70208599c509cJorim Jaggi surface.reportDrawn(); 17902886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } 18002886a82d876aa5e31a92444fec70208599c509cJorim Jaggi break; 18102886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } 18202886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } 18302886a82d876aa5e31a92444fec70208599c509cJorim Jaggi }; 18402886a82d876aa5e31a92444fec70208599c509cJorim Jaggi 18502886a82d876aa5e31a92444fec70208599c509cJorim Jaggi private static class Window extends BaseIWindow { 18602886a82d876aa5e31a92444fec70208599c509cJorim Jaggi 18702886a82d876aa5e31a92444fec70208599c509cJorim Jaggi private TaskSnapshotSurface mOuter; 18802886a82d876aa5e31a92444fec70208599c509cJorim Jaggi 18902886a82d876aa5e31a92444fec70208599c509cJorim Jaggi public void setOuter(TaskSnapshotSurface outer) { 19002886a82d876aa5e31a92444fec70208599c509cJorim Jaggi mOuter = outer; 19102886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } 19202886a82d876aa5e31a92444fec70208599c509cJorim Jaggi 19302886a82d876aa5e31a92444fec70208599c509cJorim Jaggi @Override 19402886a82d876aa5e31a92444fec70208599c509cJorim Jaggi public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, 19502886a82d876aa5e31a92444fec70208599c509cJorim Jaggi Rect stableInsets, Rect outsets, boolean reportDraw, Configuration newConfig, 19602886a82d876aa5e31a92444fec70208599c509cJorim Jaggi Rect backDropFrame, boolean forceLayout, boolean alwaysConsumeNavBar) { 19702886a82d876aa5e31a92444fec70208599c509cJorim Jaggi if (reportDraw) { 19802886a82d876aa5e31a92444fec70208599c509cJorim Jaggi sHandler.obtainMessage(MSG_REPORT_DRAW, mOuter).sendToTarget(); 19902886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } 20002886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } 20102886a82d876aa5e31a92444fec70208599c509cJorim Jaggi } 20202886a82d876aa5e31a92444fec70208599c509cJorim Jaggi} 203