Merge "Add unit test for Preferences."
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/Constant.java b/nearby/service/java/com/android/server/nearby/fastpair/Constant.java
index 1477d95..5958007 100644
--- a/nearby/service/java/com/android/server/nearby/fastpair/Constant.java
+++ b/nearby/service/java/com/android/server/nearby/fastpair/Constant.java
@@ -20,6 +20,17 @@
  * String constant for half sheet.
  */
 public class Constant {
+
+    /**
+     * Value represents true for {@link android.provider.Settings.Secure}
+     */
+    public static final int SETTINGS_TRUE_VALUE = 1;
+
+    /**
+     * Tag for Fast Pair service related logs.
+     */
+    public static final String TAG = "FastPairService";
+
     public static final String EXTRA_BINDER = "com.android.server.nearby.fastpair.BINDER";
     public static final String EXTRA_BUNDLE = "com.android.server.nearby.fastpair.BUNDLE_EXTRA";
     public static final String SUCCESS_STATE = "SUCCESS";
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 3f7ad2a..f8d5a62 100644
--- a/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java
+++ b/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java
@@ -86,12 +86,19 @@
 
         } else {
             // Start to process bloom filter
-            List<Account> accountList =
-                    FastPairDataProvider.getInstance().loadFastPairEligibleAccounts();
-            byte[] bloomFilterByteArray = FastPairDecoder.getBloomFilter(fastPairDevice.getData());
-            byte[] bloomFilterSalt = FastPairDecoder.getBloomFilterSalt(fastPairDevice.getData());
-            for (Account account : accountList) {
-                try {
+            try {
+                List<Account> accountList =
+                        FastPairDataProvider.getInstance().loadFastPairEligibleAccounts();
+                Log.d(TAG, "account list size" + accountList.size());
+                byte[] bloomFilterByteArray = FastPairDecoder
+                        .getBloomFilter(fastPairDevice.getData());
+                byte[] bloomFilterSalt = FastPairDecoder
+                        .getBloomFilterSalt(fastPairDevice.getData());
+                if (bloomFilterByteArray == null || bloomFilterByteArray.length == 0) {
+                    Log.d(TAG, "bloom filter byte size is 0");
+                    return;
+                }
+                for (Account account : accountList) {
                     List<Data.FastPairDeviceWithAccountKey> listDevices =
                             FastPairDataProvider.getInstance().loadFastPairDevicesWithAccountKey(
                                     account);
@@ -100,14 +107,15 @@
                                     new BloomFilter(bloomFilterByteArray,
                                             new FastPairBloomFilterHasher()), bloomFilterSalt);
                     if (recognizedDevice != null) {
-                        Log.d(TAG, "find matched device show notification to remind user to pair");
+                        Log.d(TAG, "find matched device show notification to remind"
+                                + " user to pair");
                         return;
                     }
-                } catch (IllegalStateException e) {
-                    Log.e(TAG, "OEM does not construct fast pair data proxy correctly");
                 }
-
+            } catch (IllegalStateException e) {
+                Log.e(TAG, "OEM does not construct fast pair data proxy correctly");
             }
+
         }
     }
 
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/FastPairController.java b/nearby/service/java/com/android/server/nearby/fastpair/FastPairController.java
index cf8cd62..793e126 100644
--- a/nearby/service/java/com/android/server/nearby/fastpair/FastPairController.java
+++ b/nearby/service/java/com/android/server/nearby/fastpair/FastPairController.java
@@ -125,10 +125,7 @@
                     @Override
                     public void run() {
                         DiscoveryItem item = null;
-                        if (itemId != null) {
-                            // api call to get Fast Pair related info
-                            item = mFastPairCacheManager.getDiscoveryItem(itemId);
-                        } else if (discoveryItem != null) {
+                        if (discoveryItem != null) {
                             try {
                                 item = new DiscoveryItem(mContext,
                                         Cache.StoredDiscoveryItem.parseFrom(discoveryItem));
@@ -136,6 +133,7 @@
                                 Log.w(TAG,
                                         "Error parsing serialized discovery item with size "
                                                 + discoveryItem.length);
+                                return;
                             }
                         }
 
@@ -196,6 +194,7 @@
             Log.d(TAG, "FastPair: fastpairing, skip pair request");
             return;
         }
+        mIsFastPairing = true;
         Log.d(TAG, "FastPair: start pair");
 
         // Hide all "tap to pair" notifications until after the flow completes.
@@ -213,7 +212,7 @@
                         companionApp,
                         mFootprintsDeviceManager,
                         pairingProgressHandlerBase);
-        mIsFastPairing = true;
+        mIsFastPairing = false;
     }
 
     /** Fixes a companion app package name with extra spaces. */
@@ -247,26 +246,26 @@
         FastPairManager.processBackgroundTask(() -> {
             Cache.StoredDiscoveryItem storedDiscoveryItem =
                     prepareStoredDiscoveryItemForFootprints(discoveryItem);
-            if (storedDiscoveryItem != null) {
-                byte[] hashValue =
-                        Hashing.sha256()
-                                .hashBytes(
-                                        concat(accountKey, BluetoothAddress.decode(publicAddress)))
-                                .asBytes();
-                FastPairUploadInfo uploadInfo =
-                        new FastPairUploadInfo(storedDiscoveryItem, ByteString.copyFrom(accountKey),
-                                ByteString.copyFrom(hashValue));
-                // account data place holder here
-                try {
-                    FastPairDataProvider.getInstance().optIn(new Account("empty", "empty"));
+            byte[] hashValue =
+                    Hashing.sha256()
+                            .hashBytes(
+                                    concat(accountKey, BluetoothAddress.decode(publicAddress)))
+                            .asBytes();
+            FastPairUploadInfo uploadInfo =
+                    new FastPairUploadInfo(storedDiscoveryItem, ByteString.copyFrom(accountKey),
+                            ByteString.copyFrom(hashValue));
+            // account data place holder here
+            try {
+                List<Account> accountList =
+                        FastPairDataProvider.getInstance().loadFastPairEligibleAccounts();
+                if (accountList.size() > 0) {
+                    FastPairDataProvider.getInstance().optIn(accountList.get(0));
                     FastPairDataProvider.getInstance().upload(
-                            new Account("empty", "empty"), uploadInfo);
-                } catch (IllegalStateException e) {
-                    Log.e(TAG, "OEM does not construct fast pair data proxy correctly");
+                            accountList.get(0), uploadInfo);
                 }
-
+            } catch (IllegalStateException e) {
+                Log.e(TAG, "OEM does not construct fast pair data proxy correctly");
             }
-
         });
     }
 
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/FastPairManager.java b/nearby/service/java/com/android/server/nearby/fastpair/FastPairManager.java
index 7e2151d..9e1a718 100644
--- a/nearby/service/java/com/android/server/nearby/fastpair/FastPairManager.java
+++ b/nearby/service/java/com/android/server/nearby/fastpair/FastPairManager.java
@@ -16,20 +16,27 @@
 
 package com.android.server.nearby.fastpair;
 
+import static com.android.server.nearby.fastpair.Constant.SETTINGS_TRUE_VALUE;
+import static com.android.server.nearby.fastpair.Constant.TAG;
+
 import android.annotation.Nullable;
 import android.annotation.WorkerThread;
 import android.app.KeyguardManager;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothManager;
 import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.database.ContentObserver;
 import android.nearby.FastPairDevice;
 import android.nearby.NearbyDevice;
 import android.nearby.NearbyManager;
 import android.nearby.ScanCallback;
 import android.nearby.ScanRequest;
+import android.net.Uri;
+import android.provider.Settings;
 import android.util.Log;
 
 import androidx.annotation.NonNull;
@@ -71,47 +78,32 @@
  */
 
 public class FastPairManager {
+
     private static final String ACTION_PREFIX = UserActionHandler.PREFIX;
     private static final int WAIT_FOR_UNLOCK_MILLIS = 5000;
+
     /** A notification ID which should be dismissed */
     public static final String EXTRA_NOTIFICATION_ID = ACTION_PREFIX + "EXTRA_NOTIFICATION_ID";
     public static final String ACTION_RESOURCES_APK = "android.nearby.SHOW_HALFSHEET";
 
     private static Executor sFastPairExecutor;
 
+    private ContentObserver mFastPairScanChangeContentObserver = null;
+
     final LocatorContextWrapper mLocatorContextWrapper;
     final IntentFilter mIntentFilter;
     final Locator mLocator;
-    private boolean mAllowScan = false;
+    private boolean mScanEnabled = false;
     private final BroadcastReceiver mScreenBroadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
-                Log.d("FastPairService", " screen on");
-                NearbyManager nearbyManager = (NearbyManager) mLocatorContextWrapper
-                        .getApplicationContext().getSystemService(Context.NEARBY_SERVICE);
-
-                Log.d("FastPairService", " the nearby manager is " + nearbyManager);
-
-                if (nearbyManager != null) {
-                    if (mAllowScan) {
-                        nearbyManager.startScan(
-                                new ScanRequest.Builder()
-                                        .setScanType(ScanRequest.SCAN_TYPE_FAST_PAIR).build(),
-                                ForegroundThread.getExecutor(),
-                                mScanCallback);
-                    }
-                } else {
-                    Log.d("FastPairService", " the nearby manager is null");
-                }
-
-            } else {
-                Log.d("FastPairService", " screen off");
+                Log.d(TAG, "onReceive: ACTION_SCREEN_ON.");
+                invalidateScan();
             }
         }
     };
 
-
     public FastPairManager(LocatorContextWrapper contextWrapper) {
         mLocatorContextWrapper = contextWrapper;
         mIntentFilter = new IntentFilter();
@@ -131,16 +123,14 @@
         public void onUpdated(@NonNull NearbyDevice device) {
             FastPairDevice fastPairDevice = (FastPairDevice) device;
             byte[] modelArray = FastPairDecoder.getModelId(fastPairDevice.getData());
-            Log.d("FastPairService",
-                    "update model id" + Hex.bytesToStringLowercase(modelArray));
+            Log.d(TAG, "update model id" + Hex.bytesToStringLowercase(modelArray));
         }
 
         @Override
         public void onLost(@NonNull NearbyDevice device) {
             FastPairDevice fastPairDevice = (FastPairDevice) device;
             byte[] modelArray = FastPairDecoder.getModelId(fastPairDevice.getData());
-            Log.d("FastPairService",
-                    "lost model id" + Hex.bytesToStringLowercase(modelArray));
+            Log.d(TAG, "lost model id" + Hex.bytesToStringLowercase(modelArray));
         }
     };
 
@@ -155,6 +145,13 @@
                 .registerReceiver(mScreenBroadcastReceiver, mIntentFilter);
 
         Locator.getFromContextWrapper(mLocatorContextWrapper, FastPairCacheManager.class);
+        try {
+            mScanEnabled = getScanEnabledFromSettings();
+        } catch (Settings.SettingNotFoundException e) {
+            Log.w(TAG,
+                    "initiate: Failed to get initial scan enabled status from Settings.", e);
+        }
+        registerFastPairScanChangeContentObserver(mLocatorContextWrapper.getContentResolver());
     }
 
     /**
@@ -162,6 +159,10 @@
      */
     public void cleanUp() {
         mLocatorContextWrapper.getContext().unregisterReceiver(mScreenBroadcastReceiver);
+        if (mFastPairScanChangeContentObserver != null) {
+            mLocatorContextWrapper.getContentResolver().unregisterContentObserver(
+                    mFastPairScanChangeContentObserver);
+        }
     }
 
     /**
@@ -212,18 +213,17 @@
             boolean isBluetoothEnabled = bluetoothAdapter != null && bluetoothAdapter.isEnabled();
             if (!isBluetoothEnabled) {
                 if (bluetoothAdapter == null || !bluetoothAdapter.enable()) {
-                    Log.d("FastPairManager", "FastPair: Failed to enable bluetooth");
+                    Log.d(TAG, "FastPair: Failed to enable bluetooth");
                     return;
                 }
-                Log.v("FastPairManager", "FastPair: Enabling bluetooth for fast pair");
+                Log.v(TAG, "FastPair: Enabling bluetooth for fast pair");
 
                 Locator.get(context, EventLoop.class)
                         .postRunnable(
                                 new NamedRunnable("enableBluetoothToast") {
                                     @Override
                                     public void run() {
-                                        Log.d("FastPairManager",
-                                                "Enable bluetooth toast test");
+                                        Log.d(TAG, "Enable bluetooth toast test");
                                     }
                                 });
                 // Set up call back to call this function again once bluetooth has been
@@ -287,7 +287,7 @@
                 | ExecutionException
                 | PairingException
                 | GeneralSecurityException e) {
-            Log.e("FastPairManager", "FastPair: Error");
+            Log.e(TAG, "FastPair: Error");
             pairingProgressHandlerBase.onPairingFailed(e);
         }
     }
@@ -307,8 +307,7 @@
         // pattern) So we use this method instead, which returns true when on the lock screen
         // regardless.
         if (keyguardManager.isKeyguardLocked()) {
-            Log.v("FastPairManager",
-                    "FastPair: Screen is locked, waiting until unlocked "
+            Log.v(TAG, "FastPair: Screen is locked, waiting until unlocked "
                             + "to show status notifications.");
             try (SimpleBroadcastReceiver isUnlockedReceiver =
                          SimpleBroadcastReceiver.oneShotReceiver(
@@ -319,6 +318,28 @@
         }
     }
 
+    private void registerFastPairScanChangeContentObserver(ContentResolver resolver) {
+        mFastPairScanChangeContentObserver = new ContentObserver(ForegroundThread.getHandler()) {
+            @Override
+            public void onChange(boolean selfChange, Uri uri) {
+                super.onChange(selfChange, uri);
+                try {
+                    setScanEnabled(getScanEnabledFromSettings());
+                } catch (Settings.SettingNotFoundException e) {
+                    Log.e(TAG, "Failed to get scan switch updates in Settings page.", e);
+                }
+            }
+        };
+        try {
+            resolver.registerContentObserver(
+                    Settings.Secure.getUriFor(Settings.Secure.FAST_PAIR_SCAN_ENABLED),
+                    /* notifyForDescendants= */ false,
+                    mFastPairScanChangeContentObserver);
+        }  catch (SecurityException e) {
+            Log.e(TAG, "Failed to register content observer for fast pair scan.", e);
+        }
+    }
+
     /**
      * Processed task in a background thread
      */
@@ -339,6 +360,49 @@
     }
 
     /**
+     * Null when the Nearby Service is not available.
+     */
+    @Nullable
+    private NearbyManager getNearbyManager() {
+        return (NearbyManager) mLocatorContextWrapper
+                .getApplicationContext().getSystemService(Context.NEARBY_SERVICE);
+    }
+
+    private boolean getScanEnabledFromSettings() throws Settings.SettingNotFoundException {
+        return Settings.Secure.getInt(
+                mLocatorContextWrapper.getContext().getContentResolver(),
+                Settings.Secure.FAST_PAIR_SCAN_ENABLED) == SETTINGS_TRUE_VALUE;
+    }
+
+    private void setScanEnabled(boolean scanEnabled) {
+        if (mScanEnabled == scanEnabled) {
+            return;
+        }
+        mScanEnabled = scanEnabled;
+        invalidateScan();
+    }
+
+    /**
+     *  Starts or stops scanning according to mAllowScan value.
+     */
+    private void invalidateScan() {
+        NearbyManager nearbyManager = getNearbyManager();
+        if (nearbyManager == null) {
+            Log.w(TAG, "invalidateScan: "
+                    + "failed to start or stop scannning because NearbyManager is null.");
+            return;
+        }
+        if (mScanEnabled) {
+            nearbyManager.startScan(new ScanRequest.Builder()
+                            .setScanType(ScanRequest.SCAN_TYPE_FAST_PAIR).build(),
+                    ForegroundThread.getExecutor(),
+                    mScanCallback);
+        } else {
+            nearbyManager.stopScan(mScanCallback);
+        }
+    }
+
+    /**
      * Helper function to get bluetooth adapter.
      */
     @Nullable
@@ -346,5 +410,4 @@
         BluetoothManager manager = context.getSystemService(BluetoothManager.class);
         return manager == null ? null : manager.getAdapter();
     }
-
 }
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 f8c16a1..f15239e 100644
--- a/nearby/service/java/com/android/server/nearby/provider/FastPairDataProvider.java
+++ b/nearby/service/java/com/android/server/nearby/provider/FastPairDataProvider.java
@@ -109,6 +109,7 @@
             requestParcel.account = account;
             requestParcel.requestType = FastPairDataProviderBase.MANAGE_REQUEST_ADD;
             mProxyFastPairDataProvider.manageFastPairAccount(requestParcel);
+            return;
         }
         throw new IllegalStateException("No ProxyFastPairDataProvider yet constructed");
     }
@@ -128,6 +129,7 @@
                     Utils.convertFastPairUploadInfoToFastPairAccountKeyDeviceMetadata(
                             uploadInfo);
             mProxyFastPairDataProvider.manageFastPairAccountDevice(requestParcel);
+            return;
         }
         throw new IllegalStateException("No ProxyFastPairDataProvider yet constructed");
     }
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 0b3ff07..a37cc67 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceBroadcastRequestTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceBroadcastRequestTest.java
@@ -17,6 +17,7 @@
 package android.nearby.cts;
 
 import static android.nearby.BroadcastRequest.BROADCAST_TYPE_NEARBY_PRESENCE;
+import static android.nearby.BroadcastRequest.PRESENCE_VERSION_V0;
 import static android.nearby.PresenceCredential.IDENTITY_TYPE_PRIVATE;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -34,6 +35,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Arrays;
 import java.util.Collections;
 
 /**
@@ -43,6 +45,7 @@
 @RequiresApi(Build.VERSION_CODES.TIRAMISU)
 public class PresenceBroadcastRequestTest {
 
+    private static final int VERSION = PRESENCE_VERSION_V0;
     private static final int TX_POWER = 1;
     private static final byte[] SALT = new byte[]{1, 2};
     private static final int ACTION_ID = 123;
@@ -53,7 +56,6 @@
     private static final int KEY = 1234;
     private static final byte[] VALUE = new byte[]{1, 1, 1, 1};
 
-
     private PresenceBroadcastRequest.Builder mBuilder;
 
     @Before
@@ -65,6 +67,7 @@
         DataElement element = new DataElement(KEY, VALUE);
         mBuilder = new PresenceBroadcastRequest.Builder(Collections.singletonList(BLE_MEDIUM), SALT)
                 .setTxPower(TX_POWER)
+                .setVersion(VERSION)
                 .setCredential(credential)
                 .addAction(ACTION_ID)
                 .addExtendedProperty(element);
@@ -74,6 +77,8 @@
     public void testBuilder() {
         PresenceBroadcastRequest broadcastRequest = mBuilder.build();
 
+        assertThat(broadcastRequest.getVersion()).isEqualTo(VERSION);
+        assertThat(Arrays.equals(broadcastRequest.getSalt(), SALT)).isTrue();
         assertThat(broadcastRequest.getTxPower()).isEqualTo(TX_POWER);
         assertThat(broadcastRequest.getActions()).containsExactly(ACTION_ID);
         assertThat(broadcastRequest.getExtendedProperties().get(0).getKey()).isEqualTo(
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 e21bc80..a1b282d 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceDeviceTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceDeviceTest.java
@@ -46,6 +46,10 @@
     private static final String DEVICE_NAME = "testDevice";
     private static final int KEY = 1234;
     private static final byte[] VALUE = new byte[]{1, 1, 1, 1};
+    private static final byte[] SALT = new byte[]{2, 3};
+    private static final byte[] SECRET_ID = new byte[]{11, 13};
+    private static final byte[] ENCRYPTED_IDENTITY = new byte[]{1, 3, 5, 61};
+    private static final long DISCOVERY_MILLIS = 100L;
 
     @Test
     public void testBuilder() {
@@ -57,6 +61,10 @@
                 .setRssi(RSSI)
                 .addMedium(MEDIUM)
                 .setName(DEVICE_NAME)
+                .setDiscoveryTimestampMillis(DISCOVERY_MILLIS)
+                .setSalt(SALT)
+                .setSecretId(SECRET_ID)
+                .setEncryptedIdentity(ENCRYPTED_IDENTITY)
                 .build();
 
         assertThat(device.getDeviceType()).isEqualTo(DEVICE_TYPE);
@@ -68,6 +76,10 @@
         assertThat(device.getRssi()).isEqualTo(RSSI);
         assertThat(device.getMediums()).containsExactly(MEDIUM);
         assertThat(device.getName()).isEqualTo(DEVICE_NAME);
+        assertThat(Arrays.equals(device.getSalt(), SALT)).isTrue();
+        assertThat(Arrays.equals(device.getSecretId(), SECRET_ID)).isTrue();
+        assertThat(Arrays.equals(device.getEncryptedIdentity(), ENCRYPTED_IDENTITY)).isTrue();
+        assertThat(device.getDiscoveryTimestampMillis()).isEqualTo(DISCOVERY_MILLIS);
     }
 
     @Test
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 8962499..308be9e 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceScanFilterTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceScanFilterTest.java
@@ -70,6 +70,8 @@
         assertThat(filter.getCredentials().get(0).getIdentityType()).isEqualTo(
                 IDENTITY_TYPE_PRIVATE);
         assertThat(filter.getPresenceActions()).containsExactly(ACTION);
+        assertThat(filter.getExtendedProperties().get(0).getKey()).isEqualTo(KEY);
+
     }
 
     @Test
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 3212307..5242999 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/PrivateCredentialTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/PrivateCredentialTest.java
@@ -41,6 +41,7 @@
 @RunWith(AndroidJUnit4.class)
 @RequiresApi(Build.VERSION_CODES.TIRAMISU)
 public class PrivateCredentialTest {
+    private static final String DEVICE_NAME = "myDevice";
     private static final byte[] SECRETE_ID = new byte[]{1, 2, 3, 4};
     private static final byte[] AUTHENTICITY_KEY = new byte[]{0, 1, 1, 1};
     private static final String KEY = "SecreteId";
@@ -53,6 +54,7 @@
     public void setUp() {
         mBuilder = new PrivateCredential.Builder(SECRETE_ID, AUTHENTICITY_KEY)
                 .setIdentityType(IDENTITY_TYPE_PRIVATE)
+                .setDeviceName(DEVICE_NAME)
                 .setMetadataEncryptionKey(METADATA_ENCRYPTION_KEY)
                 .addCredentialElement(new CredentialElement(KEY, VALUE));
     }
@@ -63,6 +65,7 @@
 
         assertThat(credential.getType()).isEqualTo(CREDENTIAL_TYPE_PRIVATE);
         assertThat(credential.getIdentityType()).isEqualTo(IDENTITY_TYPE_PRIVATE);
+        assertThat(credential.getDeviceName()).isEqualTo(DEVICE_NAME);
         assertThat(Arrays.equals(credential.getSecretId(), SECRETE_ID)).isTrue();
         assertThat(Arrays.equals(credential.getAuthenticityKey(), AUTHENTICITY_KEY)).isTrue();
         assertThat(Arrays.equals(credential.getMetadataEncryptionKey(),
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 4a12416..f750951 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/PublicCredentialTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/PublicCredentialTest.java
@@ -21,6 +21,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import android.nearby.CredentialElement;
 import android.nearby.PresenceCredential;
 import android.nearby.PublicCredential;
 import android.os.Build;
@@ -47,12 +48,15 @@
     private static final byte[] PUBLIC_KEY = new byte[]{1, 1, 2, 2};
     private static final byte[] ENCRYPTED_METADATA = new byte[]{1, 2, 3, 4, 5};
     private static final byte[] METADATA_ENCRYPTION_KEY_TAG = new byte[]{1, 1, 3, 4, 5};
+    private static final String KEY = "KEY";
+    private static final byte[] VALUE = new byte[]{1, 2, 3, 4, 5};
 
     private PublicCredential.Builder mBuilder;
 
     @Before
     public void setUp() {
         mBuilder = new PublicCredential.Builder(SECRETE_ID, AUTHENTICITY_KEY)
+                .addCredentialElement(new CredentialElement(KEY, VALUE))
                 .setIdentityType(IDENTITY_TYPE_PRIVATE)
                 .setPublicKey(PUBLIC_KEY).setEncryptedMetadata(ENCRYPTED_METADATA)
                 .setEncryptedMetadataKeyTag(METADATA_ENCRYPTION_KEY_TAG);
@@ -64,6 +68,7 @@
 
         assertThat(credential.getType()).isEqualTo(CREDENTIAL_TYPE_PUBLIC);
         assertThat(credential.getIdentityType()).isEqualTo(IDENTITY_TYPE_PRIVATE);
+        assertThat(credential.getCredentialElements().get(0).getKey()).isEqualTo(KEY);
         assertThat(Arrays.equals(credential.getSecretId(), SECRETE_ID)).isTrue();
         assertThat(Arrays.equals(credential.getAuthenticityKey(), AUTHENTICITY_KEY)).isTrue();
         assertThat(Arrays.equals(credential.getPublicKey(), PUBLIC_KEY)).isTrue();
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/ScanRequestTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/ScanRequestTest.java
index 2d01e83..86e764c 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/ScanRequestTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/ScanRequestTest.java
@@ -48,6 +48,16 @@
     private static final int UID = 1001;
     private static final String APP_NAME = "android.nearby.tests";
 
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testScanType() {
+        ScanRequest request = new ScanRequest.Builder()
+                .setScanType(SCAN_TYPE_NEARBY_PRESENCE)
+                .build();
+
+        assertThat(request.getScanType()).isEqualTo(SCAN_TYPE_NEARBY_PRESENCE);
+    }
+
     // Valid scan type must be set to one of ScanRequest#SCAN_TYPE_
     @Test(expected = IllegalStateException.class)
     @SdkSuppress(minSdkVersion = 32, codeName = "T")
diff --git a/nearby/tests/unit/src/com/android/server/nearby/fastpair/FastPairManagerTest.java b/nearby/tests/unit/src/com/android/server/nearby/fastpair/FastPairManagerTest.java
index f061115..26d1847 100644
--- a/nearby/tests/unit/src/com/android/server/nearby/fastpair/FastPairManagerTest.java
+++ b/nearby/tests/unit/src/com/android/server/nearby/fastpair/FastPairManagerTest.java
@@ -19,10 +19,12 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.content.Context;
 
 import androidx.test.filters.SdkSuppress;
+import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.server.nearby.common.locator.LocatorContextWrapper;
 
@@ -40,8 +42,11 @@
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
+
         mLocatorContextWrapper = new LocatorContextWrapper(mContext);
         mFastPairManager = new FastPairManager(mLocatorContextWrapper);
+        when(mContext.getContentResolver()).thenReturn(
+                InstrumentationRegistry.getInstrumentation().getContext().getContentResolver());
     }
 
     @Test