blob: 6104599e878627049ead1d1d0ccb83340b33b4d4 [file] [log] [blame]
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07001/*
2 * Copyright (C) 2015 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
Rakesh Iyer2790a372016-01-22 15:33:39 -080017package com.android.systemui.statusbar.car;
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -070018
Rakesh Iyer33d6ce42017-05-30 11:02:18 -070019import android.animation.Animator;
20import android.animation.AnimatorListenerAdapter;
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -070021import android.content.Context;
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -070022import android.view.View;
23import android.view.ViewStub;
Rakesh Iyer97ff8582017-05-22 17:47:52 -070024import android.widget.ProgressBar;
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -070025
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -070026import android.support.v7.widget.GridLayoutManager;
27import android.support.v7.widget.RecyclerView;
jovanakb8030512018-04-11 15:20:16 -070028
29import com.android.settingslib.users.UserManagerHelper;
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -070030import com.android.systemui.R;
Jason Monk2a6ea9c2017-01-26 11:14:51 -050031import com.android.systemui.statusbar.phone.StatusBar;
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -070032
33/**
34 * Manages the fullscreen user switcher.
35 */
36public class FullscreenUserSwitcher {
Rakesh Iyer97ff8582017-05-22 17:47:52 -070037 private final View mContainer;
Rakesh Iyer33d6ce42017-05-30 11:02:18 -070038 private final View mParent;
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -070039 private final UserGridRecyclerView mUserGridView;
Rakesh Iyer33d6ce42017-05-30 11:02:18 -070040 private final ProgressBar mSwitchingUsers;
Rakesh Iyer33d6ce42017-05-30 11:02:18 -070041 private final int mShortAnimDuration;
jovanak0535abc2018-04-10 15:14:50 -070042 private final StatusBar mStatusBar;
jovanakb8030512018-04-11 15:20:16 -070043 private final UserManagerHelper mUserManagerHelper;
44 private int mCurrentForegroundUserId;
Rakesh Iyer33d6ce42017-05-30 11:02:18 -070045 private boolean mShowing;
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -070046
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -070047 public FullscreenUserSwitcher(StatusBar statusBar, ViewStub containerStub, Context context) {
jovanak0535abc2018-04-10 15:14:50 -070048 mStatusBar = statusBar;
Rakesh Iyer33d6ce42017-05-30 11:02:18 -070049 mParent = containerStub.inflate();
50 mContainer = mParent.findViewById(R.id.container);
Rakesh Iyer5b3278f2017-04-19 11:28:26 -070051 mUserGridView = mContainer.findViewById(R.id.user_grid);
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -070052 GridLayoutManager layoutManager = new GridLayoutManager(context,
53 context.getResources().getInteger(R.integer.user_fullscreen_switcher_num_col));
54 mUserGridView.setLayoutManager(layoutManager);
55 mUserGridView.buildAdapter();
jovanak0535abc2018-04-10 15:14:50 -070056 mUserGridView.setUserSelectionListener(this::onUserSelected);
Rakesh Iyer5b3278f2017-04-19 11:28:26 -070057
jovanakb8030512018-04-11 15:20:16 -070058 mUserManagerHelper = new UserManagerHelper(context);
59 updateCurrentForegroundUser();
60
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -070061 mShortAnimDuration = mContainer.getResources()
62 .getInteger(android.R.integer.config_shortAnimTime);
Rakesh Iyer33d6ce42017-05-30 11:02:18 -070063
64 mSwitchingUsers = mParent.findViewById(R.id.switching_users);
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -070065 }
66
jovanak0535abc2018-04-10 15:14:50 -070067 public void show() {
68 if (mShowing) {
69 return;
70 }
71 mShowing = true;
72 mParent.setVisibility(View.VISIBLE);
73 }
74
75 public void hide() {
76 mShowing = false;
77 toggleSwitchInProgress(false);
78 mParent.setVisibility(View.GONE);
79 }
80
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -070081 public void onUserSwitched(int newUserId) {
jovanakb8030512018-04-11 15:20:16 -070082 // The logic for foreground user change is needed here to exclude the reboot case. On
83 // reboot, system fires ACTION_USER_SWITCHED change from -1 to 0 user. This is not an actual
84 // user switch. We only want to trigger keyguard dismissal when foreground user changes.
85 if (foregroundUserChanged()) {
86 updateCurrentForegroundUser();
87 mParent.post(this::dismissKeyguard);
88 }
89 }
90
91 private boolean foregroundUserChanged() {
92 return mCurrentForegroundUserId != mUserManagerHelper.getForegroundUserId();
93 }
94
95 private void updateCurrentForegroundUser() {
96 mCurrentForegroundUserId = mUserManagerHelper.getForegroundUserId();
jovanak0535abc2018-04-10 15:14:50 -070097 }
98
99 private void onUserSelected(UserGridRecyclerView.UserRecord record) {
100 if (record.mIsForeground) {
jovanakb8030512018-04-11 15:20:16 -0700101 dismissKeyguard();
jovanak0535abc2018-04-10 15:14:50 -0700102 return;
103 }
104 toggleSwitchInProgress(true);
105 }
106
jovanakb8030512018-04-11 15:20:16 -0700107 // Dismisses the keyguard and shows bouncer if authentication is necessary.
108 private void dismissKeyguard() {
jovanak0535abc2018-04-10 15:14:50 -0700109 mStatusBar.executeRunnableDismissingKeyguard(null/* runnable */, null /* cancelAction */,
110 true /* dismissShade */, true /* afterKeyguardGone */, true /* deferred */);
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -0700111 }
112
Rakesh Iyer33d6ce42017-05-30 11:02:18 -0700113 private void toggleSwitchInProgress(boolean inProgress) {
114 if (inProgress) {
115 crossFade(mSwitchingUsers, mContainer);
116 } else {
117 crossFade(mContainer, mSwitchingUsers);
118 }
119 }
120
121 private void crossFade(View incoming, View outgoing) {
122 incoming.animate()
123 .alpha(1.0f)
124 .setDuration(mShortAnimDuration)
125 .setListener(new AnimatorListenerAdapter() {
126 @Override
127 public void onAnimationStart(Animator animator) {
128 incoming.setAlpha(0.0f);
129 incoming.setVisibility(View.VISIBLE);
130 }
131 });
132
133 outgoing.animate()
134 .alpha(0.0f)
135 .setDuration(mShortAnimDuration)
136 .setListener(new AnimatorListenerAdapter() {
137 @Override
138 public void onAnimationEnd(Animator animation) {
139 outgoing.setVisibility(View.GONE);
140 }
141 });
142 }
Rakesh Iyer97ff8582017-05-22 17:47:52 -0700143}