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