Loading packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml +49 −32 Original line number Diff line number Diff line Loading @@ -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" Loading Loading @@ -52,3 +68,4 @@ android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" /> </RelativeLayout> </FrameLayout> packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java +62 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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); Loading @@ -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) { Loading @@ -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() { Loading packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridView.java +27 −39 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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); Loading @@ -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() { Loading Loading @@ -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); Loading @@ -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; } Loading Loading @@ -247,4 +231,8 @@ public class UserGridView extends ViewPager { mContainer.notifyDataSetChanged(); } } interface UserSelectionListener { void onUserSelected(UserSwitcherController.UserRecord record); }; } Loading
packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml +49 −32 Original line number Diff line number Diff line Loading @@ -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" Loading Loading @@ -52,3 +68,4 @@ android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" /> </RelativeLayout> </FrameLayout>
packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java +62 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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); Loading @@ -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) { Loading @@ -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() { Loading
packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridView.java +27 −39 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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); Loading @@ -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() { Loading Loading @@ -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); Loading @@ -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; } Loading Loading @@ -247,4 +231,8 @@ public class UserGridView extends ViewPager { mContainer.notifyDataSetChanged(); } } interface UserSelectionListener { void onUserSelected(UserSwitcherController.UserRecord record); }; }