Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aca19ed5 authored by Dave Mankoff's avatar Dave Mankoff
Browse files

Add falsing check to MultiUserSwitch

Adds MultiUserSwitchController, and perform falsing check
when it is tapped on.

Bug: 186244907
Test: atest SystemUITests && manual
Change-Id: I257fd3914f3d304e94cdd493b18fd24ffe7459d1
parent 59ea1a09
Loading
Loading
Loading
Loading
+11 −10
Original line number Diff line number Diff line
@@ -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) {
+15 −11
Original line number Diff line number Diff line
@@ -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() {
+7 −0
Original line number Diff line number Diff line
@@ -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) {
+2 −108
Original line number Diff line number Diff line
@@ -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;
    }
}
+131 −0
Original line number Diff line number Diff line
/*
 * 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)));
    }

}
Loading