Merge "Add DeviceName and account to initial paring description"
diff --git a/nearby/halfsheet/res/drawable/fast_pair_ic_info.xml b/nearby/halfsheet/res/drawable/fast_pair_ic_info.xml
new file mode 100644
index 0000000..cc514e5
--- /dev/null
+++ b/nearby/halfsheet/res/drawable/fast_pair_ic_info.xml
@@ -0,0 +1,24 @@
+<!--
+  ~ 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.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <path
+        android:fillColor="@color/fast_pair_half_sheet_subtitle_color"
+        android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z"/>
+</vector>
\ No newline at end of file
diff --git a/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/FastPairUtils.java b/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/FastPairUtils.java
index 00cd11d..ee869ba 100644
--- a/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/FastPairUtils.java
+++ b/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/FastPairUtils.java
@@ -34,6 +34,8 @@
  */
 public class FastPairUtils {
 
+    public static final String TAG = "HalfSheetActivity";
+
     /** FastPair util method check certain app is install on the device or not. */
     public static boolean isAppInstalled(String packageName, Context context) {
         try {
diff --git a/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/IconUtils.java b/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/IconUtils.java
new file mode 100644
index 0000000..0521b7b
--- /dev/null
+++ b/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/IconUtils.java
@@ -0,0 +1,133 @@
+/*
+ * 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.
+ */
+
+package com.android.nearby.halfsheet.utils;
+
+import static com.android.nearby.halfsheet.utils.FastPairUtils.TAG;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.util.Log;
+
+import androidx.annotation.Nullable;
+import androidx.core.graphics.ColorUtils;
+
+/**
+ * Utility class for icon size verification.
+ */
+public class IconUtils {
+
+    private static final float NOTIFICATION_BACKGROUND_PADDING_PERCENT = 0.125f;
+    private static final float NOTIFICATION_BACKGROUND_ALPHA = 0.7f;
+    private static final int MIN_ICON_SIZE = 16;
+    private static final int DESIRED_ICON_SIZE = 32;
+
+    /**
+     * Verify that the icon is non null and falls in the small bucket. Just because an icon isn't
+     * small doesn't guarantee it is large or exists.
+     */
+    public static boolean isIconSizedSmall(@Nullable Bitmap bitmap) {
+        if (bitmap == null) {
+            return false;
+        }
+        return bitmap.getWidth() >= MIN_ICON_SIZE
+                && bitmap.getWidth() < DESIRED_ICON_SIZE
+                && bitmap.getHeight() >= MIN_ICON_SIZE
+                && bitmap.getHeight() < DESIRED_ICON_SIZE;
+    }
+
+    /**
+     * Verify that the icon is non null and falls in the regular / default size bucket. Doesn't
+     * guarantee if not regular then it is small.
+     */
+    static boolean isIconSizedRegular(@Nullable Bitmap bitmap) {
+        if (bitmap == null) {
+            return false;
+        }
+        return bitmap.getWidth() >= DESIRED_ICON_SIZE && bitmap.getHeight() >= DESIRED_ICON_SIZE;
+    }
+
+    /**
+     * All icons that are sized correctly (larger than the MIN_ICON_SIZE icon size)
+     * are resize on the server to the DESIRED_ICON_SIZE icon size so that
+     * they appear correct.
+     */
+    public static boolean isIconSizeCorrect(@Nullable Bitmap bitmap) {
+        if (bitmap == null) {
+            return false;
+        }
+        return isIconSizedSmall(bitmap) || isIconSizedRegular(bitmap);
+    }
+
+    /**
+     * Returns the bitmap from the byte array. Returns null if cannot decode or not in correct size.
+     */
+    @Nullable
+    public static Bitmap getIcon(byte[] imageData, int size) {
+        try {
+            Bitmap icon =
+                    BitmapFactory.decodeByteArray(imageData, /* offset= */ 0, size);
+            if (IconUtils.isIconSizeCorrect(icon)) {
+                // Do not add background for Half Sheet.
+                return IconUtils.addWhiteCircleBackground(icon);
+            }
+        } catch (OutOfMemoryError e) {
+            Log.w(TAG, "getIcon: Failed to decode icon, returning null.", e);
+        }
+        return null;
+    }
+
+    /** Adds a circular, white background to the bitmap. */
+    @Nullable
+    public static Bitmap addWhiteCircleBackground(Bitmap bitmap) {
+        if (bitmap == null) {
+            Log.w(TAG, "addWhiteCircleBackground: Bitmap is null, not adding background.");
+            return null;
+        }
+
+        if (bitmap.getWidth() != bitmap.getHeight()) {
+            Log.w(TAG, "addWhiteCircleBackground: Bitmap dimensions not square. Skipping"
+                    + "adding background.");
+            return bitmap;
+        }
+
+        int padding = (int) (bitmap.getWidth() * NOTIFICATION_BACKGROUND_PADDING_PERCENT);
+        Bitmap bitmapWithBackground =
+                Bitmap.createBitmap(
+                        bitmap.getWidth() + (2 * padding),
+                        bitmap.getHeight() + (2 * padding),
+                        bitmap.getConfig());
+        Canvas canvas = new Canvas(bitmapWithBackground);
+        Paint paint = new Paint();
+        paint.setColor(
+                ColorUtils.setAlphaComponent(
+                        Color.WHITE, (int) (255 * NOTIFICATION_BACKGROUND_ALPHA)));
+        paint.setStyle(Paint.Style.FILL);
+        paint.setAntiAlias(true);
+        canvas.drawCircle(
+                bitmapWithBackground.getWidth() / 2,
+                bitmapWithBackground.getHeight() / 2,
+                bitmapWithBackground.getWidth() / 2,
+                paint);
+        canvas.drawBitmap(bitmap, padding, padding, null);
+
+        return bitmapWithBackground;
+    }
+}
+
diff --git a/nearby/service/java/com/android/server/nearby/provider/FastPairDataProvider.java b/nearby/service/java/com/android/server/nearby/provider/FastPairDataProvider.java
index 40fefaf..03484a0 100644
--- a/nearby/service/java/com/android/server/nearby/provider/FastPairDataProvider.java
+++ b/nearby/service/java/com/android/server/nearby/provider/FastPairDataProvider.java
@@ -56,7 +56,7 @@
             sInstance = new FastPairDataProvider(context);
         }
         if (sInstance.mProxyFastPairDataProvider == null) {
-            Log.wtf(TAG, "no proxy fast pair data provider found");
+            Log.w(TAG, "no proxy fast pair data provider found");
         } else {
             sInstance.mProxyFastPairDataProvider.register();
         }
diff --git a/nearby/tests/cts/fastpair/Android.bp b/nearby/tests/cts/fastpair/Android.bp
index 56dc682..9cbd7d0 100644
--- a/nearby/tests/cts/fastpair/Android.bp
+++ b/nearby/tests/cts/fastpair/Android.bp
@@ -39,5 +39,6 @@
     ],
     platform_apis: true,
     sdk_version: "module_current",
-    min_sdk_version: "32",
+    min_sdk_version: "30",
+    target_sdk_version: "32",
 }
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/CredentialElementTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/CredentialElementTest.java
index 19a4a40..aacb6d8 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/CredentialElementTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/CredentialElementTest.java
@@ -25,6 +25,7 @@
 
 import androidx.annotation.RequiresApi;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -38,6 +39,7 @@
     private static final byte[] VALUE = new byte[]{1, 2, 3, 4};
 
     @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
     public void testBuilder() {
         CredentialElement element = new CredentialElement(KEY, VALUE);
 
@@ -46,6 +48,7 @@
     }
 
     @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
     public void testWriteParcel() {
         CredentialElement element = new CredentialElement(KEY, VALUE);
 
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/DataElementTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/DataElementTest.java
index eb03a0d..ec6e89a 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/DataElementTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/DataElementTest.java
@@ -24,6 +24,7 @@
 
 import androidx.annotation.RequiresApi;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -39,6 +40,7 @@
     private static final byte[] VALUE = new byte[]{1, 1, 1, 1};
 
     @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
     public void testBuilder() {
         DataElement dataElement = new DataElement(KEY, VALUE);
 
@@ -47,6 +49,7 @@
     }
 
     @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
     public void testWriteParcel() {
         DataElement dataElement = new DataElement(KEY, VALUE);
 
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyManagerTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyManagerTest.java
index f32ef12..938eab2 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyManagerTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyManagerTest.java
@@ -35,6 +35,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -66,6 +67,7 @@
     }
 
     @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
     public void test_startAndStopScan() {
         ScanRequest scanRequest = new ScanRequest.Builder()
                 .setScanType(ScanRequest.SCAN_TYPE_FAST_PAIR)
@@ -92,6 +94,7 @@
     }
 
     @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
     public void testStartStopBroadcast() {
         PrivateCredential credential = new PrivateCredential.Builder(SECRETE_ID, AUTHENTICITY_KEY)
                 .setIdentityType(IDENTITY_TYPE_PRIVATE)
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceBroadcastRequestTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceBroadcastRequestTest.java
index a37cc67..67d5aa4 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceBroadcastRequestTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceBroadcastRequestTest.java
@@ -30,6 +30,7 @@
 
 import androidx.annotation.RequiresApi;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -74,6 +75,7 @@
     }
 
     @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
     public void testBuilder() {
         PresenceBroadcastRequest broadcastRequest = mBuilder.build();
 
@@ -90,6 +92,7 @@
     }
 
     @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
     public void testWriteParcel() {
         PresenceBroadcastRequest broadcastRequest = mBuilder.build();
 
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceDeviceTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceDeviceTest.java
index a1b282d..e0d9200 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceDeviceTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceDeviceTest.java
@@ -26,6 +26,7 @@
 
 import androidx.annotation.RequiresApi;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -52,6 +53,7 @@
     private static final long DISCOVERY_MILLIS = 100L;
 
     @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
     public void testBuilder() {
         PresenceDevice device = new PresenceDevice.Builder()
                 .setDeviceType(DEVICE_TYPE)
@@ -83,6 +85,7 @@
     }
 
     @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
     public void testWriteParcel() {
         PresenceDevice device = new PresenceDevice.Builder()
                 .setDeviceId(DEVICE_ID)
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceScanFilterTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceScanFilterTest.java
index 308be9e..6b7c43b 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceScanFilterTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceScanFilterTest.java
@@ -29,6 +29,7 @@
 
 import androidx.annotation.RequiresApi;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -63,6 +64,7 @@
             .addExtendedProperty(new DataElement(KEY, VALUE));
 
     @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
     public void testBuilder() {
         PresenceScanFilter filter = mBuilder.build();
 
@@ -75,6 +77,7 @@
     }
 
     @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
     public void testWriteParcel() {
         PresenceScanFilter filter = mBuilder.build();
 
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/PrivateCredentialTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/PrivateCredentialTest.java
index 5242999..1cd6d9c 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/PrivateCredentialTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/PrivateCredentialTest.java
@@ -28,6 +28,7 @@
 
 import androidx.annotation.RequiresApi;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -60,6 +61,7 @@
     }
 
     @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
     public void testBuilder() {
         PrivateCredential credential = mBuilder.build();
 
@@ -76,6 +78,7 @@
     }
 
     @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
     public void testWriteParcel() {
         PrivateCredential credential = mBuilder.build();
 
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/PublicCredentialTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/PublicCredentialTest.java
index f750951..7756669 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/PublicCredentialTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/PublicCredentialTest.java
@@ -29,6 +29,7 @@
 
 import androidx.annotation.RequiresApi;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -63,6 +64,7 @@
     }
 
     @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
     public void testBuilder() {
         PublicCredential credential = mBuilder.build();
 
@@ -78,6 +80,7 @@
     }
 
     @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
     public void testWriteParcel() {
         PublicCredential credential = mBuilder.build();