• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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 
17 package com.android.server.wm;
18 
19 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
20 import static android.view.SurfaceControl.METADATA_OWNER_PID;
21 import static android.view.SurfaceControl.METADATA_OWNER_UID;
22 import static android.view.SurfaceControl.METADATA_WINDOW_TYPE;
23 import static android.view.SurfaceControl.getGlobalTransaction;
24 
25 import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
26 import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
27 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
28 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
29 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
30 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
31 import static com.android.server.wm.WindowSurfaceControllerProto.LAYER;
32 import static com.android.server.wm.WindowSurfaceControllerProto.SHOWN;
33 
34 import android.os.Debug;
35 import android.os.Trace;
36 import android.util.EventLog;
37 import android.util.Slog;
38 import android.util.proto.ProtoOutputStream;
39 import android.view.SurfaceControl;
40 import android.view.WindowContentFrameStats;
41 import android.view.WindowManager;
42 
43 import com.android.internal.protolog.common.ProtoLog;
44 
45 import java.io.PrintWriter;
46 
47 class WindowSurfaceController {
48     static final String TAG = TAG_WITH_CLASS_NAME ? "WindowSurfaceController" : TAG_WM;
49 
50     final WindowStateAnimator mAnimator;
51 
52     SurfaceControl mSurfaceControl;
53 
54     // Should only be set from within setShown().
55     private boolean mSurfaceShown = false;
56     private float mSurfaceX = 0;
57     private float mSurfaceY = 0;
58 
59     // Initialize to the identity matrix.
60     private float mLastDsdx = 1;
61     private float mLastDtdx = 0;
62     private float mLastDsdy = 0;
63     private float mLastDtdy = 1;
64 
65     private float mSurfaceAlpha = 0;
66 
67     private int mSurfaceLayer = 0;
68 
69     private final String title;
70 
71     private final WindowManagerService mService;
72 
73     private final int mWindowType;
74     private final Session mWindowSession;
75 
76     // Used to track whether we have called detach children on the way to invisibility.
77     boolean mChildrenDetached;
78 
WindowSurfaceController(String name, int format, int flags, WindowStateAnimator animator, int windowType)79     WindowSurfaceController(String name, int format, int flags, WindowStateAnimator animator,
80             int windowType) {
81         mAnimator = animator;
82 
83         title = name;
84 
85         mService = animator.mService;
86         final WindowState win = animator.mWin;
87         mWindowType = windowType;
88         mWindowSession = win.mSession;
89 
90         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");
91         final SurfaceControl.Builder b = win.makeSurface()
92                 .setParent(win.getSurfaceControl())
93                 .setName(name)
94                 .setFormat(format)
95                 .setFlags(flags)
96                 .setMetadata(METADATA_WINDOW_TYPE, windowType)
97                 .setMetadata(METADATA_OWNER_UID, mWindowSession.mUid)
98                 .setMetadata(METADATA_OWNER_PID, mWindowSession.mPid)
99                 .setCallsite("WindowSurfaceController");
100 
101         final boolean useBLAST = mService.mUseBLAST && ((win.getAttrs().privateFlags
102                 & WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST) != 0);
103 
104         if (useBLAST) {
105             b.setBLASTLayer();
106         }
107 
108         mSurfaceControl = b.build();
109 
110         Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
111     }
112 
hide(SurfaceControl.Transaction transaction, String reason)113     void hide(SurfaceControl.Transaction transaction, String reason) {
114         ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE HIDE ( %s ): %s", reason, title);
115 
116         if (mSurfaceShown) {
117             hideSurface(transaction);
118         }
119     }
120 
hideSurface(SurfaceControl.Transaction transaction)121     private void hideSurface(SurfaceControl.Transaction transaction) {
122         if (mSurfaceControl == null) {
123             return;
124         }
125         setShown(false);
126         try {
127             transaction.hide(mSurfaceControl);
128             if (mAnimator.mIsWallpaper) {
129                 final DisplayContent dc = mAnimator.mWin.getDisplayContent();
130                 EventLog.writeEvent(EventLogTags.WM_WALLPAPER_SURFACE,
131                         dc.mDisplayId, 0 /* request hidden */,
132                         String.valueOf(dc.mWallpaperController.getWallpaperTarget()));
133             }
134         } catch (RuntimeException e) {
135             Slog.w(TAG, "Exception hiding surface in " + this);
136         }
137     }
138 
destroy(SurfaceControl.Transaction t)139     void destroy(SurfaceControl.Transaction t) {
140         ProtoLog.i(WM_SHOW_SURFACE_ALLOC,
141                 "Destroying surface %s called by %s", this, Debug.getCallers(8));
142         try {
143             if (mSurfaceControl != null) {
144                 if (mAnimator.mIsWallpaper && !mAnimator.mWin.mWindowRemovalAllowed
145                         && !mAnimator.mWin.mRemoveOnExit) {
146                     // The wallpaper surface should have the same lifetime as its window.
147                     Slog.e(TAG, "Unexpected removing wallpaper surface of " + mAnimator.mWin
148                             + " by " + Debug.getCallers(8));
149                 }
150                 t.remove(mSurfaceControl);
151             }
152         } catch (RuntimeException e) {
153             Slog.w(TAG, "Error destroying surface in: " + this, e);
154         } finally {
155             setShown(false);
156             mSurfaceControl = null;
157         }
158     }
159 
setPosition(SurfaceControl.Transaction t, float left, float top)160     void setPosition(SurfaceControl.Transaction t, float left, float top) {
161         final boolean surfaceMoved = mSurfaceX != left || mSurfaceY != top;
162         if (!surfaceMoved) {
163             return;
164         }
165 
166         mSurfaceX = left;
167         mSurfaceY = top;
168 
169         ProtoLog.i(WM_SHOW_TRANSACTIONS,
170                 "SURFACE POS (setPositionInTransaction) @ (%f,%f): %s", left, top, title);
171 
172         t.setPosition(mSurfaceControl, left, top);
173     }
174 
setMatrix(SurfaceControl.Transaction t, float dsdx, float dtdx, float dtdy, float dsdy)175     void setMatrix(SurfaceControl.Transaction t, float dsdx, float dtdx, float dtdy, float dsdy) {
176         final boolean matrixChanged = mLastDsdx != dsdx || mLastDtdx != dtdx ||
177                                       mLastDtdy != dtdy || mLastDsdy != dsdy;
178         if (!matrixChanged) {
179             return;
180         }
181 
182         mLastDsdx = dsdx;
183         mLastDtdx = dtdx;
184         mLastDtdy = dtdy;
185         mLastDsdy = dsdy;
186 
187         ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE MATRIX [%f,%f,%f,%f]: %s",
188                 dsdx, dtdx, dtdy, dsdy, title);
189         t.setMatrix(mSurfaceControl, dsdx, dtdx, dtdy, dsdy);
190     }
191 
prepareToShowInTransaction(SurfaceControl.Transaction t, float alpha)192     boolean prepareToShowInTransaction(SurfaceControl.Transaction t, float alpha) {
193         if (mSurfaceControl == null) {
194             return false;
195         }
196 
197         mSurfaceAlpha = alpha;
198         t.setAlpha(mSurfaceControl, alpha);
199         return true;
200     }
201 
setOpaque(boolean isOpaque)202     void setOpaque(boolean isOpaque) {
203         ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE isOpaque=%b: %s", isOpaque, title);
204 
205         if (mSurfaceControl == null) {
206             return;
207         }
208         if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setOpaqueLocked");
209         mService.openSurfaceTransaction();
210         try {
211             getGlobalTransaction().setOpaque(mSurfaceControl, isOpaque);
212         } finally {
213             mService.closeSurfaceTransaction("setOpaqueLocked");
214             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setOpaqueLocked");
215         }
216     }
217 
setSecure(boolean isSecure)218     void setSecure(boolean isSecure) {
219         ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE isSecure=%b: %s", isSecure, title);
220 
221         if (mSurfaceControl == null) {
222             return;
223         }
224         if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setSecureLocked");
225         mService.openSurfaceTransaction();
226         try {
227             getGlobalTransaction().setSecure(mSurfaceControl, isSecure);
228 
229             final DisplayContent dc = mAnimator.mWin.mDisplayContent;
230             if (dc != null) {
231                 dc.refreshImeSecureFlag(getGlobalTransaction());
232             }
233         } finally {
234             mService.closeSurfaceTransaction("setSecure");
235             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setSecureLocked");
236         }
237     }
238 
setColorSpaceAgnostic(boolean agnostic)239     void setColorSpaceAgnostic(boolean agnostic) {
240         ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE isColorSpaceAgnostic=%b: %s", agnostic, title);
241 
242         if (mSurfaceControl == null) {
243             return;
244         }
245         if (SHOW_LIGHT_TRANSACTIONS) {
246             Slog.i(TAG, ">>> OPEN TRANSACTION setColorSpaceAgnosticLocked");
247         }
248         mService.openSurfaceTransaction();
249         try {
250             getGlobalTransaction().setColorSpaceAgnostic(mSurfaceControl, agnostic);
251         } finally {
252             mService.closeSurfaceTransaction("setColorSpaceAgnostic");
253             if (SHOW_LIGHT_TRANSACTIONS) {
254                 Slog.i(TAG, "<<< CLOSE TRANSACTION setColorSpaceAgnosticLocked");
255             }
256         }
257     }
258 
showRobustly(SurfaceControl.Transaction t)259     boolean showRobustly(SurfaceControl.Transaction t) {
260         ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE SHOW (performLayout): %s", title);
261         if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
262                 + " during relayout");
263 
264         if (mSurfaceShown) {
265             return true;
266         }
267 
268         setShown(true);
269         t.show(mSurfaceControl);
270         if (mAnimator.mIsWallpaper) {
271             final DisplayContent dc = mAnimator.mWin.getDisplayContent();
272             EventLog.writeEvent(EventLogTags.WM_WALLPAPER_SURFACE,
273                     dc.mDisplayId, 1 /* request shown */,
274                     String.valueOf(dc.mWallpaperController.getWallpaperTarget()));
275         }
276         return true;
277     }
278 
clearWindowContentFrameStats()279     boolean clearWindowContentFrameStats() {
280         if (mSurfaceControl == null) {
281             return false;
282         }
283         return mSurfaceControl.clearContentFrameStats();
284     }
285 
getWindowContentFrameStats(WindowContentFrameStats outStats)286     boolean getWindowContentFrameStats(WindowContentFrameStats outStats) {
287         if (mSurfaceControl == null) {
288             return false;
289         }
290         return mSurfaceControl.getContentFrameStats(outStats);
291     }
292 
hasSurface()293     boolean hasSurface() {
294         return mSurfaceControl != null;
295     }
296 
getSurfaceControl(SurfaceControl outSurfaceControl)297     void getSurfaceControl(SurfaceControl outSurfaceControl) {
298         outSurfaceControl.copyFrom(mSurfaceControl, "WindowSurfaceController.getSurfaceControl");
299     }
300 
getShown()301     boolean getShown() {
302         return mSurfaceShown;
303     }
304 
setShown(boolean surfaceShown)305     void setShown(boolean surfaceShown) {
306         mSurfaceShown = surfaceShown;
307 
308         mService.updateNonSystemOverlayWindowsVisibilityIfNeeded(mAnimator.mWin, surfaceShown);
309 
310         mAnimator.mWin.onSurfaceShownChanged(surfaceShown);
311 
312         if (mWindowSession != null) {
313             mWindowSession.onWindowSurfaceVisibilityChanged(this, mSurfaceShown, mWindowType);
314         }
315     }
316 
dumpDebug(ProtoOutputStream proto, long fieldId)317     void dumpDebug(ProtoOutputStream proto, long fieldId) {
318         final long token = proto.start(fieldId);
319         proto.write(SHOWN, mSurfaceShown);
320         proto.write(LAYER, mSurfaceLayer);
321         proto.end(token);
322     }
323 
dump(PrintWriter pw, String prefix, boolean dumpAll)324     public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
325         if (dumpAll) {
326             pw.print(prefix); pw.print("mSurface="); pw.println(mSurfaceControl);
327         }
328         pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
329         pw.print(" layer="); pw.print(mSurfaceLayer);
330         pw.print(" alpha="); pw.print(mSurfaceAlpha);
331         pw.print(" rect=("); pw.print(mSurfaceX);
332         pw.print(","); pw.print(mSurfaceY); pw.print(") ");
333         pw.print(" transform=("); pw.print(mLastDsdx); pw.print(", ");
334         pw.print(mLastDtdx); pw.print(", "); pw.print(mLastDsdy);
335         pw.print(", "); pw.print(mLastDtdy); pw.println(")");
336     }
337 
338     @Override
toString()339     public String toString() {
340         return mSurfaceControl.toString();
341     }
342 }
343