• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.accessibility.floatingmenu;
18 
19 import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
20 
21 import android.content.Context;
22 import android.os.UserHandle;
23 import android.text.TextUtils;
24 
25 import androidx.annotation.MainThread;
26 
27 import com.android.internal.annotations.VisibleForTesting;
28 import com.android.keyguard.KeyguardUpdateMonitor;
29 import com.android.keyguard.KeyguardUpdateMonitorCallback;
30 import com.android.systemui.accessibility.AccessibilityButtonModeObserver;
31 import com.android.systemui.accessibility.AccessibilityButtonModeObserver.AccessibilityButtonMode;
32 import com.android.systemui.accessibility.AccessibilityButtonTargetsObserver;
33 import com.android.systemui.dagger.SysUISingleton;
34 import com.android.systemui.util.settings.SecureSettings;
35 
36 import javax.inject.Inject;
37 
38 /** A controller to handle the lifecycle of accessibility floating menu. */
39 @MainThread
40 @SysUISingleton
41 public class AccessibilityFloatingMenuController implements
42         AccessibilityButtonModeObserver.ModeChangedListener,
43         AccessibilityButtonTargetsObserver.TargetsChangedListener {
44 
45     private final AccessibilityButtonModeObserver mAccessibilityButtonModeObserver;
46     private final AccessibilityButtonTargetsObserver mAccessibilityButtonTargetsObserver;
47     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
48     private final SecureSettings mSecureSettings;
49 
50     private Context mContext;
51     @VisibleForTesting
52     IAccessibilityFloatingMenu mFloatingMenu;
53     private int mBtnMode;
54     private String mBtnTargets;
55     private boolean mIsKeyguardVisible;
56 
57     @VisibleForTesting
58     final KeyguardUpdateMonitorCallback mKeyguardCallback = new KeyguardUpdateMonitorCallback() {
59 
60         @Override
61         public void onUserUnlocked() {
62             handleFloatingMenuVisibility(mIsKeyguardVisible, mBtnMode, mBtnTargets);
63         }
64 
65         @Override
66         public void onKeyguardVisibilityChanged(boolean visible) {
67             mIsKeyguardVisible = visible;
68             handleFloatingMenuVisibility(mIsKeyguardVisible, mBtnMode, mBtnTargets);
69         }
70 
71         @Override
72         public void onUserSwitching(int userId) {
73             destroyFloatingMenu();
74         }
75 
76         @Override
77         public void onUserSwitchComplete(int userId) {
78             mContext = mContext.createContextAsUser(UserHandle.of(userId), /* flags= */ 0);
79             mBtnMode = mAccessibilityButtonModeObserver.getCurrentAccessibilityButtonMode();
80             mBtnTargets =
81                     mAccessibilityButtonTargetsObserver.getCurrentAccessibilityButtonTargets();
82             handleFloatingMenuVisibility(mIsKeyguardVisible, mBtnMode, mBtnTargets);
83         }
84     };
85 
86     @Inject
AccessibilityFloatingMenuController(Context context, AccessibilityButtonTargetsObserver accessibilityButtonTargetsObserver, AccessibilityButtonModeObserver accessibilityButtonModeObserver, KeyguardUpdateMonitor keyguardUpdateMonitor, SecureSettings secureSettings)87     public AccessibilityFloatingMenuController(Context context,
88             AccessibilityButtonTargetsObserver accessibilityButtonTargetsObserver,
89             AccessibilityButtonModeObserver accessibilityButtonModeObserver,
90             KeyguardUpdateMonitor keyguardUpdateMonitor,
91             SecureSettings secureSettings) {
92         mContext = context;
93         mAccessibilityButtonTargetsObserver = accessibilityButtonTargetsObserver;
94         mAccessibilityButtonModeObserver = accessibilityButtonModeObserver;
95         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
96         mSecureSettings = secureSettings;
97 
98         mIsKeyguardVisible = false;
99     }
100 
101     /**
102      * Handles visibility of the accessibility floating menu when accessibility button mode changes.
103      *
104      * @param mode Current accessibility button mode.
105      */
106     @Override
onAccessibilityButtonModeChanged(@ccessibilityButtonMode int mode)107     public void onAccessibilityButtonModeChanged(@AccessibilityButtonMode int mode) {
108         mBtnMode = mode;
109         handleFloatingMenuVisibility(mIsKeyguardVisible, mBtnMode, mBtnTargets);
110     }
111 
112     /**
113      * Handles visibility of the accessibility floating menu when accessibility button targets
114      * changes.
115      * List should come from {@link android.provider.Settings.Secure#ACCESSIBILITY_BUTTON_TARGETS}.
116      * @param targets Current accessibility button list.
117      */
118     @Override
onAccessibilityButtonTargetsChanged(String targets)119     public void onAccessibilityButtonTargetsChanged(String targets) {
120         mBtnTargets = targets;
121         handleFloatingMenuVisibility(mIsKeyguardVisible, mBtnMode, mBtnTargets);
122     }
123 
124     /** Initializes the AccessibilityFloatingMenuController configurations. */
init()125     public void init() {
126         mBtnMode = mAccessibilityButtonModeObserver.getCurrentAccessibilityButtonMode();
127         mBtnTargets = mAccessibilityButtonTargetsObserver.getCurrentAccessibilityButtonTargets();
128         registerContentObservers();
129     }
130 
registerContentObservers()131     private void registerContentObservers() {
132         mAccessibilityButtonModeObserver.addListener(this);
133         mAccessibilityButtonTargetsObserver.addListener(this);
134         mKeyguardUpdateMonitor.registerCallback(mKeyguardCallback);
135     }
136 
137     /**
138      * Handles the accessibility floating menu visibility with the given values.
139      *
140      * @param keyguardVisible the keyguard visibility status. Not show the
141      *                        {@link AccessibilityFloatingMenu} when keyguard appears.
142      * @param mode accessibility button mode {@link AccessibilityButtonMode}
143      * @param targets accessibility button list; it should comes from
144      *                {@link android.provider.Settings.Secure#ACCESSIBILITY_BUTTON_TARGETS}.
145      */
handleFloatingMenuVisibility(boolean keyguardVisible, @AccessibilityButtonMode int mode, String targets)146     private void handleFloatingMenuVisibility(boolean keyguardVisible,
147             @AccessibilityButtonMode int mode, String targets) {
148         if (keyguardVisible) {
149             destroyFloatingMenu();
150             return;
151         }
152 
153         if (shouldShowFloatingMenu(mode, targets)) {
154             showFloatingMenu();
155         } else {
156             destroyFloatingMenu();
157         }
158     }
159 
shouldShowFloatingMenu(@ccessibilityButtonMode int mode, String targets)160     private boolean shouldShowFloatingMenu(@AccessibilityButtonMode int mode, String targets) {
161         return mode == ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU && !TextUtils.isEmpty(targets);
162     }
163 
showFloatingMenu()164     private void showFloatingMenu() {
165         if (mFloatingMenu == null) {
166             mFloatingMenu = new AccessibilityFloatingMenu(mContext, mSecureSettings);
167         }
168 
169         mFloatingMenu.show();
170     }
171 
destroyFloatingMenu()172     private void destroyFloatingMenu() {
173         if (mFloatingMenu == null) {
174             return;
175         }
176 
177         mFloatingMenu.hide();
178         mFloatingMenu = null;
179     }
180 }
181