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

Commit 33d6ce4c authored by Rakesh Iyer's avatar Rakesh Iyer
Browse files

Fix up user switch flow a little.

- Remove the long click listeners since the deletion flow wasn't
  very discoverable or good anyway. Deletion is better accomplished
  in settings.
- The lock screen shows up immediately after user switch and gets
  called to be shown quite a few times in not very deterministic
  order. Now, we replace the user grid view with an infinite progress
  bar while the switch is in progress so it looks more natural.
- Switch the background to solid black like in the mocks.

Note that this does not fix the case of the lock screen showing up
briefly when switching using the notification shade. That will be
cleaned up when we replace that view with the UserGridView.

Test: Rebooted and verified lock screen still works fine.
Bug: 36454400
Change-Id: I19ad8e9305d93a069294e910998749f1f0386b5b
parent 14c991cf
Loading
Loading
Loading
Loading
+49 −32
Original line number Diff line number Diff line
@@ -14,12 +14,28 @@
     See the License for the specific language governing permissions and
     limitations under the License.
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:fitsSystemWindows="true"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/black"
        android:visibility="gone">

    <!-- This progressbar is activated while we're switching users. -->
    <ProgressBar
        android:id="@+id/switching_users"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:indeterminate="true"
        android:visibility="gone"
        android:layout_gravity="center" />

    <RelativeLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <!-- This progress bar is the countdown timer. -->
        <ProgressBar
            android:id="@+id/countdown_progress"
            android:layout_width="match_parent"
@@ -52,3 +68,4 @@
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true" />
    </RelativeLayout>
</FrameLayout>
+62 −3
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.systemui.statusbar.car;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.res.Resources;
import android.os.CountDownTimer;
import android.view.View;
@@ -31,11 +33,16 @@ import com.android.systemui.statusbar.policy.UserSwitcherController;
 */
public class FullscreenUserSwitcher {
    private final View mContainer;
    private final View mParent;
    private final UserGridView mUserGridView;
    private final UserSwitcherController mUserSwitcherController;
    private final ProgressBar mProgressBar;
    private final ProgressBar mSwitchingUsers;
    private final int mLoginTimeoutMs;
    private final int mAnimUpdateIntervalMs;
    private final int mShortAnimDuration;

    private boolean mShowing;

    private CountDownTimer mTimer;

@@ -43,9 +50,15 @@ public class FullscreenUserSwitcher {
            UserSwitcherController userSwitcherController,
            ViewStub containerStub) {
        mUserSwitcherController = userSwitcherController;
        mContainer = containerStub.inflate();
        mParent = containerStub.inflate();
        mContainer = mParent.findViewById(R.id.container);
        mUserGridView = mContainer.findViewById(R.id.user_grid);
        mUserGridView.init(statusBar, mUserSwitcherController);
        mUserGridView.setUserSelectionListener(record -> {
            if (!record.isCurrent) {
                toggleSwitchInProgress(true);
            }
        });

        PageIndicator pageIndicator = mContainer.findViewById(R.id.user_switcher_page_indicator);
        pageIndicator.setupWithViewPager(mUserGridView);
@@ -54,20 +67,64 @@ public class FullscreenUserSwitcher {
        Resources res = mContainer.getResources();
        mLoginTimeoutMs = res.getInteger(R.integer.car_user_switcher_timeout_ms);
        mAnimUpdateIntervalMs = res.getInteger(R.integer.car_user_switcher_anim_update_ms);
        mShortAnimDuration = res.getInteger(android.R.integer.config_shortAnimTime);

        mContainer.findViewById(R.id.start_driving).setOnClickListener(v -> {
            cancelTimer();
            automaticallySelectUser();
        });

        mSwitchingUsers = mParent.findViewById(R.id.switching_users);
    }

    public void onUserSwitched(int newUserId) {
        mUserGridView.onUserSwitched(newUserId);
    }

    private void toggleSwitchInProgress(boolean inProgress) {
        if (inProgress) {
            crossFade(mSwitchingUsers, mContainer);
        } else {
            crossFade(mContainer, mSwitchingUsers);
        }
    }

    private void crossFade(View incoming, View outgoing) {
        incoming.animate()
            .alpha(1.0f)
            .setDuration(mShortAnimDuration)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationStart(Animator animator) {
                    incoming.setAlpha(0.0f);
                    incoming.setVisibility(View.VISIBLE);
                }
            });

        outgoing.animate()
            .alpha(0.0f)
            .setDuration(mShortAnimDuration)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    outgoing.setVisibility(View.GONE);
                }
            });
    }

    public void show() {
        mContainer.setVisibility(View.VISIBLE);
        if (mShowing) {
            return;
        }
        mShowing = true;
        mParent.setVisibility(View.VISIBLE);
        cancelTimer();

        // This would be the case if we were in the middle of a switch.
        if (mProgressBar.getVisibility() != View.VISIBLE) {
            return;
        }

        mTimer = new CountDownTimer(mLoginTimeoutMs, mAnimUpdateIntervalMs) {
            @Override
            public void onTick(long msUntilFinished) {
@@ -85,8 +142,10 @@ public class FullscreenUserSwitcher {
    }

    public void hide() {
        mShowing = false;
        cancelTimer();
        mContainer.setVisibility(View.GONE);
        toggleSwitchInProgress(false);
        mParent.setVisibility(View.GONE);
    }

    private void cancelTimer() {
+27 −39
Original line number Diff line number Diff line
@@ -17,11 +17,12 @@
package com.android.systemui.statusbar.car;

import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
@@ -30,6 +31,7 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.android.internal.util.UserIcons;
import com.android.systemui.R;
import com.android.systemui.statusbar.UserUtil;
import com.android.systemui.statusbar.phone.StatusBar;
@@ -43,7 +45,7 @@ public class UserGridView extends ViewPager {
    private StatusBar mStatusBar;
    private UserSwitcherController mUserSwitcherController;
    private Adapter mAdapter;
    private int mPendingUserId = UserHandle.USER_NULL;
    private UserSelectionListener mUserSelectionListener;

    public UserGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
@@ -58,16 +60,12 @@ public class UserGridView extends ViewPager {
    }

    public void onUserSwitched(int newUserId) {
        if (mPendingUserId == newUserId) {
        // Bring up security view after user switch is completed.
            post(new Runnable() {
                @Override
                public void run() {
                    showOfflineAuthUi();
        post(this::showOfflineAuthUi);
    }
            });
        }
        mPendingUserId = UserHandle.USER_NULL;

    public void setUserSelectionListener(UserSelectionListener userSelectionListener) {
        mUserSelectionListener = userSelectionListener;
    }

    void showOfflineAuthUi() {
@@ -136,15 +134,19 @@ public class UserGridView extends ViewPager {
            for (int i = position * iconsPerPage; i < limit; i++) {
                pods.addView(makeUserPod(inflater, context, i, pods));
            }

            // Dynamic parameters since we specify the weightsum dynamically.
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT, limit);
            container.addView(pods, params);
            container.addView(pods);
            return pods;
        }

        private Drawable getUserIcon(Context context, UserSwitcherController.UserRecord record) {
            if (record.isAddUser) {
                Drawable icon = context.getDrawable(R.drawable.ic_add_circle_qs);
                icon.setTint(Color.WHITE);
                return icon;
            }
            return UserIcons.getDefaultUserIcon(record.resolveId(), /* light= */ true);
        }

        private View makeUserPod(LayoutInflater inflater, Context context,
                int position, ViewGroup parent) {
            final UserSwitcherController.UserRecord record = mUserAdapter.getItem(position);
@@ -160,45 +162,27 @@ public class UserGridView extends ViewPager {

            ImageView iconView = (ImageView) view.findViewById(R.id.user_avatar);
            if (record == null || record.picture == null) {
                iconView.setImageDrawable(mUserAdapter.getDrawable(context, record));
                iconView.setImageDrawable(getUserIcon(context, record));
            } else {
                iconView.setImageBitmap(record.picture);
            }

            iconView.setOnClickListener(v -> {
                mPendingUserId = UserHandle.USER_NULL;
                if (record == null) {
                    return;
                }

                if (record.isGuest || record.isAddUser) {
                    mUserSwitcherController.switchTo(record);
                    return;
                if (mUserSelectionListener != null) {
                    mUserSelectionListener.onUserSelected(record);
                }

                if (record.isCurrent) {
                    showOfflineAuthUi();
                } else {
                    mPendingUserId = record.info.id;
                    mUserSwitcherController.switchTo(record);
                }
            });

            iconView.setOnLongClickListener(v -> {
                if (record == null || record.isAddUser) {
                    return false;
                }
                if (record.isGuest) {
                    if (record.isCurrent) {
                        mUserSwitcherController.switchTo(record);
                    }
                    return true;
                }
                UserUtil.deleteUserWithPrompt(getContext(), record.info.id,
                        mUserSwitcherController);
                return true;
            });

            return view;
        }

@@ -247,4 +231,8 @@ public class UserGridView extends ViewPager {
            mContainer.notifyDataSetChanged();
        }
    }

    interface UserSelectionListener {
        void onUserSelected(UserSwitcherController.UserRecord record);
    };
}