Enable CTS for nearby brodacast.

Also fixed a few bugs related to broadcast.

Test: atest CtsNearbyFastPairTestCases
Bug: 219768328

Change-Id: Icf7561267137142eadfd2fffb75b19a18faa2f5e
diff --git a/nearby/framework/java/android/nearby/NearbyManager.java b/nearby/framework/java/android/nearby/NearbyManager.java
index 1d91242..eb34e00 100644
--- a/nearby/framework/java/android/nearby/NearbyManager.java
+++ b/nearby/framework/java/android/nearby/NearbyManager.java
@@ -307,7 +307,11 @@
 
         @Override
         public void onStatusChanged(int status) {
-            mExecutor.execute(()-> mBroadcastCallback.onStatusChanged(status));
+            mExecutor.execute(() -> {
+                if (mBroadcastCallback != null) {
+                    mBroadcastCallback.onStatusChanged(status);
+                }
+            });
         }
     }
 }
diff --git a/nearby/service/java/com/android/server/nearby/provider/BleBroadcastProvider.java b/nearby/service/java/com/android/server/nearby/provider/BleBroadcastProvider.java
index 40fc46f..3602787 100644
--- a/nearby/service/java/com/android/server/nearby/provider/BleBroadcastProvider.java
+++ b/nearby/service/java/com/android/server/nearby/provider/BleBroadcastProvider.java
@@ -27,6 +27,8 @@
 import com.android.server.nearby.injector.Injector;
 import com.android.server.nearby.presence.PresenceConstants;
 
+import java.util.concurrent.Executor;
+
 /**
  * A provider for Bluetooth Low Energy advertisement.
  */
@@ -40,15 +42,17 @@
     }
 
     private final Injector mInjector;
+    private final Executor mExecutor;
+
     private BroadcastListener mBroadcastListener;
     private boolean mIsAdvertising;
 
-    BleBroadcastProvider(Injector injector) {
+    BleBroadcastProvider(Injector injector, Executor executor) {
         mInjector = injector;
+        mExecutor = executor;
     }
 
     void start(byte[] advertisementPackets, BroadcastListener listener) {
-
         if (mIsAdvertising) {
             stop();
         }
@@ -100,9 +104,12 @@
 
     @Override
     public void onStartSuccess(AdvertiseSettings settingsInEffect) {
-        if (mBroadcastListener != null) {
-            mBroadcastListener.onStatusChanged(BroadcastCallback.STATUS_OK);
-        }
+        mExecutor.execute(() -> {
+            if (mBroadcastListener != null) {
+                mBroadcastListener.onStatusChanged(BroadcastCallback.STATUS_OK);
+            }
+            mIsAdvertising = true;
+        });
     }
 
     @Override
diff --git a/nearby/service/java/com/android/server/nearby/provider/BroadcastProviderManager.java b/nearby/service/java/com/android/server/nearby/provider/BroadcastProviderManager.java
index 6a0f637..72fe29a 100644
--- a/nearby/service/java/com/android/server/nearby/provider/BroadcastProviderManager.java
+++ b/nearby/service/java/com/android/server/nearby/provider/BroadcastProviderManager.java
@@ -47,7 +47,8 @@
     private IBroadcastListener mBroadcastListener;
 
     public BroadcastProviderManager(Context context, Injector injector) {
-        this(ForegroundThread.getExecutor(), new BleBroadcastProvider(injector));
+        this(ForegroundThread.getExecutor(),
+                new BleBroadcastProvider(injector, ForegroundThread.getExecutor()));
     }
 
     @VisibleForTesting
@@ -64,7 +65,8 @@
      */
     public void startBroadcast(BroadcastRequest broadcastRequest, IBroadcastListener listener) {
         synchronized (mLock) {
-            if (!mNearbyConfiguration.isPresenceBroadcastLegacyEnabled()) {
+            NearbyConfiguration configuration = new NearbyConfiguration();
+            if (!configuration.isPresenceBroadcastLegacyEnabled()) {
                 reportBroadcastStatus(listener, BroadcastCallback.STATUS_FAILURE);
                 return;
             }
diff --git a/nearby/tests/cts/fastpair/Android.bp b/nearby/tests/cts/fastpair/Android.bp
index 6dc1af8..845ed84 100644
--- a/nearby/tests/cts/fastpair/Android.bp
+++ b/nearby/tests/cts/fastpair/Android.bp
@@ -23,12 +23,14 @@
         "androidx.test.ext.junit",
         "androidx.test.ext.truth",
         "androidx.test.rules",
+        "bluetooth-test-util-lib",
         "compatibility-device-util-axt",
         "ctstestrunner-axt",
         "truth-prebuilt",
     ],
     libs: [
         "android.test.base",
+        "framework-bluetooth.stubs.module_lib",
         "framework-connectivity-t.impl",
     ],
     srcs: ["src/**/*.java"],
diff --git a/nearby/tests/cts/fastpair/AndroidManifest.xml b/nearby/tests/cts/fastpair/AndroidManifest.xml
index e77d70f..ce841f2 100644
--- a/nearby/tests/cts/fastpair/AndroidManifest.xml
+++ b/nearby/tests/cts/fastpair/AndroidManifest.xml
@@ -18,6 +18,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.nearby.cts">
   <uses-sdk android:minSdkVersion="32" android:targetSdkVersion="32" />
+  <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
   <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
 
   <application>
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 9dd4a93..bfbfbbe 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyManagerTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyManagerTest.java
@@ -16,13 +16,17 @@
 
 package android.nearby.cts;
 
+import static android.Manifest.permission.READ_DEVICE_CONFIG;
+import static android.Manifest.permission.WRITE_DEVICE_CONFIG;
 import static android.nearby.PresenceCredential.IDENTITY_TYPE_PRIVATE;
+import static android.provider.DeviceConfig.NAMESPACE_TETHERING;
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.Mockito.when;
-import static org.mockito.MockitoAnnotations.initMocks;
-
+import android.app.UiAutomation;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothManager;
+import android.bluetooth.cts.BTAdapterUtils;
 import android.content.Context;
 import android.nearby.BroadcastCallback;
 import android.nearby.BroadcastRequest;
@@ -33,20 +37,22 @@
 import android.nearby.ScanCallback;
 import android.nearby.ScanRequest;
 import android.os.Build;
+import android.provider.DeviceConfig;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
+import androidx.test.InstrumentationRegistry;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SdkSuppress;
-import androidx.test.platform.app.InstrumentationRegistry;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mock;
 
 import java.util.Collections;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
 
 /**
  * TODO(b/215435939) This class doesn't include any logic yet. Because SELinux denies access to
@@ -55,21 +61,27 @@
 @RunWith(AndroidJUnit4.class)
 @RequiresApi(Build.VERSION_CODES.TIRAMISU)
 public class NearbyManagerTest {
-    private static final byte[] SALT = new byte[] {1, 2};
+    private static final byte[] SALT = new byte[]{1, 2};
     private static final byte[] SECRETE_ID = new byte[]{1, 2, 3, 4};
+    private static final byte[] META_DATA_ENCRYPTION_KEY = new byte[14];
     private static final byte[] AUTHENTICITY_KEY = new byte[]{0, 1, 1, 1};
     private static final int BLE_MEDIUM = 1;
 
-    @Mock private Context mContext;
-    @Mock private NearbyManager mNearbyManager;
+    private Context mContext;
+    private NearbyManager mNearbyManager;
+    private UiAutomation mUiAutomation =
+            InstrumentationRegistry.getInstrumentation().getUiAutomation();
 
     @Before
     public void setUp() {
-        initMocks(this);
+        mUiAutomation.adoptShellPermissionIdentity(READ_DEVICE_CONFIG, WRITE_DEVICE_CONFIG);
+        DeviceConfig.setProperty(NAMESPACE_TETHERING, "nearby_enable_presence_broadcast_legacy",
+                "true", false);
 
-        when(mContext.getSystemService(Context.NEARBY_SERVICE)).thenReturn(mNearbyManager);
-        when(mContext.getContentResolver()).thenReturn(
-                InstrumentationRegistry.getInstrumentation().getContext().getContentResolver());
+        mContext = InstrumentationRegistry.getContext();
+        mNearbyManager = mContext.getSystemService(NearbyManager.class);
+
+        enableBluetooth();
     }
 
     @Test
@@ -101,19 +113,25 @@
 
     @Test
     @SdkSuppress(minSdkVersion = 32, codeName = "T")
-    public void testStartStopBroadcast() {
+    public void testStartStopBroadcast() throws InterruptedException {
         PrivateCredential credential = new PrivateCredential.Builder(SECRETE_ID, AUTHENTICITY_KEY)
                 .setIdentityType(IDENTITY_TYPE_PRIVATE)
+                .setMetadataEncryptionKey(META_DATA_ENCRYPTION_KEY)
                 .build();
         BroadcastRequest broadcastRequest =
                 new PresenceBroadcastRequest.Builder(
                         Collections.singletonList(BLE_MEDIUM), SALT, credential)
+                        .addAction(123)
                         .build();
 
+        CountDownLatch latch = new CountDownLatch(1);
         BroadcastCallback callback = status -> {
+            latch.countDown();
+            assertThat(status).isEqualTo(BroadcastCallback.STATUS_OK);
         };
         mNearbyManager.startBroadcast(broadcastRequest, Executors.newSingleThreadExecutor(),
                 callback);
+        latch.await(10, TimeUnit.SECONDS);
         mNearbyManager.stopBroadcast(callback);
     }
 
@@ -123,4 +141,12 @@
         NearbyManager.setFastPairScanEnabled(mContext, false);
         assertThat(NearbyManager.getFastPairScanEnabled(mContext, true)).isFalse();
     }
+
+    private void enableBluetooth() {
+        BluetoothManager manager = mContext.getSystemService(BluetoothManager.class);
+        BluetoothAdapter bluetoothAdapter = manager.getAdapter();
+        if (!bluetoothAdapter.isEnabled()) {
+            assertThat(BTAdapterUtils.enableAdapter(bluetoothAdapter, mContext)).isTrue();
+        }
+    }
 }
diff --git a/nearby/tests/unit/src/com/android/server/nearby/provider/BleBroadcastProviderTest.java b/nearby/tests/unit/src/com/android/server/nearby/provider/BleBroadcastProviderTest.java
index 3467407..f485e18 100644
--- a/nearby/tests/unit/src/com/android/server/nearby/provider/BleBroadcastProviderTest.java
+++ b/nearby/tests/unit/src/com/android/server/nearby/provider/BleBroadcastProviderTest.java
@@ -31,6 +31,8 @@
 import com.android.server.nearby.injector.ContextHubManagerAdapter;
 import com.android.server.nearby.injector.Injector;
 
+import com.google.common.util.concurrent.MoreExecutors;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -51,7 +53,8 @@
 
     @Before
     public void setUp() {
-        mBleBroadcastProvider = new BleBroadcastProvider(new TestInjector());
+        mBleBroadcastProvider = new BleBroadcastProvider(new TestInjector(),
+                MoreExecutors.directExecutor());
     }
 
     @Test