1 /*
2  * Copyright (C) 2014 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.statusbar.phone;
18 
19 import static com.android.systemui.DejankUtils.whitelistIpcs;
20 
21 import android.content.Context;
22 import android.os.UserManager;
23 import android.text.TextUtils;
24 import android.util.AttributeSet;
25 import android.view.View;
26 import android.view.ViewGroup;
27 import android.view.accessibility.AccessibilityEvent;
28 import android.view.accessibility.AccessibilityNodeInfo;
29 import android.widget.Button;
30 import android.widget.FrameLayout;
31 
32 import com.android.systemui.Dependency;
33 import com.android.systemui.Prefs;
34 import com.android.systemui.Prefs.Key;
35 import com.android.systemui.R;
36 import com.android.systemui.plugins.qs.DetailAdapter;
37 import com.android.systemui.qs.QSPanel;
38 import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
39 import com.android.systemui.statusbar.policy.UserSwitcherController;
40 
41 /**
42  * Container for image of the multi user switcher (tappable).
43  */
44 public class MultiUserSwitch extends FrameLayout implements View.OnClickListener {
45 
46     protected QSPanel mQsPanel;
47     private KeyguardUserSwitcher mKeyguardUserSwitcher;
48     private boolean mKeyguardMode;
49     private UserSwitcherController.BaseUserAdapter mUserListener;
50 
51     final UserManager mUserManager;
52 
53     private final int[] mTmpInt2 = new int[2];
54 
55     protected UserSwitcherController mUserSwitcherController;
56 
MultiUserSwitch(Context context, AttributeSet attrs)57     public MultiUserSwitch(Context context, AttributeSet attrs) {
58         super(context, attrs);
59         mUserManager = UserManager.get(getContext());
60     }
61 
62     @Override
onFinishInflate()63     protected void onFinishInflate() {
64         super.onFinishInflate();
65         setOnClickListener(this);
66         refreshContentDescription();
67     }
68 
setQsPanel(QSPanel qsPanel)69     public void setQsPanel(QSPanel qsPanel) {
70         mQsPanel = qsPanel;
71         setUserSwitcherController(Dependency.get(UserSwitcherController.class));
72     }
73 
hasMultipleUsers()74     public boolean hasMultipleUsers() {
75         if (mUserListener == null) {
76             return false;
77         }
78         return mUserListener.getUserCount() != 0
79                 && Prefs.getBoolean(getContext(), Key.SEEN_MULTI_USER, false);
80     }
81 
setUserSwitcherController(UserSwitcherController userSwitcherController)82     public void setUserSwitcherController(UserSwitcherController userSwitcherController) {
83         mUserSwitcherController = userSwitcherController;
84         registerListener();
85         refreshContentDescription();
86     }
87 
setKeyguardUserSwitcher(KeyguardUserSwitcher keyguardUserSwitcher)88     public void setKeyguardUserSwitcher(KeyguardUserSwitcher keyguardUserSwitcher) {
89         mKeyguardUserSwitcher = keyguardUserSwitcher;
90     }
91 
setKeyguardMode(boolean keyguardShowing)92     public void setKeyguardMode(boolean keyguardShowing) {
93         mKeyguardMode = keyguardShowing;
94         registerListener();
95     }
96 
isMultiUserEnabled()97     public boolean isMultiUserEnabled() {
98         // TODO(b/138661450) Move IPC calls to background
99         return whitelistIpcs(() -> mUserManager.isUserSwitcherEnabled(
100                 mContext.getResources().getBoolean(R.bool.qs_show_user_switcher_for_single_user)));
101     }
102 
registerListener()103     private void registerListener() {
104         if (mUserManager.isUserSwitcherEnabled() && mUserListener == null) {
105 
106             final UserSwitcherController controller = mUserSwitcherController;
107             if (controller != null) {
108                 mUserListener = new UserSwitcherController.BaseUserAdapter(controller) {
109                     @Override
110                     public void notifyDataSetChanged() {
111                         refreshContentDescription();
112                     }
113 
114                     @Override
115                     public View getView(int position, View convertView, ViewGroup parent) {
116                         return null;
117                     }
118                 };
119                 refreshContentDescription();
120             }
121         }
122     }
123 
124     @Override
onClick(View v)125     public void onClick(View v) {
126         if (mKeyguardMode) {
127             if (mKeyguardUserSwitcher != null) {
128                 mKeyguardUserSwitcher.show(true /* animate */);
129             }
130         } else if (mQsPanel != null && mUserSwitcherController != null) {
131             View center = getChildCount() > 0 ? getChildAt(0) : this;
132 
133             center.getLocationInWindow(mTmpInt2);
134             mTmpInt2[0] += center.getWidth() / 2;
135             mTmpInt2[1] += center.getHeight() / 2;
136 
137             mQsPanel.showDetailAdapter(true,
138                     getUserDetailAdapter(),
139                     mTmpInt2);
140         }
141     }
142 
143     @Override
setClickable(boolean clickable)144     public void setClickable(boolean clickable) {
145         super.setClickable(clickable);
146         refreshContentDescription();
147     }
148 
refreshContentDescription()149     private void refreshContentDescription() {
150         String currentUser = null;
151         // TODO(b/138661450)
152         if (whitelistIpcs(() -> mUserManager.isUserSwitcherEnabled())
153                 && mUserSwitcherController != null) {
154             currentUser = mUserSwitcherController.getCurrentUserName(mContext);
155         }
156 
157         String text = null;
158 
159         if (!TextUtils.isEmpty(currentUser)) {
160             text = mContext.getString(
161                     R.string.accessibility_quick_settings_user,
162                     currentUser);
163         }
164 
165         if (!TextUtils.equals(getContentDescription(), text)) {
166             setContentDescription(text);
167         }
168     }
169 
170     @Override
onInitializeAccessibilityEvent(AccessibilityEvent event)171     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
172         super.onInitializeAccessibilityEvent(event);
173         event.setClassName(Button.class.getName());
174     }
175 
176     @Override
onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info)177     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
178         super.onInitializeAccessibilityNodeInfo(info);
179         info.setClassName(Button.class.getName());
180     }
181 
182     @Override
hasOverlappingRendering()183     public boolean hasOverlappingRendering() {
184         return false;
185     }
186 
getUserDetailAdapter()187     protected DetailAdapter getUserDetailAdapter() {
188         return mUserSwitcherController.userDetailAdapter;
189     }
190 }
191