Add BT and WIFI icon for mutiple devices UI

Add BT and WIFI icon for mutiple devices ui.
Also highlight the selected item.

Test: atest CtsCompanionDeviceManagerUiAutomationTestCases:AssociationEndToEndTest
BUG: 211417476
Change-Id: I7edc2ff8734dbe440c803a8d8ab473487f383826
diff --git a/packages/CompanionDeviceManager/Android.bp b/packages/CompanionDeviceManager/Android.bp
index 0e60873..6ded1637 100644
--- a/packages/CompanionDeviceManager/Android.bp
+++ b/packages/CompanionDeviceManager/Android.bp
@@ -39,6 +39,7 @@
     static_libs: [
         "androidx.lifecycle_lifecycle-livedata",
         "androidx.lifecycle_lifecycle-extensions",
+        "androidx.recyclerview_recyclerview",
         "androidx.appcompat_appcompat",
     ],
 
diff --git a/packages/CompanionDeviceManager/res/color/selector.xml b/packages/CompanionDeviceManager/res/color/selector.xml
new file mode 100644
index 0000000..fda827d
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/color/selector.xml
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright (C) 2022 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.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:color="@android:color/darker_gray"/> <!-- pressed -->
+    <item android:color="@android:color/white"/>
+</selector>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml b/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
index 313e164..70cbfdf 100644
--- a/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
+++ b/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
@@ -49,8 +49,8 @@
             android:layout_height="0dp"
             android:layout_weight="1">
 
-        <ListView
-                android:id="@+id/device_list"
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/device_list"
                 style="@android:style/Widget.Material.ListView"
                 android:layout_width="match_parent"
                 android:layout_height="200dp" />
diff --git a/packages/CompanionDeviceManager/res/layout/list_item_device.xml b/packages/CompanionDeviceManager/res/layout/list_item_device.xml
index d79aea6..153fc1f 100644
--- a/packages/CompanionDeviceManager/res/layout/list_item_device.xml
+++ b/packages/CompanionDeviceManager/res/layout/list_item_device.xml
@@ -19,7 +19,8 @@
               android:layout_height="wrap_content"
               android:orientation="horizontal"
               android:gravity="center_vertical"
-              android:padding="12dp">
+              android:padding="12dp"
+              android:background="@color/selector">
 
     <!-- Do NOT change the ID of the root LinearLayout above: it's referenced in CTS tests. -->
 
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
index 16e851b..b51d310 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
@@ -46,10 +46,11 @@
 import android.util.Log;
 import android.view.View;
 import android.widget.Button;
-import android.widget.ListView;
 import android.widget.TextView;
 
 import androidx.appcompat.app.AppCompatActivity;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
 
 import java.util.List;
 
@@ -94,9 +95,9 @@
     // regular.
     private Button mButtonAllow;
 
-    // The list is only shown for multiple-device regular association request, after at least one
-    // matching device is found.
-    private @Nullable ListView mListView;
+    // The recycler view is only shown for multiple-device regular association request, after
+    // at least one matching device is found.
+    private @Nullable RecyclerView mRecyclerView;
     private @Nullable DeviceListAdapter mAdapter;
 
     // The flag used to prevent double taps, that may lead to sending several requests for creating
@@ -195,14 +196,15 @@
         mTitle = findViewById(R.id.title);
         mSummary = findViewById(R.id.summary);
 
-        mListView = findViewById(R.id.device_list);
-        mListView.setOnItemClickListener((av, iv, position, id) -> onListItemClick(position));
+        mRecyclerView = findViewById(R.id.device_list);
+        mAdapter = new DeviceListAdapter(this, this::onListItemClick);
 
         mButtonAllow = findViewById(R.id.btn_positive);
         mButtonAllow.setOnClickListener(this::onPositiveButtonClick);
         findViewById(R.id.btn_negative).setOnClickListener(this::onNegativeButtonClick);
 
         final CharSequence appLabel = getApplicationLabel(this, mRequest.getPackageName());
+
         if (mRequest.isSelfManaged()) {
             initUiForSelfManagedAssociation(appLabel);
         } else if (mRequest.isSingleDevice()) {
@@ -333,7 +335,7 @@
         mTitle.setText(title);
         mSummary.setText(summary);
 
-        mListView.setVisibility(View.GONE);
+        mRecyclerView.setVisibility(View.GONE);
     }
 
     private void initUiForSingleDevice(CharSequence appLabel) {
@@ -345,12 +347,12 @@
                 deviceFilterPairs -> updateSingleDeviceUi(
                         deviceFilterPairs, deviceProfile, appLabel));
 
-        mListView.setVisibility(View.GONE);
+        mRecyclerView.setVisibility(View.GONE);
     }
 
     private void updateSingleDeviceUi(List<DeviceFilterPair<?>> deviceFilterPairs,
             String deviceProfile, CharSequence appLabel) {
-        // Ignore "empty" scan repots.
+        // Ignore "empty" scan reports.
         if (deviceFilterPairs.isEmpty()) return;
         mSelectedDevice = requireNonNull(deviceFilterPairs.get(0));
 
@@ -393,10 +395,12 @@
         mTitle.setText(title);
         mSummary.setText(summary);
 
-        mAdapter = new DeviceListAdapter(this);
+        mAdapter = new DeviceListAdapter(this, this::onListItemClick);
 
         // TODO: hide the list and show a spinner until a first device matching device is found.
-        mListView.setAdapter(mAdapter);
+        mRecyclerView.setAdapter(mAdapter);
+        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
+
         CompanionDeviceDiscoveryService.getScanResult().observe(
                 /* lifecycleOwner */ this,
                 /* observer */ mAdapter);
@@ -414,6 +418,8 @@
             if (DEBUG) Log.w(TAG, "Already selected.");
             return;
         }
+        // Notify the adapter to highlight the selected item.
+        mAdapter.setSelectedPosition(position);
 
         mSelectedDevice = requireNonNull(selectedDevice);
 
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java
index 198b778..e5513b0 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java
@@ -15,73 +15,84 @@
  */
 
 package com.android.companiondevicemanager;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.BaseAdapter;
 import android.widget.ImageView;
 import android.widget.TextView;
 
 import androidx.lifecycle.Observer;
+import androidx.recyclerview.widget.RecyclerView;
 
 import java.util.List;
-
 /**
  * Adapter for the list of "found" devices.
  */
-class DeviceListAdapter extends BaseAdapter implements Observer<List<DeviceFilterPair<?>>> {
+class DeviceListAdapter extends RecyclerView.Adapter<DeviceListAdapter.ViewHolder> implements
+        Observer<List<DeviceFilterPair<?>>> {
+    public int mSelectedPosition = RecyclerView.NO_POSITION;
+
     private final Context mContext;
 
     // List if pairs (display name, address)
     private List<DeviceFilterPair<?>> mDevices;
 
-    DeviceListAdapter(Context context) {
+    private OnItemClickListener mListener;
+
+    private static final int TYPE_WIFI = 0;
+    private static final int TYPE_BT = 1;
+
+    DeviceListAdapter(Context context, OnItemClickListener listener) {
         mContext = context;
+        mListener = listener;
     }
 
-    @Override
-    public int getCount() {
-        return mDevices != null ? mDevices.size() : 0;
-    }
-
-    @Override
     public DeviceFilterPair<?> getItem(int position) {
         return mDevices.get(position);
     }
 
     @Override
+    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+        View view = LayoutInflater.from(parent.getContext()).inflate(
+                R.layout.list_item_device, parent, false);
+        ViewHolder viewHolder = new ViewHolder(view);
+        if (viewType == TYPE_WIFI) {
+            viewHolder.mImageView.setImageDrawable(getIcon(
+                    com.android.internal.R.drawable.ic_wifi_signal_3));
+        } else {
+            viewHolder.mImageView.setImageDrawable(getIcon(
+                    android.R.drawable.stat_sys_data_bluetooth));
+        }
+        return viewHolder;
+    }
+
+    @Override
+    public void onBindViewHolder(ViewHolder holder, int position) {
+        holder.itemView.setSelected(mSelectedPosition == position);
+        holder.mTextView.setText(mDevices.get(position).getDisplayName());
+        holder.itemView.setOnClickListener(v -> mListener.onItemClick(position));
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        return isWifiDevice(position) ? TYPE_WIFI : TYPE_BT;
+    }
+
+    @Override
     public long getItemId(int position) {
         return position;
     }
 
     @Override
-    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
-        final View view = convertView != null
-                ? convertView
-                : LayoutInflater.from(mContext).inflate(R.layout.list_item_device, parent, false);
-
-        final DeviceFilterPair<?> item = getItem(position);
-        bindView(view, item);
-
-        return view;
+    public int getItemCount() {
+        return mDevices != null ? mDevices.size() : 0;
     }
 
-    private void bindView(@NonNull View view, DeviceFilterPair<?> item) {
-        final TextView textView = view.findViewById(android.R.id.text1);
-        textView.setText(item.getDisplayName());
-
-        final ImageView iconView = view.findViewById(android.R.id.icon);
-
-        // TODO(b/211417476): Set either Bluetooth or WiFi icon.
-        iconView.setVisibility(View.GONE);
-        // final int iconRes = isBt ? android.R.drawable.stat_sys_data_bluetooth
-        //        : com.android.internal.R.drawable.ic_wifi_signal_3;
-        // final Drawable icon = getTintedIcon(mResources, iconRes);
-        // iconView.setImageDrawable(icon);
+    public void setSelectedPosition(int position) {
+        mSelectedPosition = position;
     }
 
     @Override
@@ -89,4 +100,28 @@
         mDevices = deviceFilterPairs;
         notifyDataSetChanged();
     }
+
+    static class ViewHolder extends RecyclerView.ViewHolder {
+        private TextView mTextView;
+        private ImageView mImageView;
+        ViewHolder(View itemView) {
+            super(itemView);
+            mTextView = itemView.findViewById(android.R.id.text1);
+            mImageView = itemView.findViewById(android.R.id.icon);
+        }
+    }
+
+    private boolean isWifiDevice(int position) {
+        return mDevices.get(position).getDevice() instanceof android.net.wifi.ScanResult;
+    }
+
+    private Drawable getIcon(int resId) {
+        Drawable icon = mContext.getResources().getDrawable(resId, null);
+        icon.setTint(Color.DKGRAY);
+        return icon;
+    }
+
+    public interface OnItemClickListener {
+        void onItemClick(int position);
+    }
 }