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 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; 20 21 import android.content.Context; 22 import android.graphics.Insets; 23 import android.graphics.Rect; 24 import android.os.Build; 25 import android.os.Process; 26 import android.os.UserHandle; 27 import android.os.UserManager; 28 import android.util.AttributeSet; 29 import android.view.View; 30 import android.view.ViewGroup; 31 import android.view.WindowInsets; 32 import android.widget.Button; 33 34 import androidx.annotation.Nullable; 35 import androidx.annotation.RequiresApi; 36 37 import com.android.launcher3.Insettable; 38 import com.android.launcher3.Launcher; 39 import com.android.launcher3.Utilities; 40 import com.android.launcher3.anim.KeyboardInsetAnimationCallback; 41 import com.android.launcher3.pm.UserCache; 42 43 /** 44 * Work profile toggle switch shown at the bottom of AllApps work tab 45 */ 46 public class WorkModeSwitch extends Button implements Insettable, View.OnClickListener { 47 48 private Rect mInsets = new Rect(); 49 private boolean mWorkEnabled; 50 51 52 @Nullable 53 private KeyboardInsetAnimationCallback mKeyboardInsetAnimationCallback; 54 WorkModeSwitch(Context context)55 public WorkModeSwitch(Context context) { 56 this(context, null, 0); 57 } 58 WorkModeSwitch(Context context, AttributeSet attrs)59 public WorkModeSwitch(Context context, AttributeSet attrs) { 60 this(context, attrs, 0); 61 } 62 WorkModeSwitch(Context context, AttributeSet attrs, int defStyleAttr)63 public WorkModeSwitch(Context context, AttributeSet attrs, int defStyleAttr) { 64 super(context, attrs, defStyleAttr); 65 } 66 67 @Override onFinishInflate()68 protected void onFinishInflate() { 69 super.onFinishInflate(); 70 setSelected(true); 71 setOnClickListener(this); 72 if (Utilities.ATLEAST_R) { 73 mKeyboardInsetAnimationCallback = new KeyboardInsetAnimationCallback(this); 74 setWindowInsetsAnimationCallback(mKeyboardInsetAnimationCallback); 75 } 76 } 77 78 @Override setInsets(Rect insets)79 public void setInsets(Rect insets) { 80 int bottomInset = insets.bottom - mInsets.bottom; 81 mInsets.set(insets); 82 ViewGroup.MarginLayoutParams marginLayoutParams = 83 (ViewGroup.MarginLayoutParams) getLayoutParams(); 84 if (marginLayoutParams != null) { 85 marginLayoutParams.bottomMargin = bottomInset + marginLayoutParams.bottomMargin; 86 } 87 } 88 89 /** 90 * Animates in/out work profile toggle panel based on the tab user is on 91 */ setWorkTabVisible(boolean workTabVisible)92 public void setWorkTabVisible(boolean workTabVisible) { 93 clearAnimation(); 94 if (workTabVisible) { 95 setEnabled(true); 96 if (mWorkEnabled) { 97 setVisibility(VISIBLE); 98 } 99 setAlpha(0); 100 animate().alpha(1).start(); 101 } else { 102 animate().alpha(0).withEndAction(() -> this.setVisibility(GONE)).start(); 103 } 104 } 105 106 @Override onClick(View view)107 public void onClick(View view) { 108 if (Utilities.ATLEAST_P) { 109 setEnabled(false); 110 Launcher.fromContext(getContext()).getStatsLogManager().logger().log( 111 LAUNCHER_TURN_OFF_WORK_APPS_TAP); 112 UI_HELPER_EXECUTOR.post(() -> setWorkProfileEnabled(getContext(), false)); 113 } 114 } 115 116 /** 117 * Sets the enabled or disabled state of the button 118 */ updateCurrentState(boolean active)119 public void updateCurrentState(boolean active) { 120 mWorkEnabled = active; 121 setEnabled(true); 122 setVisibility(active ? VISIBLE : GONE); 123 } 124 125 @RequiresApi(Build.VERSION_CODES.P) setWorkProfileEnabled(Context context, boolean enabled)126 public static Boolean setWorkProfileEnabled(Context context, boolean enabled) { 127 UserManager userManager = context.getSystemService(UserManager.class); 128 boolean showConfirm = false; 129 for (UserHandle userProfile : UserCache.INSTANCE.get(context).getUserProfiles()) { 130 if (Process.myUserHandle().equals(userProfile)) { 131 continue; 132 } 133 showConfirm |= !userManager.requestQuietModeEnabled(!enabled, userProfile); 134 } 135 return showConfirm; 136 } 137 138 @Override onApplyWindowInsets(WindowInsets insets)139 public WindowInsets onApplyWindowInsets(WindowInsets insets) { 140 if (Utilities.ATLEAST_R) { 141 setTranslationY(0); 142 if (insets.isVisible(WindowInsets.Type.ime())) { 143 Insets keyboardInsets = insets.getInsets(WindowInsets.Type.ime()); 144 setTranslationY(mInsets.bottom - keyboardInsets.bottom); 145 } 146 } 147 return insets; 148 } 149 } 150