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

Commit 28aca0a1 authored by Adrian Roos's avatar Adrian Roos Committed by Android Git Automerger
Browse files

am 29c97b8d: Update KeyguardUserSwitcher to use UserSwitcherController

* commit '29c97b8d23cd1b8174e19c13484f9f355d6356d8':
  Update KeyguardUserSwitcher to use UserSwitcherController
parents e587677d 723632ea
Loading
Loading
Loading
Loading
+19 −3
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ import android.view.View;
import android.widget.FrameLayout;

import com.android.systemui.qs.QSPanel;
import com.android.systemui.qs.tiles.UserDetailView;
import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;

/**
 * Container for image of the multi user switcher (tappable).
@@ -34,6 +34,8 @@ import com.android.systemui.qs.tiles.UserDetailView;
public class MultiUserSwitch extends FrameLayout implements View.OnClickListener {

    private QSPanel mQsPanel;
    private KeyguardUserSwitcher mKeyguardUserSwitcher;
    private boolean mKeyguardMode;

    public MultiUserSwitch(Context context, AttributeSet attrs) {
        super(context, attrs);
@@ -49,12 +51,26 @@ public class MultiUserSwitch extends FrameLayout implements View.OnClickListener
        mQsPanel = qsPanel;
    }

    public void setKeyguardUserSwitcher(KeyguardUserSwitcher keyguardUserSwitcher) {
        mKeyguardUserSwitcher = keyguardUserSwitcher;
    }

    public void setKeyguardMode(boolean keyguardShowing) {
        mKeyguardMode = keyguardShowing;
    }

    @Override
    public void onClick(View v) {
        final UserManager um = UserManager.get(getContext());
        if (um.isUserSwitcherEnabled()) {
            if (mKeyguardMode) {
                if (mKeyguardUserSwitcher != null) {
                    mKeyguardUserSwitcher.show();
                }
            } else {
                mQsPanel.showDetailAdapter(true,
                        mQsPanel.getHost().getUserSwitcherController().userDetailAdapter);
            }
        } else {
            Intent intent = ContactsContract.QuickContact.composeQuickContactsIntent(
                    getContext(), v, ContactsContract.Profile.CONTENT_URI,
+5 −3
Original line number Diff line number Diff line
@@ -737,9 +737,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
        final SignalClusterView signalCluster =
                (SignalClusterView)mStatusBarView.findViewById(R.id.signal_cluster);

        mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext,
                (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_user_switcher), mHeader);

        mNetworkController.addSignalCluster(signalCluster);
        signalCluster.setNetworkController(mNetworkController);
        final boolean isAPhone = mNetworkController.hasVoiceCallingFeature();
@@ -775,6 +772,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
        mUserSwitcherController = new UserSwitcherController(mContext);
        mKeyguardMonitor = new KeyguardMonitor();

        mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext,
                (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_user_switcher), mHeader,
                mUserSwitcherController);


        // Set up the quick settings tile panel
        mQSPanel = (QSPanel) mStatusBarWindow.findViewById(R.id.quick_settings_panel);
        if (mQSPanel != null) {
+12 −2
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import com.android.systemui.R;
import com.android.systemui.qs.QSPanel;
import com.android.systemui.qs.QSTile;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
import com.android.systemui.statusbar.policy.UserInfoController;

/**
@@ -97,6 +98,7 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
    private ActivityStarter mActivityStarter;
    private BatteryController mBatteryController;
    private QSPanel mQSPanel;
    private boolean mHasKeyguardUserSwitcher;

    private final Rect mClipBounds = new Rect();
    private final StatusIconClipper mStatusIconClipper = new StatusIconClipper();
@@ -373,7 +375,11 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
    private void updateClickTargets() {
        setClickable(!mKeyguardShowing || mExpanded);
        mDateTime.setClickable(mExpanded);
        mMultiUserSwitch.setClickable(mExpanded);

        boolean keyguardSwitcherAvailable =
                mHasKeyguardUserSwitcher && mKeyguardShowing && !mExpanded;
        mMultiUserSwitch.setClickable(mExpanded || keyguardSwitcherAvailable);
        mMultiUserSwitch.setKeyguardMode(keyguardSwitcherAvailable);
        mSystemIconsSuperContainer.setClickable(mExpanded);
    }

@@ -509,6 +515,11 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
        mMultiUserSwitch.setQsPanel(qsp);
    }

    public void setKeyguarUserSwitcher(KeyguardUserSwitcher keyguardUserSwitcher) {
        mHasKeyguardUserSwitcher = true;
        mMultiUserSwitch.setKeyguardUserSwitcher(keyguardUserSwitcher);
    }

    @Override
    public boolean shouldDelayChildPressedState() {
        return true;
@@ -522,7 +533,6 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
    }

    public void setKeyguardUserSwitcherShowing(boolean showing) {
        // STOPSHIP: NOT CALLED PROPERLY WHEN GOING TO FULL SHADE AND RETURNING!?!
        mKeyguardUserSwitcherShowing = showing;
        updateVisibilities();
        updateSystemIconsLayoutParams();
+77 −120
Original line number Diff line number Diff line
@@ -16,62 +16,56 @@

package com.android.systemui.statusbar.policy;

import com.android.systemui.BitmapHelper;
import com.android.systemui.R;
import com.android.systemui.statusbar.phone.StatusBarHeaderView;
import com.android.systemui.statusbar.phone.UserAvatarView;

import android.app.ActivityManagerNative;
import android.content.Context;
import android.content.pm.UserInfo;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.RemoteException;
import android.os.UserManager;
import android.util.Log;
import android.database.DataSetObserver;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.view.WindowManagerGlobal;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

/**
 * Manages the user switcher on the Keyguard.
 */
public class KeyguardUserSwitcher implements View.OnClickListener {
public class KeyguardUserSwitcher {

    private static final String TAG = "KeyguardUserSwitcher";
    private static final boolean ALWAYS_ON = false;
    private static final String SIMPLE_USER_SWITCHER_GLOBAL_SETTING =
            "lockscreenSimpleUserSwitcher";

    private final Context mContext;
    private final ViewGroup mUserSwitcher;
    private final UserManager mUserManager;
    private final StatusBarHeaderView mHeader;
    private final Adapter mAdapter;
    private final boolean mSimpleUserSwitcher;

    public KeyguardUserSwitcher(Context context, ViewStub userSwitcher,
            StatusBarHeaderView header) {
        mContext = context;
        if (context.getResources().getBoolean(R.bool.config_keyguardUserSwitcher)) {
            StatusBarHeaderView header, UserSwitcherController userSwitcherController) {
        if (context.getResources().getBoolean(R.bool.config_keyguardUserSwitcher) || ALWAYS_ON) {
            mUserSwitcher = (ViewGroup) userSwitcher.inflate();
            mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
            mHeader = header;
            refresh();
            mHeader.setKeyguarUserSwitcher(this);
            mAdapter = new Adapter(context, userSwitcherController);
            mAdapter.registerDataSetObserver(mDataSetObserver);
            mSimpleUserSwitcher = Settings.Global.getInt(context.getContentResolver(),
                    SIMPLE_USER_SWITCHER_GLOBAL_SETTING, 0) != 0;
        } else {
            mUserSwitcher = null;
            mUserManager = null;
            mHeader = null;
            mAdapter = null;
            mSimpleUserSwitcher = false;
        }
    }

    public void setKeyguard(boolean keyguard) {
        if (mUserSwitcher != null) {
            // TODO: Cache showUserSwitcherOnKeyguard().
            if (keyguard && showUserSwitcherOnKeyguard()) {
            if (keyguard && shouldExpandByDefault()) {
                show();
                refresh();
            } else {
                hide();
            }
@@ -79,24 +73,11 @@ public class KeyguardUserSwitcher implements View.OnClickListener {
    }

    /**
     * @return true if the user switcher should be shown on the lock screen.
     * @return true if the user switcher should be expanded by default on the lock screen.
     * @see android.os.UserManager#isUserSwitcherEnabled()
     */
    private boolean showUserSwitcherOnKeyguard() {
        // TODO: Set isEdu. The edu provisioning process can add settings to Settings.Global.
        boolean isEdu = false;
        if (isEdu) {
            return true;
        }
        List<UserInfo> users = mUserManager.getUsers(true /* excludeDying */);
        int N = users.size();
        int switchableUsers = 0;
        for (int i = 0; i < N; i++) {
            if (users.get(i).supportsSwitchTo()) {
                switchableUsers++;
            }
        }
        return switchableUsers > 1;
    private boolean shouldExpandByDefault() {
        return mSimpleUserSwitcher || mAdapter.getSwitchableUsers() > 1;
    }

    public void show() {
@@ -116,100 +97,76 @@ public class KeyguardUserSwitcher implements View.OnClickListener {
    }

    private void refresh() {
        if (mUserSwitcher != null) {
            new AsyncTask<Void, Void, ArrayList<UserData>>() {
                @Override
                protected ArrayList<UserData> doInBackground(Void... params) {
                    return loadUsers();
                }

                @Override
                protected void onPostExecute(ArrayList<UserData> userInfos) {
                    bind(userInfos);
                }
            }.execute((Void[]) null);
        }
    }

    private void bind(ArrayList<UserData> userList) {
        mUserSwitcher.removeAllViews();
        int N = userList.size();
        final int childCount = mUserSwitcher.getChildCount();
        final int adapterCount = mAdapter.getCount();
        final int N = Math.max(childCount, adapterCount);
        for (int i = 0; i < N; i++) {
            mUserSwitcher.addView(inflateUser(userList.get(i)));
        }
        // TODO: add Guest
        // TODO: add (+) button
            if (i < adapterCount) {
                View oldView = null;
                if (i < childCount) {
                    oldView = mUserSwitcher.getChildAt(i);
                }
                View newView = mAdapter.getView(i, oldView, mUserSwitcher);
                if (oldView == null) {
                    // We ran out of existing views. Add it at the end.
                    mUserSwitcher.addView(newView);
                } else if (oldView != newView) {
                    // We couldn't rebind the view. Replace it.
                    mUserSwitcher.removeViewAt(i);
                    mUserSwitcher.addView(newView, i);
                }

    private View inflateUser(UserData user) {
        View v = LayoutInflater.from(mUserSwitcher.getContext()).inflate(
                R.layout.keyguard_user_switcher_item, mUserSwitcher, false);
        TextView name = (TextView) v.findViewById(R.id.name);
        UserAvatarView picture = (UserAvatarView) v.findViewById(R.id.picture);
        name.setText(user.userInfo.name);
        picture.setActivated(user.isCurrent);
        if (user.userInfo.isGuest()) {
            picture.setDrawable(mContext.getResources().getDrawable(R.drawable.ic_account_circle));
            } else {
            picture.setBitmap(user.userIcon);
                int lastIndex = mUserSwitcher.getChildCount() - 1;
                mUserSwitcher.removeViewAt(lastIndex);
            }
        }
        v.setOnClickListener(this);
        v.setTag(user.userInfo);
        // TODO: mark which user is current for accessibility.
        return v;
    }

    public final DataSetObserver mDataSetObserver = new DataSetObserver() {
        @Override
    public void onClick(View v) {
        switchUser(((UserInfo)v.getTag()).id);
        public void onChanged() {
            refresh();
        }
    };

    // TODO: Factor out logic below and share with QS implementation.
    public static class Adapter extends UserSwitcherController.BaseUserAdapter implements
            View.OnClickListener {

    private ArrayList<UserData> loadUsers() {
        ArrayList<UserInfo> users = (ArrayList<UserInfo>) mUserManager
                .getUsers(true /* excludeDying */);
        int N = users.size();
        ArrayList<UserData> result = new ArrayList<>(N);
        int currentUser = -1;
        try {
            currentUser = ActivityManagerNative.getDefault().getCurrentUser().id;
        } catch (RemoteException e) {
            Log.e(TAG, "Couln't get current user.", e);
        }
        final int avatarSize
                = mContext.getResources().getDimensionPixelSize(R.dimen.max_avatar_size);
        for (int i = 0; i < N; i++) {
            UserInfo user = users.get(i);
            if (user.supportsSwitchTo()) {
                boolean isCurrent = user.id == currentUser;
                final Bitmap picture = BitmapHelper.createCircularClip(
                        mUserManager.getUserIcon(user.id),
                        avatarSize, avatarSize);
                result.add(new UserData(user, picture, isCurrent));
            }
        private Context mContext;

        public Adapter(Context context, UserSwitcherController controller) {
            super(controller);
            mContext = context;
        }
        return result;

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            UserSwitcherController.UserRecord item = getItem(position);

            if (convertView == null
                    || !(convertView.getTag() instanceof UserSwitcherController.UserRecord)) {
                convertView = LayoutInflater.from(mContext).inflate(
                        R.layout.keyguard_user_switcher_item, parent, false);
                convertView.setOnClickListener(this);
            }

    private void switchUser(int userId) {
        try {
            WindowManagerGlobal.getWindowManagerService().lockNow(null);
            ActivityManagerNative.getDefault().switchUser(userId);
        } catch (RemoteException e) {
            Log.e(TAG, "Couldn't switch user.", e);
            TextView nameView = (TextView) convertView.findViewById(R.id.name);
            UserAvatarView pictureView = (UserAvatarView) convertView.findViewById(R.id.picture);

            nameView.setText(getName(mContext, item));
            if (item.picture == null) {
                pictureView.setDrawable(mContext.getDrawable(R.drawable.ic_account_circle_qs));
            } else {
                pictureView.setBitmap(item.picture);
            }
            convertView.setActivated(item.isCurrent);
            convertView.setTag(item);
            return convertView;
        }

    private static class UserData {
        final UserInfo userInfo;
        final Bitmap userIcon;
        final boolean isCurrent;

        UserData(UserInfo userInfo, Bitmap userIcon, boolean isCurrent) {
            this.userInfo = userInfo;
            this.userIcon = userIcon;
            this.isCurrent = isCurrent;
        @Override
        public void onClick(View v) {
            switchTo(((UserSwitcherController.UserRecord)v.getTag()));
        }
    }
}
+13 −1
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ public class UserSwitcherController {
                    if (info.isGuest()) {
                        guestRecord = new UserRecord(info, null /* picture */,
                                true /* isGuest */, isCurrent);
                    } else if (!info.isManagedProfile()) {
                    } else if (info.supportsSwitchTo()) {
                        Bitmap picture = bitmaps.get(info.id);
                        if (picture == null) {
                            picture = mUserManager.getUserIcon(info.id);
@@ -303,6 +303,18 @@ public class UserSwitcherController {
                return item.info.name;
            }
        }

        public int getSwitchableUsers() {
            int result = 0;
            ArrayList<UserRecord> users = mController.mUsers;
            int N = users.size();
            for (int i = 0; i < N; i++) {
                if (users.get(i).info != null) {
                    result++;
                }
            }
            return result;
        }
    }

    public static final class UserRecord {