• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY;
20 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
21 import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN;
22 import static android.view.WindowManager.TRANSIT_OLD_TASK_TO_FRONT;
23 import static android.view.WindowManager.TRANSIT_OLD_WALLPAPER_CLOSE;
24 
25 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_REMOTE_ANIMATIONS;
26 import static com.android.server.wm.AnimationAdapterProto.REMOTE;
27 import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET;
28 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;
29 
30 import android.graphics.Rect;
31 import android.os.SystemClock;
32 import android.util.proto.ProtoOutputStream;
33 import android.view.RemoteAnimationTarget;
34 import android.view.SurfaceControl;
35 import android.view.WindowManager;
36 
37 import com.android.internal.protolog.common.ProtoLog;
38 import com.android.server.policy.WindowManagerPolicy;
39 
40 import java.io.PrintWriter;
41 import java.util.ArrayList;
42 
43 class NonAppWindowAnimationAdapter implements AnimationAdapter {
44 
45     private final WindowContainer mWindowContainer;
46     private RemoteAnimationTarget mTarget;
47     private SurfaceControl mCapturedLeash;
48     private SurfaceAnimator.OnAnimationFinishedCallback mCapturedLeashFinishCallback;
49     private @SurfaceAnimator.AnimationType int mLastAnimationType;
50 
51     private long mDurationHint;
52     private long mStatusBarTransitionDelay;
53 
54     @Override
getShowWallpaper()55     public boolean getShowWallpaper() {
56         return false;
57     }
58 
NonAppWindowAnimationAdapter(WindowContainer w, long durationHint, long statusBarTransitionDelay)59     NonAppWindowAnimationAdapter(WindowContainer w, long durationHint,
60             long statusBarTransitionDelay) {
61         mWindowContainer = w;
62         mDurationHint = durationHint;
63         mStatusBarTransitionDelay = statusBarTransitionDelay;
64     }
65 
startNonAppWindowAnimations(WindowManagerService service, DisplayContent displayContent, @WindowManager.TransitionOldType int transit, long durationHint, long statusBarTransitionDelay, ArrayList<NonAppWindowAnimationAdapter> adaptersOut)66     static RemoteAnimationTarget[] startNonAppWindowAnimations(WindowManagerService service,
67             DisplayContent displayContent, @WindowManager.TransitionOldType int transit,
68             long durationHint, long statusBarTransitionDelay,
69             ArrayList<NonAppWindowAnimationAdapter> adaptersOut) {
70         final ArrayList<RemoteAnimationTarget> targets = new ArrayList<>();
71         if (transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY
72                 || transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER) {
73             startNonAppWindowAnimationsForKeyguardExit(
74                     service, durationHint, statusBarTransitionDelay, targets, adaptersOut);
75         } else if (transit == TRANSIT_OLD_TASK_OPEN || transit == TRANSIT_OLD_TASK_TO_FRONT
76                 || transit == TRANSIT_OLD_WALLPAPER_CLOSE) {
77             final boolean shouldAttachNavBarToApp =
78                     displayContent.getDisplayPolicy().shouldAttachNavBarToAppDuringTransition()
79                             && service.getRecentsAnimationController() == null
80                             && displayContent.getFadeRotationAnimationController() == null;
81             if (shouldAttachNavBarToApp) {
82                 startNavigationBarWindowAnimation(
83                         displayContent, durationHint, statusBarTransitionDelay, targets,
84                         adaptersOut);
85             }
86         }
87         return targets.toArray(new RemoteAnimationTarget[targets.size()]);
88     }
89 
90     /**
91      * Creates and starts remote animations for all the visible non app windows.
92      *
93      * @return RemoteAnimationTarget[] targets for all the visible non app windows
94      */
startNonAppWindowAnimationsForKeyguardExit(WindowManagerService service, long durationHint, long statusBarTransitionDelay, ArrayList<RemoteAnimationTarget> targets, ArrayList<NonAppWindowAnimationAdapter> adaptersOut)95     private static void startNonAppWindowAnimationsForKeyguardExit(WindowManagerService service,
96             long durationHint, long statusBarTransitionDelay,
97             ArrayList<RemoteAnimationTarget> targets,
98             ArrayList<NonAppWindowAnimationAdapter> adaptersOut) {
99 
100         final WindowManagerPolicy policy = service.mPolicy;
101         service.mRoot.forAllWindows(nonAppWindow -> {
102             // Animation on the IME window is controlled via Insets.
103             if (nonAppWindow.mActivityRecord == null && policy.canBeHiddenByKeyguardLw(nonAppWindow)
104                     && nonAppWindow.wouldBeVisibleIfPolicyIgnored() && !nonAppWindow.isVisible()
105                     && nonAppWindow != service.mRoot.getCurrentInputMethodWindow()) {
106                 final NonAppWindowAnimationAdapter nonAppAdapter = new NonAppWindowAnimationAdapter(
107                         nonAppWindow, durationHint, statusBarTransitionDelay);
108                 adaptersOut.add(nonAppAdapter);
109                 nonAppWindow.startAnimation(nonAppWindow.getPendingTransaction(),
110                         nonAppAdapter, false /* hidden */, ANIMATION_TYPE_WINDOW_ANIMATION);
111                 targets.add(nonAppAdapter.createRemoteAnimationTarget());
112             }
113         }, true /* traverseTopToBottom */);
114     }
115 
116     /**
117      * Creates and starts remote animation for the navigation bar windows.
118      *
119      * @return RemoteAnimationTarget[] targets for all the visible non app windows
120      */
startNavigationBarWindowAnimation(DisplayContent displayContent, long durationHint, long statusBarTransitionDelay, ArrayList<RemoteAnimationTarget> targets, ArrayList<NonAppWindowAnimationAdapter> adaptersOut)121     private static void startNavigationBarWindowAnimation(DisplayContent displayContent,
122             long durationHint, long statusBarTransitionDelay,
123             ArrayList<RemoteAnimationTarget> targets,
124             ArrayList<NonAppWindowAnimationAdapter> adaptersOut) {
125         final WindowState navWindow = displayContent.getDisplayPolicy().getNavigationBar();
126         final NonAppWindowAnimationAdapter nonAppAdapter = new NonAppWindowAnimationAdapter(
127                 navWindow.mToken, durationHint, statusBarTransitionDelay);
128         adaptersOut.add(nonAppAdapter);
129         navWindow.mToken.startAnimation(navWindow.mToken.getPendingTransaction(),
130                 nonAppAdapter, false /* hidden */, ANIMATION_TYPE_WINDOW_ANIMATION);
131         targets.add(nonAppAdapter.createRemoteAnimationTarget());
132     }
133 
134     /**
135      * Create a remote animation target for this animation adapter.
136      */
createRemoteAnimationTarget()137     RemoteAnimationTarget createRemoteAnimationTarget() {
138         mTarget = new RemoteAnimationTarget(-1, -1, getLeash(), false,
139                 new Rect(), null, mWindowContainer.getPrefixOrderIndex(),
140                 mWindowContainer.getLastSurfacePosition(), mWindowContainer.getBounds(), null,
141                 mWindowContainer.getWindowConfiguration(), true, null, null, null,
142                 mWindowContainer.getWindowType());
143         return mTarget;
144     }
145 
146     @Override
startAnimation(SurfaceControl animationLeash, SurfaceControl.Transaction t, int type, SurfaceAnimator.OnAnimationFinishedCallback finishCallback)147     public void startAnimation(SurfaceControl animationLeash, SurfaceControl.Transaction t,
148             int type, SurfaceAnimator.OnAnimationFinishedCallback finishCallback) {
149         ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "startAnimation");
150         mCapturedLeash = animationLeash;
151         mCapturedLeashFinishCallback = finishCallback;
152         mLastAnimationType = type;
153     }
154 
155     /**
156      * @return the callback to call to clean up when the animation has finished.
157      */
getLeashFinishedCallback()158     SurfaceAnimator.OnAnimationFinishedCallback getLeashFinishedCallback() {
159         return mCapturedLeashFinishCallback;
160     }
161 
162     /**
163      * @return the type of animation.
164      */
165     @SurfaceAnimator.AnimationType
getLastAnimationType()166     int getLastAnimationType() {
167         return mLastAnimationType;
168     }
169 
getWindowContainer()170     WindowContainer getWindowContainer() {
171         return mWindowContainer;
172     }
173 
174     @Override
getDurationHint()175     public long getDurationHint() {
176         return mDurationHint;
177     }
178 
179     @Override
getStatusBarTransitionsStartTime()180     public long getStatusBarTransitionsStartTime() {
181         return SystemClock.uptimeMillis() + mStatusBarTransitionDelay;
182     }
183 
184     /**
185      * @return the leash for this animation (only valid after the non app window surface animation
186      * has started).
187      */
getLeash()188     SurfaceControl getLeash() {
189         return mCapturedLeash;
190     }
191 
192     @Override
onAnimationCancelled(SurfaceControl animationLeash)193     public void onAnimationCancelled(SurfaceControl animationLeash) {
194         ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "onAnimationCancelled");
195     }
196 
197     @Override
dump(PrintWriter pw, String prefix)198     public void dump(PrintWriter pw, String prefix) {
199         pw.print(prefix);
200         pw.print("windowContainer=");
201         pw.println(mWindowContainer);
202         if (mTarget != null) {
203             pw.print(prefix);
204             pw.println("Target:");
205             mTarget.dump(pw, prefix + "  ");
206         } else {
207             pw.print(prefix);
208             pw.println("Target: null");
209         }
210     }
211 
212     @Override
dumpDebug(ProtoOutputStream proto)213     public void dumpDebug(ProtoOutputStream proto) {
214         final long token = proto.start(REMOTE);
215         if (mTarget != null) {
216             mTarget.dumpDebug(proto, TARGET);
217         }
218         proto.end(token);
219     }
220 }
221