Merge "Add falsing check to MultiUserSwitch" into sc-dev

This commit is contained in:
Dave Mankoff
2021-04-27 01:41:15 +00:00
committed by Android (Google) Code Review
7 changed files with 173 additions and 135 deletions

View File

@@ -195,10 +195,10 @@ public class QSFooterView extends FrameLayout {
mExpandClickListener = onClickListener;
}
void setExpanded(boolean expanded, boolean isTunerEnabled) {
void setExpanded(boolean expanded, boolean isTunerEnabled, boolean multiUserEnabled) {
if (mExpanded == expanded) return;
mExpanded = expanded;
updateEverything(isTunerEnabled);
updateEverything(isTunerEnabled, multiUserEnabled);
}
/** */
@@ -251,16 +251,16 @@ public class QSFooterView extends FrameLayout {
info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND);
}
void disable(int state2, boolean isTunerEnabled) {
void disable(int state2, boolean isTunerEnabled, boolean multiUserEnabled) {
final boolean disabled = (state2 & DISABLE2_QUICK_SETTINGS) != 0;
if (disabled == mQsDisabled) return;
mQsDisabled = disabled;
updateEverything(isTunerEnabled);
updateEverything(isTunerEnabled, multiUserEnabled);
}
void updateEverything(boolean isTunerEnabled) {
void updateEverything(boolean isTunerEnabled, boolean multiUserEnabled) {
post(() -> {
updateVisibilities(isTunerEnabled);
updateVisibilities(isTunerEnabled, multiUserEnabled);
updateClickabilities();
setClickable(false);
});
@@ -273,18 +273,19 @@ public class QSFooterView extends FrameLayout {
mBuildText.setLongClickable(mBuildText.getVisibility() == View.VISIBLE);
}
private void updateVisibilities(boolean isTunerEnabled) {
private void updateVisibilities(boolean isTunerEnabled, boolean multiUserEnabled) {
mSettingsContainer.setVisibility(mQsDisabled ? View.GONE : View.VISIBLE);
mTunerIcon.setVisibility(isTunerEnabled ? View.VISIBLE : View.INVISIBLE);
final boolean isDemo = UserManager.isDeviceInDemoMode(mContext);
mMultiUserSwitch.setVisibility(showUserSwitcher() ? View.VISIBLE : View.GONE);
mMultiUserSwitch.setVisibility(
showUserSwitcher(multiUserEnabled) ? View.VISIBLE : View.GONE);
mSettingsButton.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE);
mBuildText.setVisibility(mExpanded && mShouldShowBuildText ? View.VISIBLE : View.INVISIBLE);
}
private boolean showUserSwitcher() {
return mExpanded && mMultiUserSwitch.isMultiUserEnabled();
private boolean showUserSwitcher(boolean multiUserEnabled) {
return mExpanded && multiUserEnabled;
}
void onUserInfoChanged(Drawable picture, boolean isGuestUser) {

View File

@@ -38,7 +38,7 @@ import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.qs.dagger.QSScope;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.phone.MultiUserSwitch;
import com.android.systemui.statusbar.phone.MultiUserSwitchController;
import com.android.systemui.statusbar.phone.SettingsButton;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.UserInfoController;
@@ -60,16 +60,15 @@ public class QSFooterViewController extends ViewController<QSFooterView> impleme
private final DeviceProvisionedController mDeviceProvisionedController;
private final UserTracker mUserTracker;
private final QSPanelController mQsPanelController;
private final QSDetailDisplayer mQsDetailDisplayer;
private final QuickQSPanelController mQuickQSPanelController;
private final TunerService mTunerService;
private final MetricsLogger mMetricsLogger;
private final FalsingManager mFalsingManager;
private final MultiUserSwitchController mMultiUserSwitchController;
private final SettingsButton mSettingsButton;
private final View mSettingsButtonContainer;
private final TextView mBuildText;
private final View mEdit;
private final MultiUserSwitch mMultiUserSwitch;
private final PageIndicator mPageIndicator;
private final View mPowerMenuLite;
private final boolean mShowPMLiteButton;
@@ -135,7 +134,8 @@ public class QSFooterViewController extends ViewController<QSFooterView> impleme
QSFooterViewController(QSFooterView view, UserManager userManager,
UserInfoController userInfoController, ActivityStarter activityStarter,
DeviceProvisionedController deviceProvisionedController, UserTracker userTracker,
QSPanelController qsPanelController, QSDetailDisplayer qsDetailDisplayer,
QSPanelController qsPanelController,
MultiUserSwitchController multiUserSwitchController,
QuickQSPanelController quickQSPanelController,
TunerService tunerService, MetricsLogger metricsLogger, FalsingManager falsingManager,
@Named(PM_LITE_ENABLED) boolean showPMLiteButton,
@@ -147,23 +147,28 @@ public class QSFooterViewController extends ViewController<QSFooterView> impleme
mDeviceProvisionedController = deviceProvisionedController;
mUserTracker = userTracker;
mQsPanelController = qsPanelController;
mQsDetailDisplayer = qsDetailDisplayer;
mQuickQSPanelController = quickQSPanelController;
mTunerService = tunerService;
mMetricsLogger = metricsLogger;
mFalsingManager = falsingManager;
mMultiUserSwitchController = multiUserSwitchController;
mSettingsButton = mView.findViewById(R.id.settings_button);
mSettingsButtonContainer = mView.findViewById(R.id.settings_button_container);
mBuildText = mView.findViewById(R.id.build);
mEdit = mView.findViewById(android.R.id.edit);
mMultiUserSwitch = mView.findViewById(R.id.multi_user_switch);
mPageIndicator = mView.findViewById(R.id.footer_page_indicator);
mPowerMenuLite = mView.findViewById(R.id.pm_lite);
mShowPMLiteButton = showPMLiteButton;
mGlobalActionsDialog = globalActionsDialog;
}
@Override
protected void onInit() {
super.onInit();
mMultiUserSwitchController.init();
}
@Override
protected void onViewAttached() {
if (mShowPMLiteButton) {
@@ -199,9 +204,8 @@ public class QSFooterViewController extends ViewController<QSFooterView> impleme
mQsPanelController.showEdit(view));
});
mMultiUserSwitch.setQSDetailDisplayer(mQsDetailDisplayer);
mQsPanelController.setFooterPageIndicator(mPageIndicator);
mView.updateEverything(isTunerEnabled());
mView.updateEverything(isTunerEnabled(), mMultiUserSwitchController.isMultiUserEnabled());
}
@Override
@@ -217,10 +221,10 @@ public class QSFooterViewController extends ViewController<QSFooterView> impleme
@Override
public void setExpanded(boolean expanded) {
mExpanded = expanded;
mView.setExpanded(expanded, isTunerEnabled());
mView.setExpanded(
expanded, isTunerEnabled(), mMultiUserSwitchController.isMultiUserEnabled());
}
@Override
public int getHeight() {
return mView.getHeight();
@@ -258,7 +262,7 @@ public class QSFooterViewController extends ViewController<QSFooterView> impleme
@Override
public void disable(int state1, int state2, boolean animate) {
mView.disable(state2, isTunerEnabled());
mView.disable(state2, isTunerEnabled(), mMultiUserSwitchController.isMultiUserEnabled());
}
private void startSettingsActivity() {

View File

@@ -34,6 +34,7 @@ import com.android.systemui.qs.QSPanel;
import com.android.systemui.qs.QuickQSPanel;
import com.android.systemui.qs.QuickStatusBarHeader;
import com.android.systemui.qs.customize.QSCustomizer;
import com.android.systemui.statusbar.phone.MultiUserSwitch;
import javax.inject.Named;
@@ -72,6 +73,12 @@ public interface QSFragmentModule {
return qsFragment.getView();
}
/** */
@Provides
static MultiUserSwitch providesMultiUserSWitch(QSFooterView qsFooterView) {
return qsFooterView.findViewById(R.id.multi_user_switch);
}
/** */
@Provides
static QSPanel provideQSPanel(@RootView View view) {

View File

@@ -16,127 +16,25 @@
package com.android.systemui.statusbar.phone;
import static com.android.systemui.DejankUtils.whitelistIpcs;
import android.content.Context;
import android.os.UserManager;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.Button;
import android.widget.FrameLayout;
import com.android.systemui.Dependency;
import com.android.systemui.Prefs;
import com.android.systemui.Prefs.Key;
import com.android.systemui.R;
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.qs.QSDetailDisplayer;
import com.android.systemui.statusbar.policy.UserSwitcherController;
/**
* Container for image of the multi user switcher (tappable).
*/
public class MultiUserSwitch extends FrameLayout implements View.OnClickListener {
protected QSDetailDisplayer mQSDetailDisplayer;
private UserSwitcherController.BaseUserAdapter mUserListener;
final UserManager mUserManager;
protected UserSwitcherController mUserSwitcherController;
public class MultiUserSwitch extends FrameLayout {
public MultiUserSwitch(Context context, AttributeSet attrs) {
super(context, attrs);
mUserManager = UserManager.get(getContext());
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
setOnClickListener(this);
refreshContentDescription();
}
/** */
public void setQSDetailDisplayer(QSDetailDisplayer detailDisplayer) {
mQSDetailDisplayer = detailDisplayer;
setUserSwitcherController(Dependency.get(UserSwitcherController.class));
}
public boolean hasMultipleUsers() {
if (mUserListener == null) {
return false;
}
return mUserListener.getUserCount() != 0
&& Prefs.getBoolean(getContext(), Key.SEEN_MULTI_USER, false);
}
public void setUserSwitcherController(UserSwitcherController userSwitcherController) {
mUserSwitcherController = userSwitcherController;
registerListener();
refreshContentDescription();
}
public boolean isMultiUserEnabled() {
// TODO(b/138661450) Move IPC calls to background
return whitelistIpcs(() -> mUserManager.isUserSwitcherEnabled(
mContext.getResources().getBoolean(R.bool.qs_show_user_switcher_for_single_user)));
}
private void registerListener() {
if (mUserManager.isUserSwitcherEnabled() && mUserListener == null) {
final UserSwitcherController controller = mUserSwitcherController;
if (controller != null) {
mUserListener = new UserSwitcherController.BaseUserAdapter(controller) {
@Override
public void notifyDataSetChanged() {
refreshContentDescription();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return null;
}
};
refreshContentDescription();
}
}
}
@Override
public void onClick(View v) {
if (mQSDetailDisplayer != null && mUserSwitcherController != null) {
View center = getChildCount() > 0 ? getChildAt(0) : this;
int[] tmpInt = new int[2];
center.getLocationInWindow(tmpInt);
tmpInt[0] += center.getWidth() / 2;
tmpInt[1] += center.getHeight() / 2;
mQSDetailDisplayer.showDetailAdapter(getUserDetailAdapter(), tmpInt[0], tmpInt[1]);
}
}
@Override
public void setClickable(boolean clickable) {
super.setClickable(clickable);
refreshContentDescription();
}
private void refreshContentDescription() {
String currentUser = null;
// TODO(b/138661450)
if (whitelistIpcs(() -> mUserManager.isUserSwitcherEnabled())
&& mUserSwitcherController != null) {
currentUser = mUserSwitcherController.getCurrentUserName(mContext);
}
void refreshContentDescription(String currentUser) {
String text = null;
if (!TextUtils.isEmpty(currentUser)) {
@@ -166,8 +64,4 @@ public class MultiUserSwitch extends FrameLayout implements View.OnClickListener
public boolean hasOverlappingRendering() {
return false;
}
protected DetailAdapter getUserDetailAdapter() {
return mUserSwitcherController.mUserDetailAdapter;
}
}

View File

@@ -0,0 +1,131 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.statusbar.phone;
import static com.android.systemui.DejankUtils.whitelistIpcs;
import android.os.UserManager;
import android.view.View;
import android.view.ViewGroup;
import com.android.systemui.R;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.qs.QSDetailDisplayer;
import com.android.systemui.qs.dagger.QSScope;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.util.ViewController;
import javax.inject.Inject;
/** View Controller for {@link MultiUserSwitch}. */
@QSScope
public class MultiUserSwitchController extends ViewController<MultiUserSwitch> {
private final UserManager mUserManager;
private final UserSwitcherController mUserSwitcherController;
private final QSDetailDisplayer mQsDetailDisplayer;
private final FalsingManager mFalsingManager;
private UserSwitcherController.BaseUserAdapter mUserListener;
private final View.OnClickListener mOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
return;
}
View center = mView.getChildCount() > 0 ? mView.getChildAt(0) : mView;
int[] tmpInt = new int[2];
center.getLocationInWindow(tmpInt);
tmpInt[0] += center.getWidth() / 2;
tmpInt[1] += center.getHeight() / 2;
mQsDetailDisplayer.showDetailAdapter(getUserDetailAdapter(), tmpInt[0], tmpInt[1]);
}
};
@Inject
public MultiUserSwitchController(MultiUserSwitch view, UserManager userManager,
UserSwitcherController userSwitcherController, QSDetailDisplayer qsDetailDisplayer,
FalsingManager falsingManager) {
super(view);
mUserManager = userManager;
mUserSwitcherController = userSwitcherController;
mQsDetailDisplayer = qsDetailDisplayer;
mFalsingManager = falsingManager;
}
@Override
protected void onInit() {
registerListener();
mView.refreshContentDescription(getCurrentUser());
}
@Override
protected void onViewAttached() {
mView.setOnClickListener(mOnClickListener);
}
@Override
protected void onViewDetached() {
mView.setOnClickListener(null);
}
protected DetailAdapter getUserDetailAdapter() {
return mUserSwitcherController.mUserDetailAdapter;
}
private void registerListener() {
if (mUserManager.isUserSwitcherEnabled() && mUserListener == null) {
final UserSwitcherController controller = mUserSwitcherController;
if (controller != null) {
mUserListener = new UserSwitcherController.BaseUserAdapter(controller) {
@Override
public void notifyDataSetChanged() {
mView.refreshContentDescription(getCurrentUser());
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return null;
}
};
mView.refreshContentDescription(getCurrentUser());
}
}
}
private String getCurrentUser() {
// TODO(b/138661450)
if (whitelistIpcs(() -> mUserManager.isUserSwitcherEnabled())) {
return mUserSwitcherController.getCurrentUserName();
}
return null;
}
/** Returns true if view should be made visible. */
public boolean isMultiUserEnabled() {
// TODO(b/138661450) Move IPC calls to background
return whitelistIpcs(() -> mUserManager.isUserSwitcherEnabled(
getResources().getBoolean(R.bool.qs_show_user_switcher_for_single_user)));
}
}

View File

@@ -577,11 +577,13 @@ public class UserSwitcherController implements Dumpable {
pw.println("mSimpleUserSwitcher=" + mSimpleUserSwitcher);
}
public String getCurrentUserName(Context context) {
/** Returns the name of the current user of the phone. */
public String getCurrentUserName() {
if (mUsers.isEmpty()) return null;
UserRecord item = mUsers.get(0);
if (item == null || item.info == null) return null;
if (item.isGuest) return context.getString(com.android.settingslib.R.string.guest_nickname);
if (item.isGuest) return mContext.getString(
com.android.settingslib.R.string.guest_nickname);
return item.info.name;
}

View File

@@ -42,7 +42,7 @@ import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.globalactions.GlobalActionsDialogLite;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.phone.MultiUserSwitch;
import com.android.systemui.statusbar.phone.MultiUserSwitchController;
import com.android.systemui.statusbar.phone.SettingsButton;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.UserInfoController;
@@ -90,7 +90,7 @@ public class QSFooterViewControllerTest extends LeakCheckedTest {
@Mock
private View mEdit;
@Mock
private MultiUserSwitch mMultiUserSwitch;
private MultiUserSwitchController mMultiUserSwitchController;
@Mock
private View mPowerMenuLiteView;
@Mock
@@ -116,12 +116,11 @@ public class QSFooterViewControllerTest extends LeakCheckedTest {
when(mView.findViewById(R.id.settings_button)).thenReturn(mSettingsButton);
when(mView.findViewById(R.id.build)).thenReturn(mBuildText);
when(mView.findViewById(android.R.id.edit)).thenReturn(mEdit);
when(mView.findViewById(R.id.multi_user_switch)).thenReturn(mMultiUserSwitch);
when(mView.findViewById(R.id.pm_lite)).thenReturn(mPowerMenuLiteView);
mController = new QSFooterViewController(mView, mUserManager, mUserInfoController,
mActivityStarter, mDeviceProvisionedController, mUserTracker, mQSPanelController,
new QSDetailDisplayer(), mQuickQSPanelController, mFakeTunerService,
mMultiUserSwitchController, mQuickQSPanelController, mFakeTunerService,
mMetricsLogger, new FalsingManagerFake(), false, mGlobalActionsDialog);
mController.init();