1 /*
2  * Copyright (C) 2020 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.allapps;
17 
18 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TURN_OFF_WORK_APPS_TAP;
19 
20 import android.content.Context;
21 import android.graphics.Insets;
22 import android.graphics.Rect;
23 import android.util.AttributeSet;
24 import android.view.View;
25 import android.view.ViewGroup;
26 import android.view.WindowInsets;
27 import android.widget.Button;
28 
29 import com.android.launcher3.BaseDraggingActivity;
30 import com.android.launcher3.DeviceProfile;
31 import com.android.launcher3.Insettable;
32 import com.android.launcher3.Launcher;
33 import com.android.launcher3.Utilities;
34 import com.android.launcher3.anim.KeyboardInsetAnimationCallback;
35 import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip;
36 
37 /**
38  * Work profile toggle switch shown at the bottom of AllApps work tab
39  */
40 public class WorkModeSwitch extends Button implements Insettable, View.OnClickListener,
41         KeyboardInsetAnimationCallback.KeyboardInsetListener,
42         PersonalWorkSlidingTabStrip.OnActivePageChangedListener {
43 
44     private static final int FLAG_FADE_ONGOING = 1 << 1;
45     private static final int FLAG_TRANSLATION_ONGOING = 1 << 2;
46     private static final int FLAG_PROFILE_TOGGLE_ONGOING = 1 << 3;
47 
48     private final Rect mInsets = new Rect();
49     private int mFlags;
50     private boolean mWorkEnabled;
51     private boolean mOnWorkTab;
52 
53 
WorkModeSwitch(Context context)54     public WorkModeSwitch(Context context) {
55         this(context, null, 0);
56     }
57 
WorkModeSwitch(Context context, AttributeSet attrs)58     public WorkModeSwitch(Context context, AttributeSet attrs) {
59         this(context, attrs, 0);
60     }
61 
WorkModeSwitch(Context context, AttributeSet attrs, int defStyleAttr)62     public WorkModeSwitch(Context context, AttributeSet attrs, int defStyleAttr) {
63         super(context, attrs, defStyleAttr);
64     }
65 
66     @Override
onFinishInflate()67     protected void onFinishInflate() {
68         super.onFinishInflate();
69         setSelected(true);
70         setOnClickListener(this);
71         if (Utilities.ATLEAST_R) {
72             KeyboardInsetAnimationCallback keyboardInsetAnimationCallback =
73                     new KeyboardInsetAnimationCallback(this);
74             setWindowInsetsAnimationCallback(keyboardInsetAnimationCallback);
75         }
76         DeviceProfile grid = BaseDraggingActivity.fromContext(getContext()).getDeviceProfile();
77         setInsets(grid.getInsets());
78     }
79 
80     @Override
setInsets(Rect insets)81     public void setInsets(Rect insets) {
82         int bottomInset = insets.bottom - mInsets.bottom;
83         mInsets.set(insets);
84         ViewGroup.MarginLayoutParams marginLayoutParams =
85                 (ViewGroup.MarginLayoutParams) getLayoutParams();
86         if (marginLayoutParams != null) {
87             marginLayoutParams.bottomMargin = bottomInset + marginLayoutParams.bottomMargin;
88         }
89     }
90 
91 
92     @Override
onActivePageChanged(int page)93     public void onActivePageChanged(int page) {
94         mOnWorkTab = page == AllAppsContainerView.AdapterHolder.WORK;
95         updateVisibility();
96     }
97 
98     @Override
onClick(View view)99     public void onClick(View view) {
100         if (Utilities.ATLEAST_P && isEnabled()) {
101             setFlag(FLAG_PROFILE_TOGGLE_ONGOING);
102             Launcher launcher = Launcher.getLauncher(getContext());
103             launcher.getStatsLogManager().logger().log(LAUNCHER_TURN_OFF_WORK_APPS_TAP);
104             launcher.getAppsView().getWorkManager().setWorkProfileEnabled(false);
105         }
106     }
107 
108     @Override
isEnabled()109     public boolean isEnabled() {
110         return super.isEnabled() && getVisibility() == VISIBLE && mFlags == 0;
111     }
112 
113     /**
114      * Sets the enabled or disabled state of the button
115      */
updateCurrentState(boolean isEnabled)116     public void updateCurrentState(boolean isEnabled) {
117         removeFlag(FLAG_PROFILE_TOGGLE_ONGOING);
118         if (mWorkEnabled != isEnabled) {
119             mWorkEnabled = isEnabled;
120             updateVisibility();
121         }
122     }
123 
124 
updateVisibility()125     private void updateVisibility() {
126         clearAnimation();
127         if (mWorkEnabled && mOnWorkTab) {
128             setFlag(FLAG_FADE_ONGOING);
129             setVisibility(VISIBLE);
130             animate().alpha(1).withEndAction(() -> removeFlag(FLAG_FADE_ONGOING)).start();
131         } else if (getVisibility() != GONE) {
132             setFlag(FLAG_FADE_ONGOING);
133             animate().alpha(0).withEndAction(() -> {
134                 removeFlag(FLAG_FADE_ONGOING);
135                 this.setVisibility(GONE);
136             }).start();
137         }
138     }
139 
140     @Override
onApplyWindowInsets(WindowInsets insets)141     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
142         if (Utilities.ATLEAST_R && isEnabled()) {
143             setTranslationY(0);
144             if (insets.isVisible(WindowInsets.Type.ime())) {
145                 Insets keyboardInsets = insets.getInsets(WindowInsets.Type.ime());
146                 setTranslationY(mInsets.bottom - keyboardInsets.bottom);
147             }
148         }
149         return insets;
150     }
151 
152     @Override
onTranslationStart()153     public void onTranslationStart() {
154         setFlag(FLAG_TRANSLATION_ONGOING);
155     }
156 
157     @Override
onTranslationEnd()158     public void onTranslationEnd() {
159         removeFlag(FLAG_TRANSLATION_ONGOING);
160     }
161 
setFlag(int flag)162     private void setFlag(int flag) {
163         mFlags |= flag;
164     }
165 
removeFlag(int flag)166     private void removeFlag(int flag) {
167         mFlags &= ~flag;
168     }
169 }
170