• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2016, 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.car.hvac.controllers;
17 
18 import android.animation.Animator;
19 import android.animation.AnimatorSet;
20 import android.animation.ObjectAnimator;
21 import android.animation.ValueAnimator;
22 import android.content.Context;
23 import android.content.res.Resources;
24 import android.graphics.drawable.Drawable;
25 import android.support.annotation.IntDef;
26 import android.view.MotionEvent;
27 import android.view.View;
28 import android.view.ViewGroup;
29 import android.view.WindowManager;
30 import android.widget.ImageView;
31 import com.android.car.hvac.HvacController;
32 import com.android.car.hvac.R;
33 import com.android.car.hvac.ui.FanDirectionButtons;
34 import com.android.car.hvac.ui.FanSpeedBar;
35 import com.android.car.hvac.ui.HvacPanelRow;
36 import com.android.car.hvac.ui.SeatWarmerButton;
37 import com.android.car.hvac.ui.TemperatureBarOverlay;
38 import com.android.car.hvac.ui.ToggleButton;
39 
40 import java.util.ArrayList;
41 import java.util.List;
42 
43 /**
44  * A state machine to control transition from various HVAC UI layouts.
45  */
46 public class HvacPanelController {
47     private static final int PANEL_ANIMATION_TIME_MS = 200;
48     private static final int PANEL_COLLAPSE_ANIMATION_TIME_MS = 500;
49 
50     private static final int PANEL_ANIMATION_DELAY_MS = 100;
51     private static final int PANEL_ANIMATION_LONG_DELAY_MS = 3 * PANEL_ANIMATION_DELAY_MS;
52 
53     private static final float DISABLED_BUTTON_ALPHA = 0.20f;
54     private static final float ENABLED_BUTTON_ALPHA = 1.0f;
55 
56     private static final int STATE_COLLAPSED = 0;
57     private static final int STATE_COLLAPSED_DIMMED = 1;
58     private static final int STATE_FULL_EXPANDED = 2;
59 
60     @IntDef({STATE_COLLAPSED,
61             STATE_COLLAPSED_DIMMED,
62             STATE_FULL_EXPANDED})
63     private @interface HvacPanelState {}
64 
65     private @HvacPanelState int mCurrentState;
66 
67     private int mPanelCollapsedHeight;
68     private int mPanelFullExpandedHeight;
69 
70     private View mPanel;
71     private View mContainer;
72 
73     private TemperatureBarOverlay mDriverTemperature;
74     private TemperatureBarOverlay mPassengerTemperature;
75 
76     private ViewGroup mDriverTemperatureTouchOverlay;
77     private ViewGroup mPassengerTemperatureTouchOverlay;
78 
79     private SeatWarmerButton mDriverSeatWarmer;
80     private SeatWarmerButton mPassengerSeatWarmer;
81 
82     private ToggleButton mAcButton;
83     private ToggleButton mRecycleAirButton;
84 
85     private ToggleButton mFrontDefrosterButton;
86     private ToggleButton mRearDefrosterButton;
87 
88     private Drawable mAutoOnDrawable;
89     private Drawable mAutoOffDrawable;
90 
91     private ImageView mAutoButton;
92 
93     private HvacPanelRow mPanelTopRow;
94     private HvacPanelRow mPanelBottomRow;
95 
96     private FanSpeedBar mFanSpeedBar;
97     private FanDirectionButtons mFanDirectionButtons;
98 
99     private float mTopPanelMaxAlpha = 1.0f;
100 
101     private WindowManager mWindowManager;
102 
103     private HvacPanelStateTransition mTransition;
104 
105     private View mHvacFanControlBackground;
106 
107     private HvacController mHvacController;
108     private FanSpeedBarController mFanSpeedBarController;
109     private FanDirectionButtonsController mFanDirectionButtonsController;
110     private TemperatureController mTemperatureController;
111     private SeatWarmerController mSeatWarmerController;
112 
113     private boolean mInAnimation;
114     private boolean mHvacIsOn;
115 
116     // TODO: read from shared pref
117     private boolean mAutoMode;
118 
HvacPanelController(Context context, View container, WindowManager windowManager, TemperatureBarOverlay driverTemperature, TemperatureBarOverlay passengerTemperature, ViewGroup driverTemperatureBarTouchOverlay, ViewGroup passengerTemperatureBarTouchOverlay)119     public HvacPanelController(Context context, View container,
120             WindowManager windowManager, TemperatureBarOverlay driverTemperature,
121             TemperatureBarOverlay passengerTemperature, ViewGroup driverTemperatureBarTouchOverlay,
122             ViewGroup passengerTemperatureBarTouchOverlay) {
123 
124         mCurrentState = STATE_COLLAPSED;
125         mWindowManager = windowManager;
126 
127         Resources res = context.getResources();
128         mPanelCollapsedHeight = res.getDimensionPixelSize(R.dimen.car_hvac_panel_collapsed_height);
129         mPanelFullExpandedHeight
130                 = res.getDimensionPixelSize(R.dimen.car_hvac_panel_full_expanded_height);
131 
132         mAutoOffDrawable = res.getDrawable(R.drawable.ic_auto_off);
133         mAutoOnDrawable = res.getDrawable(R.drawable.ic_auto_on);
134 
135         mDriverTemperature = driverTemperature;
136         mDriverTemperature.setBarOnClickListener(mPanelClickListener);
137 
138         mPassengerTemperature = passengerTemperature;
139         mPassengerTemperature.setBarOnClickListener(mPanelClickListener);
140 
141         mDriverTemperature.setCloseButtonOnClickListener(mOpenCloseToggleListener);
142         mPassengerTemperature.setCloseButtonOnClickListener(mOpenCloseToggleListener);
143 
144         // Initially the hvac panel is collapsed, disable touches on the overlay container.
145         disableTouchOnOverlay(mDriverTemperature);
146         disableTouchOnOverlay(mPassengerTemperature);
147 
148         mDriverTemperatureTouchOverlay = driverTemperatureBarTouchOverlay;
149         mPassengerTemperatureTouchOverlay = passengerTemperatureBarTouchOverlay;
150 
151         mDriverTemperatureTouchOverlay.setOnClickListener(mOpenCloseToggleListener);
152         mPassengerTemperatureTouchOverlay.setOnClickListener(mOpenCloseToggleListener);
153 
154         mContainer = container;
155         mContainer.setVisibility(View.INVISIBLE);
156         mContainer.setOnClickListener(mOpenCloseToggleListener);
157         mPanel = mContainer.findViewById(R.id.hvac_center_panel);
158 
159         mHvacFanControlBackground = mPanel.findViewById(R.id.fan_control_bg);
160         mPanel.setOnClickListener(mPanelClickListener);
161 
162         // Set up top row buttons
163         mPanelTopRow = (HvacPanelRow) mContainer.findViewById(R.id.top_row);
164 
165         mAcButton = (ToggleButton) mPanelTopRow.findViewById(R.id.ac_button);
166         mAcButton.setToggleIcons(res.getDrawable(R.drawable.ic_ac_on),
167                 res.getDrawable(R.drawable.ic_ac_off));
168 
169         mRecycleAirButton = (ToggleButton) mPanelTopRow.findViewById(R.id.recycle_air_button);
170 
171         mRecycleAirButton.setToggleIcons(res.getDrawable(R.drawable.ic_recycle_air_on),
172                 res.getDrawable(R.drawable.ic_recycle_air_off));
173 
174         // Setup bottom row buttons
175         mPanelBottomRow = (HvacPanelRow) mContainer.findViewById(R.id.bottom_row);
176 
177         mAutoButton = (ImageView) mContainer.findViewById(R.id.auto_button);
178         mAutoButton.setOnClickListener(mAutoButtonClickListener);
179 
180         mFrontDefrosterButton = (ToggleButton) mPanelBottomRow.findViewById(R.id.front_defroster);
181         mRearDefrosterButton = (ToggleButton) mPanelBottomRow.findViewById(R.id.rear_defroster);
182 
183         mFrontDefrosterButton.setToggleIcons(res.getDrawable(R.drawable.ic_front_defroster_on),
184                 res.getDrawable(R.drawable.ic_front_defroster_off));
185 
186         mRearDefrosterButton.setToggleIcons(res.getDrawable(R.drawable.ic_rear_defroster_on),
187                 res.getDrawable(R.drawable.ic_rear_defroster_off));
188 
189         mFanSpeedBar = (FanSpeedBar) mContainer.findViewById(R.id.fan_speed_bar);
190         mFanDirectionButtons = (FanDirectionButtons) mContainer.findViewById(R.id.fan_direction_buttons);
191 
192         mDriverSeatWarmer = (SeatWarmerButton) mContainer.findViewById(R.id.left_seat_heater);
193         mPassengerSeatWarmer = (SeatWarmerButton) mContainer.findViewById(R.id.right_seat_heater);
194     }
195 
updateHvacController(HvacController controller)196     public void updateHvacController(HvacController controller) {
197         //TODO: handle disconnected HvacController.
198         mHvacController = controller;
199 
200         mFanSpeedBarController = new FanSpeedBarController(mFanSpeedBar, mHvacController);
201         mFanDirectionButtonsController
202                 = new FanDirectionButtonsController(mFanDirectionButtons, mHvacController);
203         mTemperatureController = new TemperatureController(mPassengerTemperature,
204                 mDriverTemperature, mHvacController);
205         mSeatWarmerController = new SeatWarmerController(mPassengerSeatWarmer,
206                 mDriverSeatWarmer, mHvacController);
207 
208         // Toggle buttons do not need additional logic to map between hardware
209         // and UI settings. Simply use a ToggleListener to handle clicks.
210         mAcButton.setIsOn(mHvacController.getAcState());
211         mAcButton.setToggleListener(new ToggleButton.ToggleListener() {
212             @Override
213             public void onToggled(boolean isOn) {
214                 mHvacController.setAcState(isOn);
215             }
216         });
217 
218         mFrontDefrosterButton.setIsOn(mHvacController.getFrontDefrosterState());
219         mFrontDefrosterButton.setToggleListener(new ToggleButton.ToggleListener() {
220             @Override
221             public void onToggled(boolean isOn) {
222                 mHvacController.setFrontDefrosterState(isOn);
223             }
224         });
225 
226         mRearDefrosterButton.setIsOn(mHvacController.getRearDefrosterState());
227         mRearDefrosterButton.setToggleListener(new ToggleButton.ToggleListener() {
228             @Override
229             public void onToggled(boolean isOn) {
230                 mHvacController.setRearDefrosterState(isOn);
231             }
232         });
233 
234         mRecycleAirButton.setIsOn(mHvacController.getAirCirculationState());
235         mRecycleAirButton.setToggleListener(new ToggleButton.ToggleListener() {
236             @Override
237             public void onToggled(boolean isOn) {
238                 mHvacController.setAirCirculation(isOn);
239             }
240         });
241 
242         setAutoMode(mHvacController.getAutoModeState());
243 
244         mHvacController.registerCallback(mToggleButtonCallbacks);
245         mToggleButtonCallbacks.onHvacPowerChange(mHvacController.getHvacPowerState());
246     }
247 
248     private HvacController.Callback mToggleButtonCallbacks
249             = new HvacController.Callback() {
250         @Override
251         public void onAirCirculationChange(boolean isOn) {
252             mRecycleAirButton.setIsOn(isOn);
253         }
254 
255         @Override
256         public void onFrontDefrosterChange(boolean isOn) {
257             mFrontDefrosterButton.setIsOn(isOn);
258         }
259 
260         @Override
261         public void onRearDefrosterChange(boolean isOn) {
262             mRearDefrosterButton.setIsOn(isOn);
263         }
264 
265         @Override
266         public void onAcStateChange(boolean isOn) {
267             mAcButton.setIsOn(isOn);
268         }
269 
270         @Override
271         public void onAutoModeChange(boolean isOn) {
272             mAutoMode = isOn;
273             setAutoMode(mAutoMode);
274         }
275 
276         @Override
277         public void onHvacPowerChange(boolean isOn) {
278             // When the HVAC Power is turned off, collapse the panel and fade the temperature
279             // bars. Also disable expanding the panel until power is back on.
280             mHvacIsOn = isOn;
281             if (!mHvacIsOn && mCurrentState == STATE_FULL_EXPANDED) {
282                 transitionState(STATE_FULL_EXPANDED, STATE_COLLAPSED);
283             }
284 
285             mDriverTemperature.setIsOn(mHvacIsOn);
286             mPassengerTemperature.setIsOn(mHvacIsOn);
287         }
288     };
289 
290     /**
291      * Take the listeners and animators from a {@link AnimatorSet} and merge them to the
292      * input {@link Animator} and {@link android.animation.Animator.AnimatorListener} lists.
293      */
combineAnimationSet(List<Animator> animatorList, List<Animator.AnimatorListener> listenerList, AnimatorSet set)294     private void combineAnimationSet(List<Animator> animatorList,
295             List<Animator.AnimatorListener> listenerList, AnimatorSet set) {
296 
297         ArrayList<Animator> list = set.getChildAnimations();
298         if (list != null) {
299             int size = list.size();
300             for (int i = 0; i < size; i++) {
301                 animatorList.add(list.get(i));
302             }
303         }
304 
305         ArrayList<Animator.AnimatorListener> listeners = set.getListeners();
306         if (listeners != null) {
307             int size = listeners.size();
308             for (int i = 0; i < size; i++) {
309                 listenerList.add(listeners.get(i));
310             }
311         }
312     }
313 
314     /**
315      * Play necessary animations between {@link HvacPanelState} transitions
316      */
transitionState(@vacPanelState int startState, @HvacPanelState int endState)317     private void transitionState(@HvacPanelState int startState, @HvacPanelState int endState) {
318         if (startState == endState || mInAnimation) {
319             return;
320         }
321 
322         List<Animator> animationList = new ArrayList<>();
323         List<Animator.AnimatorListener> listenerList = new ArrayList<>();
324         ValueAnimator heightAnimator = getPanelHeightAnimator(startState, endState);
325         mTransition = new HvacPanelStateTransition(startState, endState);
326         ValueAnimator fanBgAlphaAnimator;
327         switch (endState) {
328             case STATE_COLLAPSED:
329                 // Transition to collapsed state:
330                 // 1. Collapse the temperature bars.
331                 // 2. Collapse the top and bottom panel, staggered with a different delay.
332                 // 3. Decrease height of the hvac center panel, but maintain container height.
333                 // 4. Fade the background of the fan controls seperately to create staggered effect.
334                 animationList.add(heightAnimator);
335                 heightAnimator.setDuration(PANEL_COLLAPSE_ANIMATION_TIME_MS);
336                 fanBgAlphaAnimator
337                         = ObjectAnimator.ofFloat(mHvacFanControlBackground, View.ALPHA, 1, 0)
338                         .setDuration(PANEL_COLLAPSE_ANIMATION_TIME_MS);
339                 fanBgAlphaAnimator.setStartDelay(PANEL_ANIMATION_DELAY_MS);
340                 animationList.add(fanBgAlphaAnimator);
341 
342                 ValueAnimator panelAlphaAnimator
343                         = ObjectAnimator.ofFloat(mContainer, View.ALPHA, 1, 0);
344                 panelAlphaAnimator.setDuration(200);
345                 panelAlphaAnimator.setStartDelay(300);
346 
347                 animationList.add(panelAlphaAnimator);
348 
349                 combineAnimationSet(animationList, listenerList,
350                         mDriverTemperature.getCollapseAnimations());
351                 combineAnimationSet(animationList, listenerList,
352                         mPassengerTemperature.getCollapseAnimations());
353 
354                 combineAnimationSet(animationList, listenerList,
355                         mPanelTopRow.getCollapseAnimation(PANEL_ANIMATION_DELAY_MS,
356                                 mTopPanelMaxAlpha));
357                 combineAnimationSet(animationList, listenerList,
358                         mPanelBottomRow.getCollapseAnimation(PANEL_ANIMATION_DELAY_MS,
359                                 mTopPanelMaxAlpha));
360                 break;
361             case STATE_COLLAPSED_DIMMED:
362                 // Hide the temperature numbers, open arrows and auto state button.
363                 // TODO: determine if this section is still needed.
364                 break;
365             case STATE_FULL_EXPANDED:
366                 // Transition to expaneded state:
367                 // 1. Expand the temperature bars.
368                 // 2. Expand the top and bottom panel, staggered with a different delay.
369                 // 3. Increase height of the hvac center panel, but maintain container height.
370                 // 4. Fade in fan control background in a staggered manner.
371                 fanBgAlphaAnimator
372                         = ObjectAnimator.ofFloat(mHvacFanControlBackground, View.ALPHA, 0, 1)
373                         .setDuration(PANEL_ANIMATION_TIME_MS);
374                 fanBgAlphaAnimator.setStartDelay(PANEL_ANIMATION_DELAY_MS);
375                 animationList.add(fanBgAlphaAnimator);
376 
377                 animationList.add(heightAnimator);
378                 combineAnimationSet(animationList, listenerList,
379                         mDriverTemperature.getExpandAnimatons());
380                 combineAnimationSet(animationList, listenerList,
381                         mPassengerTemperature.getExpandAnimatons());
382 
383                 // During expansion, the bottom panel animation should be delayed
384                 combineAnimationSet(animationList, listenerList,
385                         mPanelTopRow.getExpandAnimation(PANEL_ANIMATION_DELAY_MS,
386                                 mTopPanelMaxAlpha));
387                 combineAnimationSet(animationList, listenerList,
388                         mPanelBottomRow.getExpandAnimation(PANEL_ANIMATION_LONG_DELAY_MS, 1f));
389                 break;
390             default:
391         }
392 
393         // If there are animations for the state change, play them all together and ensure
394         // the animation listeners are attached.
395         if (animationList.size() > 0) {
396             AnimatorSet animatorSet = new AnimatorSet();
397             animatorSet.playTogether(animationList);
398             for (Animator.AnimatorListener listener : listenerList) {
399                 animatorSet.addListener(listener);
400             }
401             animatorSet.addListener(mAnimatorListener);
402             animatorSet.start();
403         }
404     }
405 
406     private AnimatorSet.AnimatorListener mAnimatorListener = new AnimatorSet.AnimatorListener() {
407         @Override
408         public void onAnimationStart(Animator animation) {
409             mTransition.onTransitionStart();
410         }
411 
412         @Override
413         public void onAnimationEnd(Animator animation) {
414             mTransition.onTransitionComplete();
415         }
416 
417         @Override
418         public void onAnimationCancel(Animator animation) {}
419 
420         @Override
421         public void onAnimationRepeat(Animator animation) {}
422     };
423 
getPanelHeightAnimator(@vacPanelState int startState, @HvacPanelState int endState)424     private ValueAnimator getPanelHeightAnimator(@HvacPanelState int startState,
425             @HvacPanelState int endState) {
426         int startHeight = getStateHeight(startState);
427         int endHeight = getStateHeight(endState);
428         if (startHeight == endHeight) {
429             return null;
430         }
431 
432         ValueAnimator heightAnimator = new ValueAnimator().ofInt(startHeight, endHeight)
433                 .setDuration(PANEL_ANIMATION_TIME_MS);
434         heightAnimator.addUpdateListener(mHeightUpdateListener);
435         return heightAnimator;
436     }
437 
getStateHeight(@vacPanelState int state)438     private int getStateHeight(@HvacPanelState int state) {
439         switch (state) {
440             case STATE_COLLAPSED:
441             case STATE_COLLAPSED_DIMMED:
442                 return mPanelCollapsedHeight;
443             case STATE_FULL_EXPANDED:
444                 return mPanelFullExpandedHeight;
445             default:
446                 throw new IllegalArgumentException("No height mapped to HVAC State: " + state);
447         }
448     }
449 
setAutoMode(boolean isOn)450     private void setAutoMode(boolean isOn) {
451         if (isOn) {
452             mPanelTopRow.setOnTouchListener(new View.OnTouchListener() {
453                 @Override
454                 public boolean onTouch(View v, MotionEvent event) {
455                     return true;
456                 }
457             });
458             mAutoMode = true;
459             mPanelTopRow.disablePanel(true);
460             mTopPanelMaxAlpha = DISABLED_BUTTON_ALPHA;
461             mAutoButton.setImageDrawable(mAutoOnDrawable);
462         } else {
463             mPanelTopRow.disablePanel(false);
464             mTopPanelMaxAlpha = ENABLED_BUTTON_ALPHA;
465             mAutoButton.setImageDrawable(mAutoOffDrawable);
466         }
467         mHvacFanControlBackground.setAlpha(mTopPanelMaxAlpha);
468         mPanelTopRow.setAlpha(mTopPanelMaxAlpha);
469     }
470 
471     private View.OnClickListener mPanelClickListener = new View.OnClickListener() {
472         @Override
473         public void onClick(View v) {
474             if (!mHvacIsOn) {
475                 return;
476             }
477             switch (mCurrentState) {
478                 case STATE_COLLAPSED:
479                     transitionState(STATE_COLLAPSED, STATE_FULL_EXPANDED);
480                     break;
481                 case STATE_COLLAPSED_DIMMED:
482                     transitionState(mCurrentState, STATE_COLLAPSED);
483                     break;
484                 default:
485             }
486         }
487     };
488 
489     private View.OnClickListener mAutoButtonClickListener = new View.OnClickListener() {
490         @Override
491         public void onClick(View v) {
492             if (mAutoMode) {
493                 mAutoMode = false;
494             } else {
495                 mAutoMode = true;
496             }
497             mHvacController.setAutoMode(mAutoMode);
498             setAutoMode(mAutoMode);
499         }
500     };
501 
502     private View.OnClickListener mOpenCloseToggleListener = new View.OnClickListener() {
503         @Override
504         public void onClick(View v) {
505             if (!mHvacIsOn) {
506                 return;
507             }
508             if (mCurrentState == STATE_FULL_EXPANDED) {
509                 transitionState(mCurrentState, STATE_COLLAPSED);
510             } else if (mCurrentState == STATE_COLLAPSED) {
511                 transitionState(mCurrentState, STATE_FULL_EXPANDED);
512             }
513         }
514     };
515 
516     private ValueAnimator.AnimatorUpdateListener mHeightUpdateListener
517             = new ValueAnimator.AnimatorUpdateListener() {
518         @Override
519         public void onAnimationUpdate(ValueAnimator animation) {
520             int height = (Integer) animation.getAnimatedValue();
521             int currentHeight = mPanel.getLayoutParams().height;
522             mPanel.getLayoutParams().height = height;
523             mPanel.setTop(mPanel.getTop() + height - currentHeight);
524             mPanel.requestLayout();
525         }
526     };
527 
528     /**
529      * Handles the necessary setup/clean up before and after a state transition.
530      */
531     private class HvacPanelStateTransition {
532         private @HvacPanelState int mEndState;
533         private @HvacPanelState int mStartState;
534 
HvacPanelStateTransition(@vacPanelState int startState, @HvacPanelState int endState)535         public HvacPanelStateTransition(@HvacPanelState int startState,
536                 @HvacPanelState int endState) {
537             mStartState = startState;
538             mEndState = endState;
539         }
540 
onTransitionStart()541         public void onTransitionStart() {
542             mInAnimation = true;
543             if (mEndState == STATE_FULL_EXPANDED) {
544                 mContainer.setAlpha(1);
545                 mContainer.setVisibility(View.VISIBLE);
546             } else if (mStartState == STATE_FULL_EXPANDED) {
547                 // Finished transitioning out of the fully expanded panel. Make the HVAC container
548                 // and temperature bars not touchable so clicks on the screen bar are not intercepted.
549                 disableTouchOnOverlay(mContainer);
550                 disableTouchOnOverlay(mDriverTemperature);
551                 disableTouchOnOverlay(mPassengerTemperature);
552             }
553         }
554 
onTransitionComplete()555         public void onTransitionComplete() {
556             if (mStartState == STATE_FULL_EXPANDED) {
557                 mContainer.setVisibility(View.INVISIBLE);
558 
559                 enableTouchOnOverlay(mDriverTemperatureTouchOverlay);
560                 enableTouchOnOverlay(mPassengerTemperatureTouchOverlay);
561             } else if (mEndState == STATE_FULL_EXPANDED) {
562                 // Finished transitioning into the fully expanded HVAC panel, make the
563                 // container and temperature bars touchable since it covers the screen.
564                 enableTouchOnOverlay(mContainer);
565                 enableTouchOnOverlay(mDriverTemperature);
566                 enableTouchOnOverlay(mPassengerTemperature);
567 
568                 disableTouchOnOverlay(mDriverTemperatureTouchOverlay);
569                 disableTouchOnOverlay(mPassengerTemperatureTouchOverlay);
570             }
571 
572             // set new states
573             mCurrentState = mEndState;
574             mInAnimation = false;
575         }
576     }
577 
disableTouchOnOverlay(View view)578     private void disableTouchOnOverlay(View view) {
579         WindowManager.LayoutParams params
580                 = (WindowManager.LayoutParams) view.getLayoutParams();
581         params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
582                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
583                 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
584                 & ~WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
585         mWindowManager.updateViewLayout(view, params);
586     }
587 
enableTouchOnOverlay(View view)588     private void enableTouchOnOverlay(View view) {
589         WindowManager.LayoutParams params
590                 = (WindowManager.LayoutParams) view.getLayoutParams();
591         params.flags =
592                 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
593                         | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
594                         & ~WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
595         mWindowManager.updateViewLayout(view, params);
596     }
597 
598 }
599