Merge "Add APIs for Presence Broadcast."
diff --git a/nearby/framework/java/android/nearby/NearbyDeviceParcelable.java b/nearby/framework/java/android/nearby/NearbyDeviceParcelable.java
index 0f85519..3b0a776 100644
--- a/nearby/framework/java/android/nearby/NearbyDeviceParcelable.java
+++ b/nearby/framework/java/android/nearby/NearbyDeviceParcelable.java
@@ -60,6 +60,9 @@
                         builder.setFastPairModelId(in.readString());
                     }
                     if (in.readInt() == 1) {
+                        builder.setBluetoothAddress(in.readString());
+                    }
+                    if (in.readInt() == 1) {
                         int dataLength = in.readInt();
                         byte[] data = new byte[dataLength];
                         in.readByteArray(data);
@@ -125,7 +128,7 @@
             dest.writeString(mFastPairModelId);
         }
         dest.writeInt(mBluetoothAddress == null ? 0 : 1);
-        if (mFastPairModelId != null) {
+        if (mBluetoothAddress != null) {
             dest.writeString(mBluetoothAddress);
         }
         dest.writeInt(mData == null ? 0 : 1);
diff --git a/nearby/halfsheet/Android.bp b/nearby/halfsheet/Android.bp
index 3f4f258..2b35254 100644
--- a/nearby/halfsheet/Android.bp
+++ b/nearby/halfsheet/Android.bp
@@ -16,45 +16,42 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
-java_defaults {
-    name: "HalfSheetDefaults",
+android_app {
+    name: "HalfSheetUX",
+    defaults: ["platform_app_defaults"],
     srcs: ["src/**/*.java"],
     sdk_version: "module_current",
     // This is included in tethering apex, which uses min SDK 30
     min_sdk_version: "30",
     target_sdk_version: "current",
-    manifest: "AndroidManifest.xml",
-    plugins: ["java_api_finder"],
-    jarjar_rules: ":nearby-jarjar-rules",
+    updatable: true,
+    certificate: ":com.android.nearby.halfsheetcertificate",
     libs: [
         "framework-bluetooth",
         "framework-connectivity-tiramisu",
         "nearby-service-string",
-      ],
+    ],
     static_libs: [
         "androidx.annotation_annotation",
         "androidx.fragment_fragment",
         "androidx-constraintlayout_constraintlayout",
         "androidx.localbroadcastmanager_localbroadcastmanager",
+        "androidx.core_core",
+        "androidx.appcompat_appcompat",
+        "androidx.recyclerview_recyclerview",
+        "androidx.lifecycle_lifecycle-runtime",
+        "androidx.lifecycle_lifecycle-extensions",
+        "com.google.android.material_material",
         "fast-pair-lite-protos",
     ],
-    lint: { strict_updatability_linting: true }
-}
-
-android_app {
-    name: "HalfSheetUX",
-    defaults: ["HalfSheetDefaults"],
-    resource_dirs: ["res"],
-    certificate: ":com.android.nearby.halfsheetcertificate",
-    updatable: true,
-    static_libs: [
-        "com.google.android.material_material",
-    ],
+    plugins: ["java_api_finder"],
+    manifest: "AndroidManifest.xml",
+    jarjar_rules: ":nearby-jarjar-rules",
     apex_available: ["com.android.tethering",],
+    lint: { strict_updatability_linting: true }
 }
 
 android_app_certificate {
     name: "com.android.nearby.halfsheetcertificate",
     certificate: "apk-certs/com.android.nearby.halfsheet"
 }
-
diff --git a/nearby/halfsheet/AndroidManifest.xml b/nearby/halfsheet/AndroidManifest.xml
index 3e8b39b..22987fb 100644
--- a/nearby/halfsheet/AndroidManifest.xml
+++ b/nearby/halfsheet/AndroidManifest.xml
@@ -15,17 +15,17 @@
   ~ limitations under the License.
   -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
     package="com.android.nearby.halfsheet">
-    <application android:label="@string/app_name">
+    <application>
         <activity
             android:name="com.android.nearby.halfsheet.HalfSheetActivity"
-            android:exported="true">
+            android:exported="true"
+            android:launchMode="singleInstance"
+            android:theme="@style/HalfSheetStyle" >
             <intent-filter>
                 <action android:name="android.nearby.SHOW_HALFSHEET"/>
                 <category android:name="android.intent.category.DEFAULT"/>
             </intent-filter>
         </activity>
     </application>
-
-</manifest>
\ No newline at end of file
+</manifest>
diff --git a/nearby/halfsheet/res/layout/activity_half_sheet.xml b/nearby/halfsheet/res/layout/activity_half_sheet.xml
deleted file mode 100644
index 4915d4b..0000000
--- a/nearby/halfsheet/res/layout/activity_half_sheet.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    xmlns:tools="http://schemas.android.com/tools"
-    xmlns:app="http://schemas.android.com/apk/res-auto">
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:orientation="vertical" >
-
-        <TextView
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="abc half sheet" />
-    </LinearLayout>
-
-</FrameLayout>
-
diff --git a/nearby/halfsheet/res/layout/fast_pair_app_launch_fragment.xml b/nearby/halfsheet/res/layout/fast_pair_app_launch_fragment.xml
deleted file mode 100644
index ad321b2..0000000
--- a/nearby/halfsheet/res/layout/fast_pair_app_launch_fragment.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<android.support.v7.widget.LinearLayoutCompat
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:orientation="vertical"
-    android:layout_width="match_parent" android:layout_height="match_parent">
-
-  <android.support.constraint.ConstraintLayout
-      android:id="@+id/image_view"
-      android:layout_width="match_parent"
-      android:layout_height="340dp"
-      android:paddingStart="12dp"
-      android:paddingEnd="12dp"
-      android:paddingTop="12dp">
-    <TextView
-        android:id="@+id/header_subtitle"
-        android:textColor="@color/fast_pair_half_sheet_subtitle_color"
-        android:fontFamily="google-sans"
-        android:textSize="14sp"
-        android:gravity="center"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toEndOf="parent" />
-
-    <ImageView
-        android:id="@+id/pairing_pic"
-        android:layout_width="@dimen/fast_pair_half_sheet_image_size"
-        android:layout_height="@dimen/fast_pair_half_sheet_image_size"
-        android:paddingTop="18dp"
-        android:paddingBottom="18dp"
-        android:importantForAccessibility="no"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toBottomOf="@+id/header_subtitle" />
-
-    <Button
-        android:id="@+id/connect_btn"
-        android:text="@string/fast_pair_app_launch_button"
-        android:layout_height="@dimen/fast_pair_connect_button_height"
-        android:layout_width="@dimen/fast_pair_half_sheet_image_size"
-        android:background="@color/fast_pair_half_sheet_button_color"
-        android:paddingTop="6dp"
-        android:paddingBottom="6dp"
-        app:layout_constraintTop_toBottomOf="@+id/pairing_pic"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        style="@style/HalfSheetButton" />
-
-  </android.support.constraint.ConstraintLayout>
-
-</android.support.v7.widget.LinearLayoutCompat>
diff --git a/nearby/halfsheet/res/values/strings.xml b/nearby/halfsheet/res/values/strings.xml
index a3a2b00..12e3c23 100644
--- a/nearby/halfsheet/res/values/strings.xml
+++ b/nearby/halfsheet/res/values/strings.xml
@@ -15,7 +15,7 @@
   -->
 
 <resources>
-    <string name="app_name">Nearby HalfSheet Dialog</string>
+
     <string name="common_done" description="After pairing process finish button text to dismiss halfsheet">Done</string>
     <string name="common_save">Save</string>
     <string name="common_connect" description="Button text to start connecting process">Connect</string>
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java b/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java
index 672d785..db2d69f 100644
--- a/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java
+++ b/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java
@@ -70,9 +70,6 @@
      */
     public void handleBroadcast(NearbyDevice device) {
         FastPairDevice fastPairDevice = (FastPairDevice) device;
-        if (mBleAddress != null && mBleAddress.equals(fastPairDevice.getBluetoothAddress())) {
-            return;
-        }
         mBleAddress = fastPairDevice.getBluetoothAddress();
         if (FastPairDecoder.checkModelId(fastPairDevice.getData())) {
             byte[] model = FastPairDecoder.getModelId(fastPairDevice.getData());
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManager.java b/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManager.java
index 9fdd01a..cfac904 100644
--- a/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManager.java
+++ b/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManager.java
@@ -48,6 +48,8 @@
  */
 public class FastPairHalfSheetManager {
     private static final String ACTIVITY_INTENT_ACTION = "android.nearby.SHOW_HALFSHEET";
+    private static final String HALF_SHEET_CLASS_NAME =
+            "com.android.nearby.halfsheet.HalfSheetActivity";
 
     private String mHalfSheetApkPkgName;
     private Context mContext;
@@ -65,22 +67,28 @@
      * app can't get the correct component name.
      */
     public void showHalfSheet(Cache.ScanFastPairStoreItem scanFastPairStoreItem) {
-        if (mContext != null) {
-            String packageName = getHalfSheetApkPkgName();
-            HalfSheetCallback callback = new HalfSheetCallback();
-            callback.setmFastPairController(Locator.get(mContext, FastPairController.class));
-            Bundle bundle = new Bundle();
-            bundle.putBinder(EXTRA_BINDER, callback);
-            mContext
-                    .startActivityAsUser(new Intent(ACTIVITY_INTENT_ACTION)
-                                    .putExtra(EXTRA_HALF_SHEET_INFO,
-                                            scanFastPairStoreItem.toByteArray())
-                                    .putExtra(EXTRA_HALF_SHEET_TYPE, DEVICE_PAIRING_FRAGMENT_TYPE)
-                                    .putExtra(EXTRA_BUNDLE, bundle)
-                                    .setComponent(new ComponentName(packageName,
-                                            packageName + ".HalfSheetActivity")),
-                            UserHandle.CURRENT);
+        try {
+            if (mContext != null) {
+                String packageName = getHalfSheetApkPkgName();
+                HalfSheetCallback callback = new HalfSheetCallback();
+                callback.setmFastPairController(Locator.get(mContext, FastPairController.class));
+                Bundle bundle = new Bundle();
+                bundle.putBinder(EXTRA_BINDER, callback);
+                mContext
+                        .startActivityAsUser(new Intent(ACTIVITY_INTENT_ACTION)
+                                        .putExtra(EXTRA_HALF_SHEET_INFO,
+                                                scanFastPairStoreItem.toByteArray())
+                                        .putExtra(EXTRA_HALF_SHEET_TYPE,
+                                                DEVICE_PAIRING_FRAGMENT_TYPE)
+                                        .putExtra(EXTRA_BUNDLE, bundle)
+                                        .setComponent(new ComponentName(packageName,
+                                                HALF_SHEET_CLASS_NAME)),
+                                UserHandle.CURRENT);
 
+            }
+        } catch (IllegalStateException e) {
+            Log.e("FastPairHalfSheetManager",
+                    "Can't resolve package that contains half sheet");
         }
     }
 
diff --git a/nearby/service/java/com/android/server/nearby/util/Environment.java b/nearby/service/java/com/android/server/nearby/util/Environment.java
index dc131e7..e7277cd 100644
--- a/nearby/service/java/com/android/server/nearby/util/Environment.java
+++ b/nearby/service/java/com/android/server/nearby/util/Environment.java
@@ -29,7 +29,7 @@
     /**
      * NEARBY apex name.
      */
-    private static final String NEARBY_APEX_NAME = "com.android.nearby";
+    private static final String NEARBY_APEX_NAME = "com.android.tethering";
 
     /**
      * The path where the Nearby apex is mounted.
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceParcelableTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceParcelableTest.java
index 081626b..82e6615 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceParcelableTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceParcelableTest.java
@@ -21,32 +21,47 @@
 import android.nearby.NearbyDevice;
 import android.nearby.NearbyDeviceParcelable;
 import android.os.Build;
+import android.os.Parcel;
 
 import androidx.annotation.RequiresApi;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SdkSuppress;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Arrays;
+
 @RunWith(AndroidJUnit4.class)
 @RequiresApi(Build.VERSION_CODES.TIRAMISU)
 public class NearbyDeviceParcelableTest {
 
     private static final String BLUETOOTH_ADDRESS = "00:11:22:33:FF:EE";
+    private static final byte[] SCAN_DATA = new byte[] {1, 2, 3, 4};
+    private static final String FAST_PAIR_MODEL_ID = "1234";
+    private static final int RSSI = -60;
+
+    private NearbyDeviceParcelable.Builder mBuilder;
+
+    @Before
+    public void setUp() {
+        mBuilder =  new NearbyDeviceParcelable.Builder()
+                .setName("testDevice")
+                .setMedium(NearbyDevice.Medium.BLE)
+                .setRssi(RSSI)
+                .setFastPairModelId(FAST_PAIR_MODEL_ID)
+                .setBluetoothAddress(BLUETOOTH_ADDRESS)
+                .setData(SCAN_DATA);
+    }
+
 
     /** Verify toString returns expected string. */
     @Test
     @SdkSuppress(minSdkVersion = 32, codeName = "T")
     public void testToString() {
-        NearbyDeviceParcelable nearbyDeviceParcelable =  new NearbyDeviceParcelable.Builder()
-                .setName("testDevice")
-                .setMedium(NearbyDevice.Medium.BLE)
-                .setRssi(-60)
-                .setFastPairModelId(null)
-                .setBluetoothAddress(BLUETOOTH_ADDRESS)
-                .setData(null)
-                .build();
+        NearbyDeviceParcelable nearbyDeviceParcelable =
+                mBuilder.setFastPairModelId(null).setData(null).build();
 
         assertThat(nearbyDeviceParcelable.toString()).isEqualTo(
                 "NearbyDeviceParcelable[name=testDevice, medium=BLE, rssi=-60, "
@@ -59,7 +74,7 @@
     public void test_defaultNullFields() {
         NearbyDeviceParcelable nearbyDeviceParcelable =  new NearbyDeviceParcelable.Builder()
                 .setMedium(NearbyDevice.Medium.BLE)
-                .setRssi(-60)
+                .setRssi(RSSI)
                 .build();
 
         assertThat(nearbyDeviceParcelable.getName()).isNull();
@@ -68,6 +83,56 @@
         assertThat(nearbyDeviceParcelable.getData()).isNull();
 
         assertThat(nearbyDeviceParcelable.getMedium()).isEqualTo(NearbyDevice.Medium.BLE);
-        assertThat(nearbyDeviceParcelable.getRssi()).isEqualTo(-60);
+        assertThat(nearbyDeviceParcelable.getRssi()).isEqualTo(RSSI);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testWriteParcel() {
+        NearbyDeviceParcelable nearbyDeviceParcelable =  mBuilder.build();
+
+        Parcel parcel = Parcel.obtain();
+        nearbyDeviceParcelable.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        NearbyDeviceParcelable actualNearbyDevice = NearbyDeviceParcelable.CREATOR.createFromParcel(
+                parcel);
+        parcel.recycle();
+
+        assertThat(actualNearbyDevice.getRssi()).isEqualTo(RSSI);
+        assertThat(actualNearbyDevice.getFastPairModelId()).isEqualTo(FAST_PAIR_MODEL_ID);
+        assertThat(actualNearbyDevice.getBluetoothAddress()).isEqualTo(BLUETOOTH_ADDRESS);
+        assertThat(Arrays.equals(actualNearbyDevice.getData(), SCAN_DATA)).isTrue();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testWriteParcel_nullModelId() {
+        NearbyDeviceParcelable nearbyDeviceParcelable =
+                mBuilder.setFastPairModelId(null).build();
+
+        Parcel parcel = Parcel.obtain();
+        nearbyDeviceParcelable.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        NearbyDeviceParcelable actualNearbyDevice = NearbyDeviceParcelable.CREATOR.createFromParcel(
+                parcel);
+        parcel.recycle();
+
+        assertThat(actualNearbyDevice.getFastPairModelId()).isNull();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testWriteParcel_nullBluetoothAddress() {
+        NearbyDeviceParcelable nearbyDeviceParcelable =
+                mBuilder.setBluetoothAddress(null).build();
+
+        Parcel parcel = Parcel.obtain();
+        nearbyDeviceParcelable.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        NearbyDeviceParcelable actualNearbyDevice = NearbyDeviceParcelable.CREATOR.createFromParcel(
+                parcel);
+        parcel.recycle();
+
+        assertThat(actualNearbyDevice.getBluetoothAddress()).isNull();
     }
 }
diff --git a/nearby/tests/unit/Android.bp b/nearby/tests/unit/Android.bp
index 93ab20a..9b5b14c 100644
--- a/nearby/tests/unit/Android.bp
+++ b/nearby/tests/unit/Android.bp
@@ -33,18 +33,14 @@
     compile_multilib: "both",
 
     static_libs: [
-        "Robolectric_all-target",
         "androidx.test.ext.junit",
         "androidx.test.rules",
-        "compatibility-device-util-axt",
         "framework-nearby-static",
         "guava",
         "junit",
         "libprotobuf-java-lite",
         "mockito-target",
         "platform-test-annotations",
-        "robolectric_android-all-stub",
-        "service-appsearch",
         "service-nearby",
         "truth-prebuilt",
     ],