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 24 import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC; 25 import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_TRANSACTIONS; 26 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; 27 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; 28 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; 29 import static com.android.server.wm.WindowSurfaceControllerProto.SHOWN; 30 31 import android.os.Debug; 32 import android.os.Trace; 33 import android.util.EventLog; 34 import android.util.Slog; 35 import android.util.proto.ProtoOutputStream; 36 import android.view.SurfaceControl; 37 import android.view.WindowContentFrameStats; 38 39 import com.android.internal.protolog.common.ProtoLog; 40 41 import java.io.PrintWriter; 42 43 class WindowSurfaceController { 44 static final String TAG = TAG_WITH_CLASS_NAME ? "WindowSurfaceController" : TAG_WM; 45 46 final WindowStateAnimator mAnimator; 47 48 SurfaceControl mSurfaceControl; 49 50 // Should only be set from within setShown(). 51 private boolean mSurfaceShown = false; 52 53 private final String title; 54 55 private final WindowManagerService mService; 56 57 private final int mWindowType; 58 private final Session mWindowSession; 59 60 WindowSurfaceController(String name, int format, int flags, WindowStateAnimator animator, int windowType)61 WindowSurfaceController(String name, int format, int flags, WindowStateAnimator animator, 62 int windowType) { 63 mAnimator = animator; 64 65 title = name; 66 67 mService = animator.mService; 68 final WindowState win = animator.mWin; 69 mWindowType = windowType; 70 mWindowSession = win.mSession; 71 72 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl"); 73 mSurfaceControl = win.makeSurface() 74 .setParent(win.getSurfaceControl()) 75 .setName(name) 76 .setFormat(format) 77 .setFlags(flags) 78 .setMetadata(METADATA_WINDOW_TYPE, windowType) 79 .setMetadata(METADATA_OWNER_UID, mWindowSession.mUid) 80 .setMetadata(METADATA_OWNER_PID, mWindowSession.mPid) 81 .setCallsite("WindowSurfaceController") 82 .setBLASTLayer().build(); 83 84 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 85 } 86 hide(SurfaceControl.Transaction transaction, String reason)87 void hide(SurfaceControl.Transaction transaction, String reason) { 88 ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE HIDE ( %s ): %s", reason, title); 89 90 if (mSurfaceShown) { 91 hideSurface(transaction); 92 } 93 } 94 hideSurface(SurfaceControl.Transaction transaction)95 private void hideSurface(SurfaceControl.Transaction transaction) { 96 if (mSurfaceControl == null) { 97 return; 98 } 99 setShown(false); 100 try { 101 transaction.hide(mSurfaceControl); 102 if (mAnimator.mIsWallpaper) { 103 final DisplayContent dc = mAnimator.mWin.getDisplayContent(); 104 EventLog.writeEvent(EventLogTags.WM_WALLPAPER_SURFACE, 105 dc.mDisplayId, 0 /* request hidden */, 106 String.valueOf(dc.mWallpaperController.getWallpaperTarget())); 107 } 108 } catch (RuntimeException e) { 109 Slog.w(TAG, "Exception hiding surface in " + this); 110 } 111 } 112 destroy(SurfaceControl.Transaction t)113 void destroy(SurfaceControl.Transaction t) { 114 ProtoLog.i(WM_SHOW_SURFACE_ALLOC, 115 "Destroying surface %s called by %s", this, Debug.getCallers(8)); 116 try { 117 if (mSurfaceControl != null) { 118 if (mAnimator.mIsWallpaper && !mAnimator.mWin.mWindowRemovalAllowed 119 && !mAnimator.mWin.mRemoveOnExit) { 120 // The wallpaper surface should have the same lifetime as its window. 121 Slog.e(TAG, "Unexpected removing wallpaper surface of " + mAnimator.mWin 122 + " by " + Debug.getCallers(8)); 123 } 124 t.remove(mSurfaceControl); 125 } 126 } catch (RuntimeException e) { 127 Slog.w(TAG, "Error destroying surface in: " + this, e); 128 } finally { 129 setShown(false); 130 mSurfaceControl = null; 131 } 132 } 133 prepareToShowInTransaction(SurfaceControl.Transaction t, float alpha)134 boolean prepareToShowInTransaction(SurfaceControl.Transaction t, float alpha) { 135 if (mSurfaceControl == null) { 136 return false; 137 } 138 139 t.setAlpha(mSurfaceControl, alpha); 140 return true; 141 } 142 setOpaque(boolean isOpaque)143 void setOpaque(boolean isOpaque) { 144 ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE isOpaque=%b: %s", isOpaque, title); 145 146 if (mSurfaceControl == null) { 147 return; 148 } 149 150 mAnimator.mWin.getPendingTransaction().setOpaque(mSurfaceControl, isOpaque); 151 mService.scheduleAnimationLocked(); 152 } 153 setColorSpaceAgnostic(SurfaceControl.Transaction t, boolean agnostic)154 void setColorSpaceAgnostic(SurfaceControl.Transaction t, boolean agnostic) { 155 ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE isColorSpaceAgnostic=%b: %s", agnostic, title); 156 157 if (mSurfaceControl == null) { 158 return; 159 } 160 t.setColorSpaceAgnostic(mSurfaceControl, agnostic); 161 } 162 showRobustly(SurfaceControl.Transaction t)163 void showRobustly(SurfaceControl.Transaction t) { 164 ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE SHOW (performLayout): %s", title); 165 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this 166 + " during relayout"); 167 168 if (mSurfaceShown) { 169 return; 170 } 171 172 setShown(true); 173 t.show(mSurfaceControl); 174 if (mAnimator.mIsWallpaper) { 175 final DisplayContent dc = mAnimator.mWin.getDisplayContent(); 176 EventLog.writeEvent(EventLogTags.WM_WALLPAPER_SURFACE, 177 dc.mDisplayId, 1 /* request shown */, 178 String.valueOf(dc.mWallpaperController.getWallpaperTarget())); 179 } 180 } 181 clearWindowContentFrameStats()182 boolean clearWindowContentFrameStats() { 183 if (mSurfaceControl == null) { 184 return false; 185 } 186 return mSurfaceControl.clearContentFrameStats(); 187 } 188 getWindowContentFrameStats(WindowContentFrameStats outStats)189 boolean getWindowContentFrameStats(WindowContentFrameStats outStats) { 190 if (mSurfaceControl == null) { 191 return false; 192 } 193 return mSurfaceControl.getContentFrameStats(outStats); 194 } 195 hasSurface()196 boolean hasSurface() { 197 return mSurfaceControl != null; 198 } 199 getSurfaceControl(SurfaceControl outSurfaceControl)200 void getSurfaceControl(SurfaceControl outSurfaceControl) { 201 outSurfaceControl.copyFrom(mSurfaceControl, "WindowSurfaceController.getSurfaceControl"); 202 } 203 getShown()204 boolean getShown() { 205 return mSurfaceShown; 206 } 207 setShown(boolean surfaceShown)208 void setShown(boolean surfaceShown) { 209 mSurfaceShown = surfaceShown; 210 211 mService.updateNonSystemOverlayWindowsVisibilityIfNeeded(mAnimator.mWin, surfaceShown); 212 213 mAnimator.mWin.onSurfaceShownChanged(surfaceShown); 214 215 if (mWindowSession != null) { 216 mWindowSession.onWindowSurfaceVisibilityChanged(this, mSurfaceShown, mWindowType); 217 } 218 } 219 dumpDebug(ProtoOutputStream proto, long fieldId)220 void dumpDebug(ProtoOutputStream proto, long fieldId) { 221 final long token = proto.start(fieldId); 222 proto.write(SHOWN, mSurfaceShown); 223 proto.end(token); 224 } 225 dump(PrintWriter pw, String prefix, boolean dumpAll)226 public void dump(PrintWriter pw, String prefix, boolean dumpAll) { 227 if (dumpAll) { 228 pw.print(prefix); pw.print("mSurface="); pw.println(mSurfaceControl); 229 } 230 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown); 231 } 232 233 @Override toString()234 public String toString() { 235 return mSurfaceControl.toString(); 236 } 237 } 238