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.systemui.car.hvac;
18 
19 import android.animation.Animator;
20 import android.animation.AnimatorInflater;
21 import android.animation.AnimatorListenerAdapter;
22 import android.animation.ObjectAnimator;
23 import android.app.UiModeManager;
24 import android.content.Context;
25 import android.content.res.Resources;
26 import android.os.Handler;
27 import android.view.MotionEvent;
28 import android.view.View;
29 
30 import com.android.systemui.R;
31 import com.android.systemui.car.CarDeviceProvisionedController;
32 import com.android.systemui.car.window.OverlayViewGlobalStateController;
33 import com.android.systemui.dagger.SysUISingleton;
34 import com.android.systemui.dagger.qualifiers.Main;
35 import com.android.systemui.statusbar.policy.ConfigurationController;
36 import com.android.wm.shell.animation.FlingAnimationUtils;
37 
38 import javax.inject.Inject;
39 
40 /**
41  * An extension of {@link HvacPanelOverlayViewController} which auto dismisses the panel if there
42  * is no activity for some configured amount of time.
43  */
44 @SysUISingleton
45 public class AutoDismissHvacPanelOverlayViewController extends HvacPanelOverlayViewController {
46 
47     private final Resources mResources;
48     private final Handler mHandler;
49     private final Context mContext;
50 
51     private int mAutoDismissDurationMs;
52     private ObjectAnimator mOpenAnimator;
53     private ObjectAnimator mCloseAnimator;
54 
55     private final Runnable mAutoDismiss = () -> {
56         if (isPanelExpanded()) {
57             toggle();
58         }
59     };
60 
61     @Inject
AutoDismissHvacPanelOverlayViewController(Context context, @Main Resources resources, HvacController hvacController, OverlayViewGlobalStateController overlayViewGlobalStateController, FlingAnimationUtils.Builder flingAnimationUtilsBuilder, CarDeviceProvisionedController carDeviceProvisionedController, @Main Handler handler, ConfigurationController configurationController, UiModeManager uiModeManager)62     public AutoDismissHvacPanelOverlayViewController(Context context,
63             @Main Resources resources,
64             HvacController hvacController,
65             OverlayViewGlobalStateController overlayViewGlobalStateController,
66             FlingAnimationUtils.Builder flingAnimationUtilsBuilder,
67             CarDeviceProvisionedController carDeviceProvisionedController,
68             @Main Handler handler,
69             ConfigurationController configurationController,
70             UiModeManager uiModeManager) {
71         super(context, resources, hvacController, overlayViewGlobalStateController,
72                 flingAnimationUtilsBuilder, carDeviceProvisionedController, configurationController,
73                 uiModeManager);
74         mResources = resources;
75         mHandler = handler;
76         mContext = context;
77     }
78 
79     @Override
onTouchEvent(View view, MotionEvent event)80     protected void onTouchEvent(View view, MotionEvent event) {
81         int hvacHeight = mResources.getDimensionPixelSize(R.dimen.hvac_panel_full_expanded_height);
82         if (isPanelExpanded() && (event.getY() < (view.getHeight() - hvacHeight))
83                 && (event.getAction() == MotionEvent.ACTION_UP)) {
84             mHandler.post(mAutoDismiss);
85         }
86     }
87 
88     @Override
onFinishInflate()89     protected void onFinishInflate() {
90         super.onFinishInflate();
91 
92         mAutoDismissDurationMs = mResources.getInteger(R.integer.config_hvacAutoDismissDurationMs);
93 
94         mOpenAnimator = (ObjectAnimator) AnimatorInflater.loadAnimator(mContext,
95                 R.anim.hvac_open_anim);
96         mOpenAnimator.setTarget(getLayout());
97         mCloseAnimator = (ObjectAnimator) AnimatorInflater.loadAnimator(mContext,
98                 R.anim.hvac_close_anim);
99         mCloseAnimator.setTarget(getLayout());
100     }
101 
102     @Override
onAnimateExpandPanel()103     protected void onAnimateExpandPanel() {
104         super.onAnimateExpandPanel();
105 
106         mHandler.postDelayed(mAutoDismiss, mAutoDismissDurationMs);
107     }
108 
109     @Override
onAnimateCollapsePanel()110     protected void onAnimateCollapsePanel() {
111         super.onAnimateCollapsePanel();
112 
113         mHandler.removeCallbacks(mAutoDismiss);
114     }
115 
116     @Override
animate(float from, float to, float velocity, boolean isClosing)117     protected void animate(float from, float to, float velocity, boolean isClosing) {
118         if (isAnimating()) {
119             return;
120         }
121         mIsAnimating = true;
122         setIsTracking(true);
123 
124         ObjectAnimator animator = isClosing ? mCloseAnimator : mOpenAnimator;
125         animator.setFloatValues(from, to);
126         animator.removeAllListeners();
127         animator.addListener(new AnimatorListenerAdapter() {
128             @Override
129             public void onAnimationEnd(Animator animation) {
130                 super.onAnimationEnd(animation);
131                 mIsAnimating = false;
132                 setIsTracking(false);
133                 mOpeningVelocity = DEFAULT_FLING_VELOCITY;
134                 mClosingVelocity = DEFAULT_FLING_VELOCITY;
135                 if (isClosing) {
136                     resetPanelVisibility();
137                 } else {
138                     onExpandAnimationEnd();
139                     setPanelExpanded(true);
140                     setViewClipBounds((int) to);
141                 }
142             }
143         });
144         animator.start();
145     }
146 
147     @Override
setUpHandleBar()148     protected void setUpHandleBar() {
149         // No-op
150     }
151 }
152