Merge "Refactored the UserRecyclerGridView to use PagedListView from the car support library.  This also surfaced a scrollbar. Additionally, added a touch ripple when you touch a user's picture and disabled the user buttons once a profile is selected" into pi-dev
diff --git a/packages/SystemUI/res/drawable/car_progress_bar.xml b/packages/SystemUI/res/drawable/car_progress_bar.xml
deleted file mode 100644
index 742fca7..0000000
--- a/packages/SystemUI/res/drawable/car_progress_bar.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<!--
-  Copyright (C) 2017 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
--->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:id="@android:id/background">
-        <shape>
-            <solid android:color="@color/car_user_switcher_progress_bgcolor" />
-        </shape>
-    </item>
-
-    <item android:id="@android:id/progress">
-        <clip>
-            <shape>
-                <solid android:color="@color/car_user_switcher_progress_fgcolor" />
-            </shape>
-        </clip>
-    </item>
-</layer-list>
diff --git a/packages/SystemUI/res/drawable/car_round_button.xml b/packages/SystemUI/res/drawable/car_round_button.xml
deleted file mode 100644
index 5f4deb3..0000000
--- a/packages/SystemUI/res/drawable/car_round_button.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
-  Copyright (C) 2017 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
--->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-
-    <solid android:color="@color/car_start_driving_background" />
-    <corners android:radius="@dimen/car_start_driving_corner_radius" />
-</shape>
diff --git a/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml b/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
index c59b067..3242165 100644
--- a/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
+++ b/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
@@ -22,14 +22,13 @@
     android:alpha="0"
     android:layout_height="wrap_content"
     android:layout_width="match_parent"
-    android:gravity="fill_horizontal"
-    android:layout_marginTop="@dimen/car_padding_5"
-    android:layout_marginStart="@dimen/car_padding_4">
+    android:gravity="fill_horizontal">
 
     <ImageView android:id="@+id/user_avatar"
         android:layout_centerHorizontal="true"
         android:layout_width="@dimen/car_fullscreen_user_pod_image_avatar_width"
         android:layout_height="@dimen/car_fullscreen_user_pod_image_avatar_height"
+        android:background="@drawable/car_button_ripple_background_inverse"
         />
 
     <TextView android:id="@+id/user_name"
diff --git a/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml b/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
index 27d0e46..d8b52fc 100644
--- a/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
+++ b/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
@@ -15,6 +15,7 @@
      limitations under the License.
 -->
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:app="http://schemas.android.com/apk/res-auto"
         android:fitsSystemWindows="true"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
@@ -31,34 +32,19 @@
             android:theme="@android:style/Theme"
             android:layout_alignParentTop="true"/>
 
-        <RelativeLayout
-            android:id="@+id/fullscreen_user_switcher_container"
-            android:layout_width="match_parent"
+        <!-- TODO: add app:verticallyCenterListContent="true" when car support lib is updated -->
+        <com.android.systemui.statusbar.car.UserGridRecyclerView
+            android:id="@+id/user_grid"
+            android:layout_width="wrap_content"
             android:layout_height="match_parent"
-            android:layout_marginStart="@dimen/car_margin"
-            android:layout_marginEnd="@dimen/car_margin">
-
-            <RelativeLayout
-                android:id="@+id/fullscreen_user_switcher_container_inner"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:layout_marginEnd="@dimen/car_padding_4">
-
-                <com.android.systemui.statusbar.car.UserGridRecyclerView
-                    android:id="@+id/user_grid"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_below="@+id/header"
-                    android:scrollbars="vertical"
-                    android:scrollbarFadeDuration="0"
-                    android:verticalScrollbarPosition="left"
-                    android:layout_centerHorizontal="true"
-                    android:layout_centerVertical="true"
-                    android:layout_alignParentRight="true"/>
-
-            </RelativeLayout>
-
-        </RelativeLayout>
+            android:layout_below="@+id/header"
+            android:layout_centerHorizontal="true"
+            android:layout_centerVertical="true"
+            android:layout_alignParentRight="true"
+            app:dayNightStyle="force_night"
+            app:showPagedListViewDivider="false"
+            app:gutter="both"
+            app:itemSpacing="@dimen/car_padding_5"/>
 
     </RelativeLayout>
 </FrameLayout>
diff --git a/packages/SystemUI/res/layout/car_qs_panel.xml b/packages/SystemUI/res/layout/car_qs_panel.xml
index c01bbce..9c2b95b 100644
--- a/packages/SystemUI/res/layout/car_qs_panel.xml
+++ b/packages/SystemUI/res/layout/car_qs_panel.xml
@@ -29,6 +29,7 @@
 
     <RelativeLayout
         xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:app="http://schemas.android.com/apk/res-auto"
         android:id="@+id/user_switcher_container"
         android:layout_marginStart="@dimen/car_margin"
         android:layout_marginEnd="@dimen/car_margin"
@@ -36,23 +37,17 @@
         android:layout_width="match_parent"
         android:layout_height="@dimen/car_user_switcher_container_height">
 
-        <RelativeLayout
-            android:id="@+id/fullscreen_user_switcher_container_inner"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_marginEnd="@dimen/car_padding_4">
-
-            <com.android.systemui.statusbar.car.UserGridRecyclerView
-                android:id="@+id/user_grid"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:scrollbars="vertical"
-                android:verticalScrollbarPosition="left"
-                android:layout_centerHorizontal="true"
-                android:layout_centerVertical="true"
-                android:layout_alignParentRight="true"
-                android:scrollbarFadeDuration="0"/>
-        </RelativeLayout>
+        <com.android.systemui.statusbar.car.UserGridRecyclerView
+            android:id="@+id/user_grid"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerHorizontal="true"
+            android:layout_centerVertical="true"
+            android:layout_alignParentRight="true"
+            app:dayNightStyle="force_night"
+            app:showPagedListViewDivider="false"
+            app:gutter="both"
+            app:itemSpacing="@dimen/car_padding_4"/>
 
     </RelativeLayout>
 
diff --git a/packages/SystemUI/res/values/dimens_car.xml b/packages/SystemUI/res/values/dimens_car.xml
index 0cd3825..6bc8e26 100644
--- a/packages/SystemUI/res/values/dimens_car.xml
+++ b/packages/SystemUI/res/values/dimens_car.xml
@@ -16,9 +16,6 @@
 */
 -->
 <resources>
-    <dimen name="car_margin">148dp</dimen>
-    <dimen name="car_margin_standard">112dp</dimen>
-
     <!-- TODO replace with car support lib sizes when available -->
     <dimen name="car_fullscreen_user_pod_icon_text_size">64sp</dimen>
     <dimen name="car_fullscreen_user_pod_width">243dp</dimen>
@@ -31,14 +28,6 @@
     <dimen name="car_left_navigation_bar_width">96dp</dimen>
     <dimen name="car_right_navigation_bar_width">96dp</dimen>
 
-    <dimen name="car_page_indicator_dot_diameter">12dp</dimen>
-    <dimen name="car_page_indicator_margin_bottom">24dp</dimen>
-
-    <dimen name="car_start_driving_corner_radius">16dp</dimen>
-    <dimen name="car_start_driving_padding_side">30dp</dimen>
-    <dimen name="car_start_driving_height">80dp</dimen>
-    <dimen name="car_start_driving_text_size">@dimen/car_body2_size</dimen>
-
     <dimen name="car_qs_footer_height">112dp</dimen>
     <dimen name="car_qs_footer_padding_bottom">16dp</dimen>
     <dimen name="car_qs_footer_padding_top">16dp</dimen>
diff --git a/packages/SystemUI/res/values/styles_car.xml b/packages/SystemUI/res/values/styles_car.xml
deleted file mode 100644
index 2aaef86..0000000
--- a/packages/SystemUI/res/values/styles_car.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (c) 2017, 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.
--->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
-    <style name="CarUserSwitcher.StartDrivingButton" parent="@android:style/Widget.Material.Button">
-        <item name="android:background">@drawable/car_round_button</item>
-        <item name="android:textSize">@dimen/car_start_driving_text_size</item>
-        <item name="android:textColor">@color/car_start_driving_text</item>
-        <item name="android:paddingLeft">@dimen/car_start_driving_padding_side</item>
-        <item name="android:paddingRight">@dimen/car_start_driving_padding_side</item>
-    </style>
-</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFragment.java
index da21aa5..608a236 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFragment.java
@@ -75,7 +75,7 @@
         mUserGridView = mUserSwitcherContainer.findViewById(R.id.user_grid);
         GridLayoutManager layoutManager = new GridLayoutManager(context,
                 context.getResources().getInteger(R.integer.user_fullscreen_switcher_num_col));
-        mUserGridView.setLayoutManager(layoutManager);
+        mUserGridView.getRecyclerView().setLayoutManager(layoutManager);
         mUserGridView.buildAdapter();
 
         mUserSwitchCallback = new UserSwitchCallback();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
index c1af1fa..6cb80c0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
@@ -23,7 +23,6 @@
 import android.view.ViewStub;
 
 import android.support.v7.widget.GridLayoutManager;
-import android.support.v7.widget.RecyclerView;
 
 import com.android.settingslib.users.UserManagerHelper;
 import com.android.systemui.R;
@@ -49,7 +48,7 @@
         mUserGridView = mContainer.findViewById(R.id.user_grid);
         GridLayoutManager layoutManager = new GridLayoutManager(context,
                 context.getResources().getInteger(R.integer.user_fullscreen_switcher_num_col));
-        mUserGridView.setLayoutManager(layoutManager);
+        mUserGridView.getRecyclerView().setLayoutManager(layoutManager);
         mUserGridView.buildAdapter();
         mUserGridView.setUserSelectionListener(this::onUserSelected);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
index 5006a2c..41b70f8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
@@ -16,19 +16,12 @@
 
 package com.android.systemui.statusbar.car;
 
-import android.app.ActivityManager;
 import android.content.Context;
 import android.content.pm.UserInfo;
+import android.content.res.ColorStateList;
 import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Paint.Align;
-import android.graphics.drawable.GradientDrawable;
 import android.os.AsyncTask;
-import android.support.annotation.Nullable;
 import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerView.ViewHolder;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -36,6 +29,8 @@
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import androidx.car.widget.PagedListView;
+
 import com.android.settingslib.users.UserManagerHelper;
 import com.android.systemui.R;
 
@@ -46,7 +41,7 @@
  * Displays a GridLayout with icons for the users in the system to allow switching between users.
  * One of the uses of this is for the lock screen in auto.
  */
-public class UserGridRecyclerView extends RecyclerView implements
+public class UserGridRecyclerView extends PagedListView implements
         UserManagerHelper.OnUsersUpdateListener {
     private UserSelectionListener mUserSelectionListener;
     private UserAdapter mAdapter;
@@ -55,7 +50,6 @@
 
     public UserGridRecyclerView(Context context, AttributeSet attrs) {
         super(context, attrs);
-        super.setHasFixedSize(true);
         mContext = context;
         mUserManagerHelper = new UserManagerHelper(mContext);
     }
@@ -65,6 +59,7 @@
      */
     @Override
     public void onFinishInflate() {
+        super.onFinishInflate();
         mUserManagerHelper.registerOnUsersUpdateListener(this);
     }
 
@@ -73,6 +68,7 @@
      */
     @Override
     public void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
         mUserManagerHelper.unregisterOnUsersUpdateListener();
     }
 
@@ -152,8 +148,6 @@
 
         private final Context mContext;
         private List<UserRecord> mUsers;
-        private final int mPodImageAvatarWidth;
-        private final int mPodImageAvatarHeight;
         private final Resources mRes;
         private final String mGuestName;
         private final String mNewUserName;
@@ -162,10 +156,6 @@
             mRes = context.getResources();
             mContext = context;
             updateUsers(users);
-            mPodImageAvatarWidth = mRes.getDimensionPixelSize(
-                    R.dimen.car_fullscreen_user_pod_image_avatar_width);
-            mPodImageAvatarHeight = mRes.getDimensionPixelSize(
-                    R.dimen.car_fullscreen_user_pod_image_avatar_height);
             mGuestName = mRes.getString(R.string.car_guest);
             mNewUserName = mRes.getString(R.string.car_new_user);
         }
@@ -190,13 +180,22 @@
         @Override
         public void onBindViewHolder(UserAdapterViewHolder holder, int position) {
             UserRecord userRecord = mUsers.get(position);
-            holder.mUserAvatarImageView.setImageBitmap(getDefaultUserIcon(userRecord));
+            if (!userRecord.mIsAddUser) {
+                holder.mUserAvatarImageView.setImageBitmap(mUserManagerHelper
+                        .getUserIcon(userRecord.mInfo));
+            } else {
+                holder.mUserAvatarImageView.setImageDrawable(mContext
+                        .getDrawable(R.drawable.ic_add_circle_qs));
+            }
             holder.mUserNameTextView.setText(userRecord.mInfo.name);
             holder.mView.setOnClickListener(v -> {
                 if (userRecord == null) {
                     return;
                 }
 
+                // Disable button so it cannot be clicked multiple times
+                holder.mView.setEnabled(false);
+
                 // Notify the listener which user was selected
                 if (mUserSelectionListener != null) {
                     mUserSelectionListener.onUserSelected(userRecord);
@@ -244,57 +243,6 @@
             return mUsers.size();
         }
 
-        /**
-         * Returns the default user icon.  This icon is a circle with a letter in it.  The letter is
-         * the first character in the username.
-         *
-         * @param record the profile of the user for which the icon should be created
-         */
-        private Bitmap getDefaultUserIcon(UserRecord record) {
-            CharSequence displayText;
-            boolean isAddUserText = false;
-            if (record.mIsAddUser) {
-                displayText = "+";
-                isAddUserText = true;
-            } else {
-                displayText = record.mInfo.name.subSequence(0, 1);
-            }
-            Bitmap out = Bitmap.createBitmap(mPodImageAvatarWidth, mPodImageAvatarHeight,
-                    Bitmap.Config.ARGB_8888);
-            Canvas canvas = new Canvas(out);
-
-            // Draw the circle background.
-            GradientDrawable shape = new GradientDrawable();
-            shape.setShape(GradientDrawable.RADIAL_GRADIENT);
-            shape.setGradientRadius(1.0f);
-            shape.setColor(mContext.getColor(R.color.car_grey_50));
-            shape.setBounds(0, 0, mPodImageAvatarWidth, mPodImageAvatarHeight);
-            shape.draw(canvas);
-
-            // Draw the letter in the center.
-            Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
-            paint.setColor(mContext.getColor(R.color.car_grey_900));
-            paint.setTextAlign(Align.CENTER);
-            if (isAddUserText) {
-                paint.setTextSize(mRes.getDimensionPixelSize(
-                        R.dimen.car_touch_target_size));
-            } else {
-                paint.setTextSize(mRes.getDimensionPixelSize(
-                        R.dimen.car_fullscreen_user_pod_icon_text_size));
-            }
-
-            Paint.FontMetricsInt metrics = paint.getFontMetricsInt();
-            // The Y coordinate is measured by taking half the height of the pod, but that would
-            // draw the character putting the bottom of the font in the middle of the pod.  To
-            // correct this, half the difference between the top and bottom distance metrics of the
-            // font gives the offset of the font.  Bottom is a positive value, top is negative, so
-            // the different is actually a sum.  The "half" operation is then factored out.
-            canvas.drawText(displayText.toString(), mPodImageAvatarWidth / 2,
-                    (mPodImageAvatarHeight - (metrics.bottom + metrics.top)) / 2, paint);
-
-            return out;
-        }
-
         public class UserAdapterViewHolder extends RecyclerView.ViewHolder {
 
             public ImageView mUserAvatarImageView;
diff --git a/services/core/java/com/android/server/am/CarUserSwitchingDialog.java b/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
index e34ee63..676f0c7 100644
--- a/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
+++ b/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
@@ -20,17 +20,16 @@
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
-import android.graphics.Canvas;
+import android.graphics.BitmapFactory;
 import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Paint.Align;
 import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.GradientDrawable;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.TextView;
 import com.android.internal.R;
+import com.android.server.pm.UserManagerService;
+import java.io.FileDescriptor;
 
 /**
  * Dialog to show when a user switch it about to happen for the car. The intent is to snapshot the
@@ -60,54 +59,13 @@
         View view = LayoutInflater.from(getContext()).inflate(R.layout.car_user_switching_dialog,
             null);
 
+        FileDescriptor fileDescriptor = UserManagerService.getInstance()
+                .getUserIcon(mNewUser.id).getFileDescriptor();
+        Bitmap bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);
         ((ImageView) view.findViewById(R.id.user_loading_avatar))
-            .setImageBitmap(getDefaultUserIcon(mNewUser));
+            .setImageBitmap(bitmap);
         ((TextView) view.findViewById(R.id.user_loading))
             .setText(res.getString(R.string.car_loading_profile));
         setView(view);
     }
-
-    /**
-     * Returns the default user icon.  This icon is a circle with a letter in it.  The letter is
-     * the first character in the username.
-     *
-     * @param userInfo the profile of the user for which the icon should be created
-     */
-    private Bitmap getDefaultUserIcon(UserInfo userInfo) {
-        Resources res = mContext.getResources();
-        int mPodImageAvatarWidth = res.getDimensionPixelSize(
-            R.dimen.car_fullscreen_user_pod_image_avatar_width);
-        int mPodImageAvatarHeight = res.getDimensionPixelSize(
-            R.dimen.car_fullscreen_user_pod_image_avatar_height);
-        CharSequence displayText = userInfo.name.subSequence(0, 1);
-        Bitmap out = Bitmap.createBitmap(mPodImageAvatarWidth, mPodImageAvatarHeight,
-            Bitmap.Config.ARGB_8888);
-        Canvas canvas = new Canvas(out);
-
-        // Draw the circle background.
-        GradientDrawable shape = new GradientDrawable();
-        shape.setShape(GradientDrawable.RADIAL_GRADIENT);
-        shape.setGradientRadius(1.0f);
-        shape.setColor(mContext.getColor(R.color.car_user_switcher_user_image_bgcolor));
-        shape.setBounds(0, 0, mPodImageAvatarWidth, mPodImageAvatarHeight);
-        shape.draw(canvas);
-
-        // Draw the letter in the center.
-        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
-        paint.setColor(mContext.getColor(R.color.car_user_switcher_user_image_fgcolor));
-        paint.setTextAlign(Align.CENTER);
-        paint.setTextSize(res.getDimensionPixelSize(
-            R.dimen.car_fullscreen_user_pod_icon_text_size));
-
-        Paint.FontMetricsInt metrics = paint.getFontMetricsInt();
-        // The Y coordinate is measured by taking half the height of the pod, but that would
-        // draw the character putting the bottom of the font in the middle of the pod.  To
-        // correct this, half the difference between the top and bottom distance metrics of the
-        // font gives the offset of the font.  Bottom is a positive value, top is negative, so
-        // the different is actually a sum.  The "half" operation is then factored out.
-        canvas.drawText(displayText.toString(), mPodImageAvatarWidth / 2,
-            (mPodImageAvatarHeight - (metrics.bottom + metrics.top)) / 2, paint);
-
-        return out;
-    }
 }