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.statusbar.phone;
18 
19 import static com.android.systemui.DejankUtils.whitelistIpcs;
20 
21 import android.os.UserManager;
22 import android.view.View;
23 import android.view.ViewGroup;
24 
25 import com.android.systemui.R;
26 import com.android.systemui.flags.FeatureFlags;
27 import com.android.systemui.plugins.FalsingManager;
28 import com.android.systemui.plugins.qs.DetailAdapter;
29 import com.android.systemui.qs.FooterActionsView;
30 import com.android.systemui.qs.QSDetailDisplayer;
31 import com.android.systemui.qs.dagger.QSScope;
32 import com.android.systemui.qs.user.UserSwitchDialogController;
33 import com.android.systemui.statusbar.policy.UserSwitcherController;
34 import com.android.systemui.util.ViewController;
35 
36 import javax.inject.Inject;
37 
38 /** View Controller for {@link MultiUserSwitch}. */
39 public class MultiUserSwitchController extends ViewController<MultiUserSwitch> {
40     private final UserManager mUserManager;
41     private final UserSwitcherController mUserSwitcherController;
42     private final QSDetailDisplayer mQsDetailDisplayer;
43     private final FalsingManager mFalsingManager;
44     private final UserSwitchDialogController mUserSwitchDialogController;
45     private final FeatureFlags mFeatureFlags;
46 
47     private UserSwitcherController.BaseUserAdapter mUserListener;
48 
49     private final View.OnClickListener mOnClickListener = new View.OnClickListener() {
50         @Override
51         public void onClick(View v) {
52             if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
53                 return;
54             }
55 
56             if (mFeatureFlags.useNewUserSwitcher()) {
57                 mUserSwitchDialogController.showDialog(v);
58             } else {
59                 View center = mView.getChildCount() > 0 ? mView.getChildAt(0) : mView;
60 
61                 int[] tmpInt = new int[2];
62                 center.getLocationInWindow(tmpInt);
63                 tmpInt[0] += center.getWidth() / 2;
64                 tmpInt[1] += center.getHeight() / 2;
65 
66                 mQsDetailDisplayer.showDetailAdapter(getUserDetailAdapter(), tmpInt[0], tmpInt[1]);
67             }
68         }
69     };
70 
71     @QSScope
72     public static class Factory {
73         private final UserManager mUserManager;
74         private final UserSwitcherController mUserSwitcherController;
75         private final QSDetailDisplayer mQsDetailDisplayer;
76         private final FalsingManager mFalsingManager;
77         private final UserSwitchDialogController mUserSwitchDialogController;
78         private final FeatureFlags mFeatureFlags;
79 
80         @Inject
Factory(UserManager userManager, UserSwitcherController userSwitcherController, QSDetailDisplayer qsDetailDisplayer, FalsingManager falsingManager, UserSwitchDialogController userSwitchDialogController, FeatureFlags featureFlags)81         public Factory(UserManager userManager, UserSwitcherController userSwitcherController,
82                 QSDetailDisplayer qsDetailDisplayer, FalsingManager falsingManager,
83                 UserSwitchDialogController userSwitchDialogController,
84                 FeatureFlags featureFlags) {
85             mUserManager = userManager;
86             mUserSwitcherController = userSwitcherController;
87             mQsDetailDisplayer = qsDetailDisplayer;
88             mFalsingManager = falsingManager;
89             mUserSwitchDialogController = userSwitchDialogController;
90             mFeatureFlags = featureFlags;
91         }
92 
create(FooterActionsView view)93         public MultiUserSwitchController create(FooterActionsView view) {
94             return new MultiUserSwitchController(view.findViewById(R.id.multi_user_switch),
95                     mUserManager, mUserSwitcherController, mQsDetailDisplayer,
96                     mFalsingManager, mUserSwitchDialogController, mFeatureFlags);
97         }
98     }
99 
MultiUserSwitchController(MultiUserSwitch view, UserManager userManager, UserSwitcherController userSwitcherController, QSDetailDisplayer qsDetailDisplayer, FalsingManager falsingManager, UserSwitchDialogController userSwitchDialogController, FeatureFlags featureFlags)100     private MultiUserSwitchController(MultiUserSwitch view, UserManager userManager,
101             UserSwitcherController userSwitcherController, QSDetailDisplayer qsDetailDisplayer,
102             FalsingManager falsingManager, UserSwitchDialogController userSwitchDialogController,
103             FeatureFlags featureFlags) {
104         super(view);
105         mUserManager = userManager;
106         mUserSwitcherController = userSwitcherController;
107         mQsDetailDisplayer = qsDetailDisplayer;
108         mFalsingManager = falsingManager;
109         mUserSwitchDialogController = userSwitchDialogController;
110         mFeatureFlags = featureFlags;
111     }
112 
113     @Override
onInit()114     protected void onInit() {
115         registerListener();
116         mView.refreshContentDescription(getCurrentUser());
117     }
118 
119     @Override
onViewAttached()120     protected void onViewAttached() {
121         mView.setOnClickListener(mOnClickListener);
122     }
123 
124     @Override
onViewDetached()125     protected void onViewDetached() {
126         mView.setOnClickListener(null);
127     }
128 
getUserDetailAdapter()129     protected DetailAdapter getUserDetailAdapter() {
130         return mUserSwitcherController.mUserDetailAdapter;
131     }
132 
registerListener()133     private void registerListener() {
134         if (mUserManager.isUserSwitcherEnabled() && mUserListener == null) {
135 
136             final UserSwitcherController controller = mUserSwitcherController;
137             if (controller != null) {
138                 mUserListener = new UserSwitcherController.BaseUserAdapter(controller) {
139                     @Override
140                     public void notifyDataSetChanged() {
141                         mView.refreshContentDescription(getCurrentUser());
142                     }
143 
144                     @Override
145                     public View getView(int position, View convertView, ViewGroup parent) {
146                         return null;
147                     }
148                 };
149                 mView.refreshContentDescription(getCurrentUser());
150             }
151         }
152     }
153 
getCurrentUser()154     private String getCurrentUser() {
155         // TODO(b/138661450)
156         if (whitelistIpcs(() -> mUserManager.isUserSwitcherEnabled())) {
157             return mUserSwitcherController.getCurrentUserName();
158         }
159 
160         return null;
161     }
162 
163     /** Returns true if view should be made visible. */
isMultiUserEnabled()164     public boolean isMultiUserEnabled() {
165         // TODO(b/138661450) Move IPC calls to background
166         return whitelistIpcs(() -> mUserManager.isUserSwitcherEnabled(
167                 getResources().getBoolean(R.bool.qs_show_user_switcher_for_single_user)));
168     }
169 
170 }
171