1 /* 2 * Copyright (C) 2014 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 com.android.internal.protolog.WmProtoLogGroups.WM_SHOW_TRANSACTIONS; 20 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_ALL; 21 import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN; 22 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE; 23 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; 24 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; 25 26 import android.annotation.IntDef; 27 import android.content.Context; 28 import android.os.HandlerExecutor; 29 import android.os.Trace; 30 import android.util.Slog; 31 import android.util.TimeUtils; 32 import android.view.Choreographer; 33 import android.view.SurfaceControl; 34 35 import com.android.internal.protolog.ProtoLog; 36 import com.android.server.policy.WindowManagerPolicy; 37 38 import java.io.PrintWriter; 39 import java.lang.annotation.Retention; 40 import java.lang.annotation.RetentionPolicy; 41 import java.util.ArrayList; 42 43 /** 44 * Singleton class that carries out the animations and Surface operations in a separate task 45 * on behalf of WindowManagerService. 46 */ 47 public class WindowAnimator { 48 private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowAnimator" : TAG_WM; 49 50 final WindowManagerService mService; 51 final Context mContext; 52 final WindowManagerPolicy mPolicy; 53 54 /** Is any window animating? */ 55 private boolean mLastRootAnimating; 56 57 final Choreographer.FrameCallback mAnimationFrameCallback; 58 59 /** Time of current animation step. Reset on each iteration */ 60 long mCurrentTime; 61 62 private boolean mInitialized = false; 63 64 private Choreographer mChoreographer; 65 66 private final HandlerExecutor mExecutor; 67 68 /** 69 * Indicates whether we have an animation frame callback scheduled, which will happen at 70 * vsync-app and then schedule the animation tick at the right time (vsync-sf). 71 */ 72 private boolean mAnimationFrameCallbackScheduled; 73 boolean mNotifyWhenNoAnimation = false; 74 75 /** 76 * A list of runnable that need to be run after {@link WindowContainer#prepareSurfaces} is 77 * executed and the corresponding transaction is closed and applied. 78 */ 79 private ArrayList<Runnable> mAfterPrepareSurfacesRunnables = new ArrayList<>(); 80 81 private final SurfaceControl.Transaction mTransaction; 82 83 /** The pending transaction is applied. */ 84 static final int PENDING_STATE_NONE = 0; 85 /** There are some (significant) operations set to the pending transaction. */ 86 static final int PENDING_STATE_HAS_CHANGES = 1; 87 /** The pending transaction needs to be applied before sending sync transaction to shell. */ 88 static final int PENDING_STATE_NEED_APPLY = 2; 89 90 @IntDef(prefix = { "PENDING_STATE_" }, value = { 91 PENDING_STATE_NONE, 92 PENDING_STATE_HAS_CHANGES, 93 PENDING_STATE_NEED_APPLY, 94 }) 95 @Retention(RetentionPolicy.SOURCE) 96 @interface PendingState {} 97 98 /** The global state of pending transaction. */ 99 @PendingState 100 int mPendingState; 101 WindowAnimator(final WindowManagerService service)102 WindowAnimator(final WindowManagerService service) { 103 mService = service; 104 mContext = service.mContext; 105 mPolicy = service.mPolicy; 106 mTransaction = service.mTransactionFactory.get(); 107 service.mAnimationHandler.runWithScissors( 108 () -> mChoreographer = Choreographer.getSfInstance(), 0 /* timeout */); 109 mExecutor = new HandlerExecutor(service.mAnimationHandler); 110 111 mAnimationFrameCallback = frameTimeNs -> { 112 synchronized (mService.mGlobalLock) { 113 mAnimationFrameCallbackScheduled = false; 114 animate(frameTimeNs); 115 if (mNotifyWhenNoAnimation && !mLastRootAnimating) { 116 mService.mGlobalLock.notifyAll(); 117 } 118 } 119 }; 120 } 121 ready()122 void ready() { 123 mInitialized = true; 124 } 125 animate(long frameTimeNs)126 private void animate(long frameTimeNs) { 127 if (!mInitialized) { 128 return; 129 } 130 131 // Schedule next frame already such that back-pressure happens continuously. 132 scheduleAnimation(); 133 134 final RootWindowContainer root = mService.mRoot; 135 boolean rootAnimating = false; 136 mCurrentTime = frameTimeNs / TimeUtils.NANOS_PER_MS; 137 if (DEBUG_WINDOW_TRACE) { 138 Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime); 139 } 140 141 ProtoLog.i(WM_SHOW_TRANSACTIONS, ">>> OPEN TRANSACTION animate"); 142 try { 143 // Remove all deferred displays, tasks, and activities. 144 root.handleCompleteDeferredRemoval(); 145 146 final AccessibilityController accessibilityController = 147 mService.mAccessibilityController; 148 final int numDisplays = root.getChildCount(); 149 for (int i = 0; i < numDisplays; i++) { 150 final DisplayContent dc = root.getChildAt(i); 151 // Update animations of all applications, including those associated with 152 // exiting/removed apps. 153 dc.updateWindowsForAnimator(); 154 dc.prepareSurfaces(); 155 } 156 157 for (int i = 0; i < numDisplays; i++) { 158 final DisplayContent dc = root.getChildAt(i); 159 if (accessibilityController.hasCallbacks()) { 160 accessibilityController 161 .recomputeMagnifiedRegionAndDrawMagnifiedRegionBorderIfNeeded( 162 dc.mDisplayId); 163 } 164 165 if (dc.isAnimating(CHILDREN, ANIMATION_TYPE_ALL)) { 166 rootAnimating = true; 167 if (!dc.mLastContainsRunningSurfaceAnimator) { 168 dc.mLastContainsRunningSurfaceAnimator = true; 169 dc.enableHighFrameRate(true); 170 } 171 } else if (dc.mLastContainsRunningSurfaceAnimator) { 172 dc.mLastContainsRunningSurfaceAnimator = false; 173 dc.enableHighFrameRate(false); 174 } 175 mTransaction.merge(dc.getPendingTransaction()); 176 } 177 178 cancelAnimation(); 179 180 if (mService.mWatermark != null) { 181 mService.mWatermark.drawIfNeeded(); 182 } 183 184 } catch (RuntimeException e) { 185 Slog.wtf(TAG, "Unhandled exception in Window Manager", e); 186 } 187 188 final boolean hasPendingLayoutChanges = root.hasPendingLayoutChanges(this); 189 if (hasPendingLayoutChanges) { 190 mService.mWindowPlacerLocked.requestTraversal(); 191 } 192 193 if (rootAnimating && !mLastRootAnimating) { 194 Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "animating", 0); 195 } 196 if (!rootAnimating && mLastRootAnimating) { 197 mService.mWindowPlacerLocked.requestTraversal(); 198 Trace.asyncTraceEnd(Trace.TRACE_TAG_WINDOW_MANAGER, "animating", 0); 199 } 200 mLastRootAnimating = rootAnimating; 201 202 final ArrayList<Runnable> afterPrepareSurfacesRunnables = mAfterPrepareSurfacesRunnables; 203 if (!afterPrepareSurfacesRunnables.isEmpty()) { 204 mAfterPrepareSurfacesRunnables = new ArrayList<>(); 205 mTransaction.addTransactionCommittedListener(mExecutor, () -> { 206 synchronized (mService.mGlobalLock) { 207 // Traverse in order they were added. 208 for (int i = 0, size = afterPrepareSurfacesRunnables.size(); i < size; i++) { 209 afterPrepareSurfacesRunnables.get(i).run(); 210 } 211 afterPrepareSurfacesRunnables.clear(); 212 } 213 }); 214 } 215 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "applyTransaction"); 216 mTransaction.apply(); 217 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); 218 mPendingState = PENDING_STATE_NONE; 219 mService.mWindowTracing.logState("WindowAnimator"); 220 ProtoLog.i(WM_SHOW_TRANSACTIONS, "<<< CLOSE TRANSACTION animate"); 221 222 mService.mAtmService.mTaskOrganizerController.dispatchPendingEvents(); 223 224 if (DEBUG_WINDOW_TRACE) { 225 Slog.i(TAG, "!!! animate: exit" 226 + " hasPendingLayoutChanges=" + hasPendingLayoutChanges); 227 } 228 } 229 dumpLocked(PrintWriter pw, String prefix, boolean dumpAll)230 public void dumpLocked(PrintWriter pw, String prefix, boolean dumpAll) { 231 final String subPrefix = " " + prefix; 232 233 for (int i = 0; i < mService.mRoot.getChildCount(); i++) { 234 final DisplayContent dc = mService.mRoot.getChildAt(i); 235 pw.print(prefix); pw.print(dc); pw.println(":"); 236 dc.dumpWindowAnimators(pw, subPrefix); 237 pw.println(); 238 } 239 240 pw.println(); 241 242 if (dumpAll) { 243 pw.print(prefix); pw.print("mCurrentTime="); 244 pw.println(TimeUtils.formatUptime(mCurrentTime)); 245 } 246 } 247 scheduleAnimation()248 void scheduleAnimation() { 249 if (!mAnimationFrameCallbackScheduled) { 250 mAnimationFrameCallbackScheduled = true; 251 mChoreographer.postFrameCallback(mAnimationFrameCallback); 252 } 253 } 254 cancelAnimation()255 private void cancelAnimation() { 256 if (mAnimationFrameCallbackScheduled) { 257 mAnimationFrameCallbackScheduled = false; 258 mChoreographer.removeFrameCallback(mAnimationFrameCallback); 259 } 260 } 261 isAnimationScheduled()262 boolean isAnimationScheduled() { 263 return mAnimationFrameCallbackScheduled; 264 } 265 applyPendingTransaction()266 void applyPendingTransaction() { 267 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "applyPendingTransaction"); 268 mPendingState = PENDING_STATE_NONE; 269 final int numDisplays = mService.mRoot.getChildCount(); 270 if (numDisplays == 1) { 271 mService.mRoot.getChildAt(0).getPendingTransaction().apply(); 272 } else { 273 for (int i = 0; i < numDisplays; i++) { 274 mTransaction.merge(mService.mRoot.getChildAt(i).getPendingTransaction()); 275 } 276 mTransaction.apply(); 277 } 278 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); 279 } 280 281 /** 282 * Adds a runnable to be executed after {@link WindowContainer#prepareSurfaces} is called and 283 * the corresponding transaction is closed, applied, and committed. 284 */ addAfterPrepareSurfacesRunnable(Runnable r)285 void addAfterPrepareSurfacesRunnable(Runnable r) { 286 mAfterPrepareSurfacesRunnables.add(r); 287 scheduleAnimation(); 288 } 289 } 290