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 package com.android.launcher3.taskbar;
17 
18 import android.view.View;
19 import android.view.WindowManager;
20 
21 import com.android.quickstep.util.LauncherViewsMoveFromCenterTranslationApplier;
22 import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator;
23 import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener;
24 import com.android.systemui.unfold.updates.RotationChangeProvider;
25 import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider;
26 import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider;
27 
28 import java.io.PrintWriter;
29 
30 /**
31  * Controls animation of taskbar icons when unfolding foldable devices
32  */
33 public class TaskbarUnfoldAnimationController implements
34         TaskbarControllers.LoggableTaskbarController {
35 
36     private static final float MAX_WIDTH_INSET_FRACTION = 0.035f;
37 
38     private final ScopedUnfoldTransitionProgressProvider mScopedUnfoldTransitionProgressProvider;
39     private final NaturalRotationUnfoldProgressProvider mNaturalUnfoldTransitionProgressProvider;
40     private final UnfoldMoveFromCenterAnimator mMoveFromCenterAnimator;
41     private final TransitionListener mTransitionListener = new TransitionListener();
42     private TaskbarViewController mTaskbarViewController;
43     private TaskbarDragLayerController mTaskbarDragLayerController;
44 
TaskbarUnfoldAnimationController(BaseTaskbarContext context, ScopedUnfoldTransitionProgressProvider source, WindowManager windowManager, RotationChangeProvider rotationChangeProvider)45     public TaskbarUnfoldAnimationController(BaseTaskbarContext context,
46             ScopedUnfoldTransitionProgressProvider source,
47             WindowManager windowManager,
48             RotationChangeProvider rotationChangeProvider) {
49         mScopedUnfoldTransitionProgressProvider = source;
50         mNaturalUnfoldTransitionProgressProvider =
51                 new NaturalRotationUnfoldProgressProvider(context,
52                         rotationChangeProvider,
53                         source);
54         mMoveFromCenterAnimator = new UnfoldMoveFromCenterAnimator(windowManager,
55                 new LauncherViewsMoveFromCenterTranslationApplier());
56     }
57 
58     /**
59      * Initializes the controller
60      *
61      * @param taskbarControllers references to all other taskbar controllers
62      */
init(TaskbarControllers taskbarControllers)63     public void init(TaskbarControllers taskbarControllers) {
64         mNaturalUnfoldTransitionProgressProvider.init();
65         mTaskbarViewController = taskbarControllers.taskbarViewController;
66         mTaskbarViewController.addOneTimePreDrawListener(() ->
67                 mScopedUnfoldTransitionProgressProvider.setReadyToHandleTransition(true));
68         mNaturalUnfoldTransitionProgressProvider.addCallback(mTransitionListener);
69         mTaskbarDragLayerController = taskbarControllers.taskbarDragLayerController;
70     }
71 
72     /**
73      * Destroys the controller
74      */
onDestroy()75     public void onDestroy() {
76         mScopedUnfoldTransitionProgressProvider.setReadyToHandleTransition(false);
77         mNaturalUnfoldTransitionProgressProvider.removeCallback(mTransitionListener);
78         mNaturalUnfoldTransitionProgressProvider.destroy();
79         mTaskbarViewController = null;
80     }
81 
82     @Override
dumpLogs(String prefix, PrintWriter pw)83     public void dumpLogs(String prefix, PrintWriter pw) {
84         pw.println(prefix + "TaskbarUnfoldAnimationController:");
85     }
86 
87     private class TransitionListener implements TransitionProgressListener {
88 
89         @Override
onTransitionStarted()90         public void onTransitionStarted() {
91             mMoveFromCenterAnimator.updateDisplayProperties();
92             View[] icons = mTaskbarViewController.getIconViews();
93             for (View icon : icons) {
94                 // TODO(b/193794563) we should re-register views if they are re-bound/re-inflated
95                 //                   during the animation
96                 mMoveFromCenterAnimator.registerViewForAnimation(icon);
97             }
98 
99             mMoveFromCenterAnimator.onTransitionStarted();
100         }
101 
102         @Override
onTransitionFinished()103         public void onTransitionFinished() {
104             mMoveFromCenterAnimator.onTransitionFinished();
105             mMoveFromCenterAnimator.clearRegisteredViews();
106             mTaskbarDragLayerController.setBackgroundHorizontalInsets(0f);
107         }
108 
109         @Override
onTransitionProgress(float progress)110         public void onTransitionProgress(float progress) {
111             mMoveFromCenterAnimator.onTransitionProgress(progress);
112             float insetPercentage = (1 - progress) * MAX_WIDTH_INSET_FRACTION;
113             mTaskbarDragLayerController.setBackgroundHorizontalInsets(insetPercentage);
114         }
115     }
116 }
117