Merge changes from topic "nearby_tethering_apex"

* changes:
  Rename NearbyServiceImpl to NearbyService
  Start NearbyService from connectivity initializer
  Move nearby apex to tethering
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 a41d7a3..a792c0b 100644
--- a/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java
+++ b/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java
@@ -23,12 +23,14 @@
 
 import com.android.server.nearby.common.locator.Locator;
 import com.android.server.nearby.fastpair.halfsheet.FastPairHalfSheetManager;
+import com.android.server.nearby.provider.FastPairDataProvider;
 import com.android.server.nearby.util.FastPairDecoder;
 import com.android.server.nearby.util.Hex;
 
 import com.google.protobuf.ByteString;
 
 import service.proto.Cache;
+import service.proto.Rpcs;
 
 /**
  * Handler that handle fast pair related broadcast.
@@ -54,14 +56,18 @@
             return;
         }
         mBleAddress = fastPairDevice.getBluetoothAddress();
-        byte[] model = FastPairDecoder.getModelId(fastPairDevice.getData());
-        Log.d("FastPairService",
-                "On discovery model id" + Hex.bytesToStringLowercase(model));
-        // Use api to get anti spoofing key from model id.
-        Locator.get(mContext, FastPairHalfSheetManager.class).showHalfSheet(
-                Cache.ScanFastPairStoreItem.newBuilder()
-                        .setAddress(mBleAddress)
-                        .setAntiSpoofingPublicKey(ByteString.EMPTY)
-                        .build());
+        if (FastPairDecoder.checkModelId(fastPairDevice.getData())) {
+            byte[] model = FastPairDecoder.getModelId(fastPairDevice.getData());
+            Log.d("FastPairService",
+                    "On discovery model id" + Hex.bytesToStringLowercase(model));
+            // Use api to get anti spoofing key from model id.
+            Rpcs.GetObservedDeviceResponse response =
+                    FastPairDataProvider.getInstance().loadFastPairDeviceMetadata(model);
+            ByteString publicKey = response.getDevice().getAntiSpoofingKeyPair().getPublicKey();
+            Locator.get(mContext, FastPairHalfSheetManager.class).showHalfSheet(
+                    Cache.ScanFastPairStoreItem.newBuilder().setAddress(mBleAddress)
+                            .setAntiSpoofingPublicKey(publicKey)
+                            .build());
+        }
     }
 }
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 41b6da7..bc1603e 100644
--- a/nearby/service/java/com/android/server/nearby/fastpair/FastPairManager.java
+++ b/nearby/service/java/com/android/server/nearby/fastpair/FastPairManager.java
@@ -48,14 +48,10 @@
 import com.android.server.nearby.fastpair.cache.DiscoveryItem;
 import com.android.server.nearby.fastpair.cache.FastPairCacheManager;
 import com.android.server.nearby.fastpair.footprint.FootprintsDeviceManager;
-import com.android.server.nearby.fastpair.halfsheet.FastPairHalfSheetManager;
 import com.android.server.nearby.fastpair.pairinghandler.PairingProgressHandlerBase;
-import com.android.server.nearby.provider.FastPairDataProvider;
 import com.android.server.nearby.util.FastPairDecoder;
 import com.android.server.nearby.util.Hex;
 
-import com.google.protobuf.ByteString;
-
 import java.security.GeneralSecurityException;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
@@ -65,7 +61,6 @@
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
-import service.proto.Cache;
 import service.proto.Rpcs;
 
 /**
@@ -79,10 +74,6 @@
     /** 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";
-    // Temp action deleted when the scanner is ready
-    public static final String ACTION_START_PAIRING = "NEARBY_START_PAIRING";
-    public static final String EXTRA_MODEL_ID = "MODELID";
-    public static final String EXTRA_ADDRESS = "ADDRESS";
 
     private static Executor sFastPairExecutor;
 
@@ -110,17 +101,6 @@
                     Log.d("FastPairService", " the nearby manager is null");
                 }
 
-            } else if (intent.getAction().equals(ACTION_START_PAIRING)) {
-                byte[] model = intent.getByteArrayExtra(EXTRA_MODEL_ID);
-                String address = intent.getStringExtra(EXTRA_ADDRESS);
-                Log.d("FastPairService", "start pair " + address);
-                Rpcs.GetObservedDeviceResponse response =
-                        FastPairDataProvider.getInstance().loadFastPairDeviceMetadata(model);
-                ByteString publicKey = response.getDevice().getAntiSpoofingKeyPair().getPublicKey();
-                Locator.get(mLocatorContextWrapper, FastPairHalfSheetManager.class).showHalfSheet(
-                        Cache.ScanFastPairStoreItem.newBuilder().setAddress(address)
-                                .setAntiSpoofingPublicKey(publicKey)
-                                .build());
             } else {
                 Log.d("FastPairService", " screen off");
             }
@@ -166,7 +146,6 @@
     public void initiate() {
         mIntentFilter.addAction(Intent.ACTION_SCREEN_ON);
         mIntentFilter.addAction(Intent.ACTION_SCREEN_OFF);
-        mIntentFilter.addAction(ACTION_START_PAIRING);
 
         mLocatorContextWrapper.getContext()
                 .registerReceiver(mScreenBroadcastReceiver, mIntentFilter);
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 cac815b..2ecbaa3 100644
--- a/nearby/service/java/com/android/server/nearby/provider/FastPairDataProvider.java
+++ b/nearby/service/java/com/android/server/nearby/provider/FastPairDataProvider.java
@@ -56,8 +56,11 @@
     private FastPairDataProvider(Context context) {
         mProxyFastPairDataProvider = ProxyFastPairDataProvider.create(
                 context, FastPairDataProviderBase.ACTION_FAST_PAIR_DATA_PROVIDER);
-        Log.d("FastPairService", "the fast pair proxy provider is init"
-                + (mProxyFastPairDataProvider == null));
+        if (mProxyFastPairDataProvider == null) {
+            Log.d("FastPairService", "fail to initiate the fast pair proxy provider");
+        } else {
+            Log.d("FastPairService", "the fast pair proxy provider initiated");
+        }
     }
 
     /** loadFastPairDeviceMetadata. */
diff --git a/nearby/tests/cts/fastpair/Android.bp b/nearby/tests/cts/fastpair/Android.bp
index 60626f1..56dc682 100644
--- a/nearby/tests/cts/fastpair/Android.bp
+++ b/nearby/tests/cts/fastpair/Android.bp
@@ -35,6 +35,7 @@
     test_suites: [
         "cts",
         "general-tests",
+        "mts-tethering",
     ],
     platform_apis: true,
     sdk_version: "module_current",
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/FastPairDataProviderBaseTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/FastPairDataProviderBaseTest.java
index bceca81..bfe71cd 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/FastPairDataProviderBaseTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/FastPairDataProviderBaseTest.java
@@ -20,21 +20,23 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.verify;
 import static org.mockito.MockitoAnnotations.initMocks;
 
 import android.accounts.Account;
+import android.nearby.FastPairAccountKeyDeviceMetadata;
 import android.nearby.FastPairAntispoofkeyDeviceMetadata;
 import android.nearby.FastPairDataProviderBase;
 import android.nearby.FastPairDeviceMetadata;
+import android.nearby.FastPairDiscoveryItem;
 import android.nearby.FastPairEligibleAccount;
 import android.nearby.aidl.FastPairAccountDevicesMetadataRequestParcel;
 import android.nearby.aidl.FastPairAccountKeyDeviceMetadataParcel;
 import android.nearby.aidl.FastPairAntispoofkeyDeviceMetadataParcel;
 import android.nearby.aidl.FastPairAntispoofkeyDeviceMetadataRequestParcel;
 import android.nearby.aidl.FastPairDeviceMetadataParcel;
+import android.nearby.aidl.FastPairDiscoveryItemParcel;
 import android.nearby.aidl.FastPairEligibleAccountParcel;
 import android.nearby.aidl.FastPairEligibleAccountsRequestParcel;
 import android.nearby.aidl.FastPairManageAccountDeviceRequestParcel;
@@ -76,18 +78,14 @@
     private static final int DEVICE_TYPE = 7;
     private static final String DOWNLOAD_COMPANION_APP_DESCRIPTION =
             "DOWNLOAD_COMPANION_APP_DESCRIPTION";
-    private static final int ELIGIBLE_ACCOUNTS_NUM = 2;
     private static final Account ELIGIBLE_ACCOUNT_1 = new Account("abc@google.com", "type1");
     private static final boolean ELIGIBLE_ACCOUNT_1_OPT_IN = true;
     private static final Account ELIGIBLE_ACCOUNT_2 = new Account("def@gmail.com", "type2");
     private static final boolean ELIGIBLE_ACCOUNT_2_OPT_IN = false;
     private static final Account MANAGE_ACCOUNT = new Account("ghi@gmail.com", "type3");
-    private static final ImmutableList<FastPairEligibleAccount> ELIGIBLE_ACCOUNTS =
-            ImmutableList.of(
-                    genHappyPathFastPairEligibleAccount(ELIGIBLE_ACCOUNT_1,
-                            ELIGIBLE_ACCOUNT_1_OPT_IN),
-                    genHappyPathFastPairEligibleAccount(ELIGIBLE_ACCOUNT_2,
-                            ELIGIBLE_ACCOUNT_2_OPT_IN));
+    private static final Account ACCOUNTDEVICES_METADATA_ACCOUNT =
+            new Account("jk@gmail.com", "type4");
+
     private static final int ERROR_CODE_BAD_REQUEST =
             FastPairDataProviderBase.ERROR_CODE_BAD_REQUEST;
     private static final int MANAGE_ACCOUNT_REQUEST_TYPE =
@@ -126,23 +124,79 @@
             "UPDATE_COMPANION_APP_DESCRIPTION";
     private static final String WAIT_LAUNCH_COMPANION_APP_DESCRIPTION =
             "WAIT_LAUNCH_COMPANION_APP_DESCRIPTION";
+    private static final byte[] ACCOUNT_KEY = new byte[] {3};
+    private static final byte[] SHA256_ACCOUNT_KEY_PUBLIC_ADDRESS = new byte[] {2, 8};
     private static final byte[] REQUEST_MODEL_ID = new byte[] {1, 2, 3};
     private static final byte[] ANTI_SPOOFING_KEY = new byte[] {4, 5, 6};
+    private static final String ACTION_URL = "ACTION_URL";
+    private static final int ACTION_URL_TYPE = 5;
+    private static final String APP_NAME = "APP_NAME";
+    private static final int ATTACHMENT_TYPE = 8;
+    private static final byte[] AUTHENTICATION_PUBLIC_KEY_SEC_P256R1 = new byte[] {5, 7};
+    private static final byte[] BLE_RECORD_BYTES = new byte[]{2, 4};
+    private static final int DEBUG_CATEGORY = 9;
+    private static final String DEBUG_MESSAGE = "DEBUG_MESSAGE";
+    private static final String DESCRIPTION = "DESCRIPTION";
+    private static final String DEVICE_NAME = "DEVICE_NAME";
+    private static final String DISPLAY_URL = "DISPLAY_URL";
+    private static final String ENTITY_ID = "ENTITY_ID";
+    private static final String FEATURE_GRAPHIC_URL = "FEATURE_GRAPHIC_URL";
+    private static final long FIRST_OBSERVATION_TIMESTAMP_MILLIS = 8393L;
+    private static final String GROUP_ID = "GROUP_ID";
+    private static final String  ICON_FIFE_URL = "ICON_FIFE_URL";
+    private static final byte[]  ICON_PNG = new byte[]{2, 5};
+    private static final String ID = "ID";
+    private static final long LAST_OBSERVATION_TIMESTAMP_MILLIS = 934234L;
+    private static final int LAST_USER_EXPERIENCE = 93;
+    private static final long LOST_MILLIS = 393284L;
+    private static final String MAC_ADDRESS = "MAC_ADDRESS";
+    private static final String PACKAGE_NAME = "PACKAGE_NAME";
+    private static final long PENDING_APP_INSTALL_TIMESTAMP_MILLIS = 832393L;
+    private static final int RSSI = 9;
+    private static final int STATE = 63;
+    private static final String TITLE = "TITLE";
+    private static final String TRIGGER_ID = "TRIGGER_ID";
+    private static final int TX_POWER = 62;
+    private static final int TYPE = 73;
+    private static final String BLE_ADDRESS = "BLE_ADDRESS";
+
+    private static final int ELIGIBLE_ACCOUNTS_NUM = 2;
+    private static final ImmutableList<FastPairEligibleAccount> ELIGIBLE_ACCOUNTS =
+            ImmutableList.of(
+                    genHappyPathFastPairEligibleAccount(ELIGIBLE_ACCOUNT_1,
+                            ELIGIBLE_ACCOUNT_1_OPT_IN),
+                    genHappyPathFastPairEligibleAccount(ELIGIBLE_ACCOUNT_2,
+                            ELIGIBLE_ACCOUNT_2_OPT_IN));
+    private static final int ACCOUNTKEY_DEVICE_NUM = 2;
+    private static final ImmutableList<FastPairAccountKeyDeviceMetadata>
+            FAST_PAIR_ACCOUNT_DEVICES_METADATA =
+            ImmutableList.of(
+                    genHappyPathFastPairAccountkeyDeviceMetadata(),
+                    genHappyPathFastPairAccountkeyDeviceMetadata());
+
     private static final FastPairAntispoofkeyDeviceMetadataRequestParcel
             FAST_PAIR_ANTI_SPOOF_KEY_DEVICE_METADATA_REQUEST_PARCEL =
             genFastPairAntispoofkeyDeviceMetadataRequestParcel();
+    private static final FastPairAccountDevicesMetadataRequestParcel
+            FAST_PAIR_ACCOUNT_DEVICES_METADATA_REQUEST_PARCEL =
+            genFastPairAccountDevicesMetadataRequestParcel();
     private static final FastPairEligibleAccountsRequestParcel
             FAST_PAIR_ELIGIBLE_ACCOUNTS_REQUEST_PARCEL =
             genFastPairEligibleAccountsRequestParcel();
     private static final FastPairManageAccountRequestParcel
             FAST_PAIR_MANAGE_ACCOUNT_REQUEST_PARCEL =
             genFastPairManageAccountRequestParcel();
+    private static final FastPairManageAccountDeviceRequestParcel
+            FAST_PAIR_MANAGE_ACCOUNT_DEVICE_REQUEST_PARCEL =
+            genFastPairManageAccountDeviceRequestParcel();
     private static final FastPairAntispoofkeyDeviceMetadata
             HAPPY_PATH_FAST_PAIR_ANTI_SPOOF_KEY_DEVICE_METADATA =
             genHappyPathFastPairAntispoofkeyDeviceMetadata();
 
     private @Captor ArgumentCaptor<FastPairEligibleAccountParcel[]>
             mFastPairEligibleAccountParcelsArgumentCaptor;
+    private @Captor ArgumentCaptor<FastPairAccountKeyDeviceMetadataParcel[]>
+            mFastPairAccountKeyDeviceMetadataParcelsArgumentCaptor;
 
     private @Mock FastPairDataProviderBase mMockFastPairDataProviderBase;
     private @Mock IFastPairAntispoofkeyDeviceMetadataCallback.Stub
@@ -174,33 +228,45 @@
 
         // OEM receives request and verifies that it is as expected.
         final ArgumentCaptor<FastPairDataProviderBase.FastPairAntispoofkeyDeviceMetadataRequest>
-                mFastPairAntispoofkeyDeviceMetadataRequestCaptor =
+                fastPairAntispoofkeyDeviceMetadataRequestCaptor =
                 ArgumentCaptor.forClass(
                         FastPairDataProviderBase.FastPairAntispoofkeyDeviceMetadataRequest.class);
         verify(mMockFastPairDataProviderBase).onLoadFastPairAntispoofkeyDeviceMetadata(
-                mFastPairAntispoofkeyDeviceMetadataRequestCaptor.capture(),
+                fastPairAntispoofkeyDeviceMetadataRequestCaptor.capture(),
                 any(FastPairDataProviderBase.FastPairAntispoofkeyDeviceMetadataCallback.class));
-        ensureHappyPathAsExpected(mFastPairAntispoofkeyDeviceMetadataRequestCaptor.getValue());
+        ensureHappyPathAsExpected(fastPairAntispoofkeyDeviceMetadataRequestCaptor.getValue());
 
         // AOSP receives responses and verifies that it is as expected.
         final ArgumentCaptor<FastPairAntispoofkeyDeviceMetadataParcel>
-                mFastPairAntispoofkeyDeviceMetadataParcelCaptor =
+                fastPairAntispoofkeyDeviceMetadataParcelCaptor =
                 ArgumentCaptor.forClass(FastPairAntispoofkeyDeviceMetadataParcel.class);
         verify(mAntispoofkeyDeviceMetadataCallback).onFastPairAntispoofkeyDeviceMetadataReceived(
-                mFastPairAntispoofkeyDeviceMetadataParcelCaptor.capture());
-        ensureHappyPathAsExpected(mFastPairAntispoofkeyDeviceMetadataParcelCaptor.getValue());
+                fastPairAntispoofkeyDeviceMetadataParcelCaptor.capture());
+        ensureHappyPathAsExpected(fastPairAntispoofkeyDeviceMetadataParcelCaptor.getValue());
     }
 
     @Test
     public void testHappyPathLoadFastPairAccountDevicesMetadata() throws Exception {
+        // AOSP sends calls to OEM via Parcelable.
         mHappyPathFastPairDataProvider.asProvider().loadFastPairAccountDevicesMetadata(
-                new FastPairAccountDevicesMetadataRequestParcel(),
+                FAST_PAIR_ACCOUNT_DEVICES_METADATA_REQUEST_PARCEL,
                 mAccountDevicesMetadataCallback);
+
+        // OEM receives request and verifies that it is as expected.
+        final ArgumentCaptor<FastPairDataProviderBase.FastPairAccountDevicesMetadataRequest>
+                fastPairAccountDevicesMetadataRequestCaptor =
+                ArgumentCaptor.forClass(
+                        FastPairDataProviderBase.FastPairAccountDevicesMetadataRequest.class);
         verify(mMockFastPairDataProviderBase).onLoadFastPairAccountDevicesMetadata(
-                any(FastPairDataProviderBase.FastPairAccountDevicesMetadataRequest.class),
+                fastPairAccountDevicesMetadataRequestCaptor.capture(),
                 any(FastPairDataProviderBase.FastPairAccountDevicesMetadataCallback.class));
+        ensureHappyPathAsExpected(fastPairAccountDevicesMetadataRequestCaptor.getValue());
+
+        // AOSP receives responses and verifies that it is as expected.
         verify(mAccountDevicesMetadataCallback).onFastPairAccountDevicesMetadataReceived(
-                any(FastPairAccountKeyDeviceMetadataParcel[].class));
+                mFastPairAccountKeyDeviceMetadataParcelsArgumentCaptor.capture());
+        ensureHappyPathAsExpected(
+                mFastPairAccountKeyDeviceMetadataParcelsArgumentCaptor.getValue());
     }
 
     @Test
@@ -212,13 +278,13 @@
 
         // OEM receives request and verifies that it is as expected.
         final ArgumentCaptor<FastPairDataProviderBase.FastPairEligibleAccountsRequest>
-                mFastPairEligibleAccountsRequestCaptor =
+                fastPairEligibleAccountsRequestCaptor =
                 ArgumentCaptor.forClass(
                         FastPairDataProviderBase.FastPairEligibleAccountsRequest.class);
         verify(mMockFastPairDataProviderBase).onLoadFastPairEligibleAccounts(
-                mFastPairEligibleAccountsRequestCaptor.capture(),
+                fastPairEligibleAccountsRequestCaptor.capture(),
                 any(FastPairDataProviderBase.FastPairEligibleAccountsCallback.class));
-        ensureHappyPathAsExpected(mFastPairEligibleAccountsRequestCaptor.getValue());
+        ensureHappyPathAsExpected(fastPairEligibleAccountsRequestCaptor.getValue());
 
         // AOSP receives responses and verifies that it is as expected.
         verify(mEligibleAccountsCallback).onFastPairEligibleAccountsReceived(
@@ -235,13 +301,13 @@
 
         // OEM receives request and verifies that it is as expected.
         final ArgumentCaptor<FastPairDataProviderBase.FastPairManageAccountRequest>
-                mFastPairManageAccountRequestCaptor =
+                fastPairManageAccountRequestCaptor =
                 ArgumentCaptor.forClass(
                         FastPairDataProviderBase.FastPairManageAccountRequest.class);
         verify(mMockFastPairDataProviderBase).onManageFastPairAccount(
-                mFastPairManageAccountRequestCaptor.capture(),
+                fastPairManageAccountRequestCaptor.capture(),
                 any(FastPairDataProviderBase.FastPairManageActionCallback.class));
-        ensureHappyPathAsExpected(mFastPairManageAccountRequestCaptor.getValue());
+        ensureHappyPathAsExpected(fastPairManageAccountRequestCaptor.getValue());
 
         // AOSP receives SUCCESS response.
         verify(mManageAccountCallback).onSuccess();
@@ -249,12 +315,22 @@
 
     @Test
     public void testHappyPathManageFastPairAccountDevice() throws Exception {
+        // AOSP sends calls to OEM via Parcelable.
         mHappyPathFastPairDataProvider.asProvider().manageFastPairAccountDevice(
-                new FastPairManageAccountDeviceRequestParcel(),
+                FAST_PAIR_MANAGE_ACCOUNT_DEVICE_REQUEST_PARCEL,
                 mManageAccountDeviceCallback);
+
+        // OEM receives request and verifies that it is as expected.
+        final ArgumentCaptor<FastPairDataProviderBase.FastPairManageAccountDeviceRequest>
+                fastPairManageAccountDeviceRequestCaptor =
+                ArgumentCaptor.forClass(
+                        FastPairDataProviderBase.FastPairManageAccountDeviceRequest.class);
         verify(mMockFastPairDataProviderBase).onManageFastPairAccountDevice(
-                any(FastPairDataProviderBase.FastPairManageAccountDeviceRequest.class),
+                fastPairManageAccountDeviceRequestCaptor.capture(),
                 any(FastPairDataProviderBase.FastPairManageActionCallback.class));
+        ensureHappyPathAsExpected(fastPairManageAccountDeviceRequestCaptor.getValue());
+
+        // AOSP receives SUCCESS response.
         verify(mManageAccountDeviceCallback).onSuccess();
     }
 
@@ -273,12 +349,13 @@
     @Test
     public void testErrorPathLoadFastPairAccountDevicesMetadata() throws Exception {
         mErrorPathFastPairDataProvider.asProvider().loadFastPairAccountDevicesMetadata(
-                new FastPairAccountDevicesMetadataRequestParcel(),
+                FAST_PAIR_ACCOUNT_DEVICES_METADATA_REQUEST_PARCEL,
                 mAccountDevicesMetadataCallback);
         verify(mMockFastPairDataProviderBase).onLoadFastPairAccountDevicesMetadata(
                 any(FastPairDataProviderBase.FastPairAccountDevicesMetadataRequest.class),
                 any(FastPairDataProviderBase.FastPairAccountDevicesMetadataCallback.class));
-        verify(mAccountDevicesMetadataCallback).onError(anyInt(), any());
+        verify(mAccountDevicesMetadataCallback).onError(
+                eq(ERROR_CODE_BAD_REQUEST), eq(ERROR_STRING));
     }
 
     @Test
@@ -307,12 +384,12 @@
     @Test
     public void testErrorPathManageFastPairAccountDevice() throws Exception {
         mErrorPathFastPairDataProvider.asProvider().manageFastPairAccountDevice(
-                new FastPairManageAccountDeviceRequestParcel(),
+                FAST_PAIR_MANAGE_ACCOUNT_DEVICE_REQUEST_PARCEL,
                 mManageAccountDeviceCallback);
         verify(mMockFastPairDataProviderBase).onManageFastPairAccountDevice(
                 any(FastPairDataProviderBase.FastPairManageAccountDeviceRequest.class),
                 any(FastPairDataProviderBase.FastPairManageActionCallback.class));
-        verify(mManageAccountDeviceCallback).onError(anyInt(), any());
+        verify(mManageAccountDeviceCallback).onError(eq(ERROR_CODE_BAD_REQUEST), eq(ERROR_STRING));
     }
 
     public static class MyHappyPathProvider extends FastPairDataProviderBase {
@@ -344,7 +421,7 @@
                 @NonNull FastPairAccountDevicesMetadataCallback callback) {
             mMockFastPairDataProviderBase.onLoadFastPairAccountDevicesMetadata(
                     request, callback);
-            callback.onFastPairAccountDevicesMetadataReceived(ImmutableList.of());
+            callback.onFastPairAccountDevicesMetadataReceived(FAST_PAIR_ACCOUNT_DEVICES_METADATA);
         }
 
         @Override
@@ -438,6 +515,17 @@
         return requestParcel;
     }
 
+    /* Generates AccountDevicesMetadataRequestParcel. */
+    private static FastPairAccountDevicesMetadataRequestParcel
+            genFastPairAccountDevicesMetadataRequestParcel() {
+        FastPairAccountDevicesMetadataRequestParcel requestParcel =
+                new FastPairAccountDevicesMetadataRequestParcel();
+
+        requestParcel.account = ACCOUNTDEVICES_METADATA_ACCOUNT;
+
+        return requestParcel;
+    }
+
     /* Generates FastPairEligibleAccountsRequestParcel. */
     private static FastPairEligibleAccountsRequestParcel
             genFastPairEligibleAccountsRequestParcel() {
@@ -458,6 +546,20 @@
         return requestParcel;
     }
 
+    /* Generates FastPairManageAccountDeviceRequestParcel. */
+    private static FastPairManageAccountDeviceRequestParcel
+            genFastPairManageAccountDeviceRequestParcel() {
+        FastPairManageAccountDeviceRequestParcel requestParcel =
+                new FastPairManageAccountDeviceRequestParcel();
+        requestParcel.account = MANAGE_ACCOUNT;
+        requestParcel.requestType = MANAGE_ACCOUNT_REQUEST_TYPE;
+        requestParcel.bleAddress = BLE_ADDRESS;
+        requestParcel.accountKeyDeviceMetadata =
+                genHappyPathFastPairAccountkeyDeviceMetadataParcel();
+
+        return requestParcel;
+    }
+
     /* Generates Happy Path AntispoofkeyDeviceMetadata. */
     private static FastPairAntispoofkeyDeviceMetadata
             genHappyPathFastPairAntispoofkeyDeviceMetadata() {
@@ -469,6 +571,108 @@
         return builder.build();
     }
 
+    /* Generates Happy Path FastPairAccountKeyDeviceMetadata. */
+    private static FastPairAccountKeyDeviceMetadata
+            genHappyPathFastPairAccountkeyDeviceMetadata() {
+        FastPairAccountKeyDeviceMetadata.Builder builder =
+                new FastPairAccountKeyDeviceMetadata.Builder();
+        builder.setAccountKey(ACCOUNT_KEY);
+        builder.setFastPairDeviceMetadata(genHappyPathFastPairDeviceMetadata());
+        builder.setSha256AccountKeyPublicAddress(SHA256_ACCOUNT_KEY_PUBLIC_ADDRESS);
+        builder.setFastPairDiscoveryItem(genHappyPathFastPairDiscoveryItem());
+
+        return builder.build();
+    }
+
+    /* Generates Happy Path FastPairAccountKeyDeviceMetadataParcel. */
+    private static FastPairAccountKeyDeviceMetadataParcel
+            genHappyPathFastPairAccountkeyDeviceMetadataParcel() {
+        FastPairAccountKeyDeviceMetadataParcel parcel =
+                new FastPairAccountKeyDeviceMetadataParcel();
+        parcel.accountKey = ACCOUNT_KEY;
+        parcel.metadata = genHappyPathFastPairDeviceMetadataParcel();
+        parcel.sha256AccountKeyPublicAddress = SHA256_ACCOUNT_KEY_PUBLIC_ADDRESS;
+        parcel.discoveryItem = genHappyPathFastPairDiscoveryItemParcel();
+
+        return parcel;
+    }
+
+    /* Generates Happy Path DiscoveryItem. */
+    private static FastPairDiscoveryItem genHappyPathFastPairDiscoveryItem() {
+        FastPairDiscoveryItem.Builder builder = new FastPairDiscoveryItem.Builder();
+
+        builder.setActionUrl(ACTION_URL);
+        builder.setActionUrlType(ACTION_URL_TYPE);
+        builder.setAppName(APP_NAME);
+        builder.setAttachmentType(ATTACHMENT_TYPE);
+        builder.setAuthenticationPublicKeySecp256r1(AUTHENTICATION_PUBLIC_KEY_SEC_P256R1);
+        builder.setBleRecordBytes(BLE_RECORD_BYTES);
+        builder.setDebugCategory(DEBUG_CATEGORY);
+        builder.setDebugMessage(DEBUG_MESSAGE);
+        builder.setDescription(DESCRIPTION);
+        builder.setDeviceName(DEVICE_NAME);
+        builder.setDisplayUrl(DISPLAY_URL);
+        builder.setEntityId(ENTITY_ID);
+        builder.setFeatureGraphicUrl(FEATURE_GRAPHIC_URL);
+        builder.setFirstObservationTimestampMillis(FIRST_OBSERVATION_TIMESTAMP_MILLIS);
+        builder.setGroupId(GROUP_ID);
+        builder.setIconFfeUrl(ICON_FIFE_URL);
+        builder.setIconPng(ICON_PNG);
+        builder.setId(ID);
+        builder.setLastObservationTimestampMillis(LAST_OBSERVATION_TIMESTAMP_MILLIS);
+        builder.setLastUserExperience(LAST_USER_EXPERIENCE);
+        builder.setLostMillis(LOST_MILLIS);
+        builder.setMacAddress(MAC_ADDRESS);
+        builder.setPackageName(PACKAGE_NAME);
+        builder.setPendingAppInstallTimestampMillis(PENDING_APP_INSTALL_TIMESTAMP_MILLIS);
+        builder.setRssi(RSSI);
+        builder.setState(STATE);
+        builder.setTitle(TITLE);
+        builder.setTriggerId(TRIGGER_ID);
+        builder.setTxPower(TX_POWER);
+        builder.setType(TYPE);
+
+        return builder.build();
+    }
+
+    /* Generates Happy Path DiscoveryItemParcel. */
+    private static FastPairDiscoveryItemParcel genHappyPathFastPairDiscoveryItemParcel() {
+        FastPairDiscoveryItemParcel parcel = new FastPairDiscoveryItemParcel();
+
+        parcel.actionUrl = ACTION_URL;
+        parcel.actionUrlType = ACTION_URL_TYPE;
+        parcel.appName = APP_NAME;
+        parcel.attachmentType = ATTACHMENT_TYPE;
+        parcel.authenticationPublicKeySecp256r1 = AUTHENTICATION_PUBLIC_KEY_SEC_P256R1;
+        parcel.bleRecordBytes = BLE_RECORD_BYTES;
+        parcel.debugCategory = DEBUG_CATEGORY;
+        parcel.debugMessage = DEBUG_MESSAGE;
+        parcel.description = DESCRIPTION;
+        parcel.deviceName = DEVICE_NAME;
+        parcel.displayUrl = DISPLAY_URL;
+        parcel.entityId = ENTITY_ID;
+        parcel.featureGraphicUrl = FEATURE_GRAPHIC_URL;
+        parcel.firstObservationTimestampMillis = FIRST_OBSERVATION_TIMESTAMP_MILLIS;
+        parcel.groupId = GROUP_ID;
+        parcel.iconFifeUrl = ICON_FIFE_URL;
+        parcel.iconPng = ICON_PNG;
+        parcel.id = ID;
+        parcel.lastObservationTimestampMillis = LAST_OBSERVATION_TIMESTAMP_MILLIS;
+        parcel.lastUserExperience = LAST_USER_EXPERIENCE;
+        parcel.lostMillis = LOST_MILLIS;
+        parcel.macAddress = MAC_ADDRESS;
+        parcel.packageName = PACKAGE_NAME;
+        parcel.pendingAppInstallTimestampMillis = PENDING_APP_INSTALL_TIMESTAMP_MILLIS;
+        parcel.rssi = RSSI;
+        parcel.state = STATE;
+        parcel.title = TITLE;
+        parcel.triggerId = TRIGGER_ID;
+        parcel.txPower = TX_POWER;
+        parcel.type = TYPE;
+
+        return parcel;
+    }
+
     /* Generates Happy Path DeviceMetadata. */
     private static FastPairDeviceMetadata genHappyPathFastPairDeviceMetadata() {
         FastPairDeviceMetadata.Builder builder = new FastPairDeviceMetadata.Builder();
@@ -512,6 +716,50 @@
         return builder.build();
     }
 
+    /* Generates Happy Path DeviceMetadataParcel. */
+    private static FastPairDeviceMetadataParcel genHappyPathFastPairDeviceMetadataParcel() {
+        FastPairDeviceMetadataParcel parcel = new FastPairDeviceMetadataParcel();
+
+        parcel.assistantSetupHalfSheet = ASSISTANT_SETUP_HALFSHEET;
+        parcel.assistantSetupNotification = ASSISTANT_SETUP_NOTIFICATION;
+        parcel.bleTxPower = BLE_TX_POWER;
+        parcel.confirmPinDescription = CONFIRM_PIN_DESCRIPTION;
+        parcel.confirmPinTitle = CONFIRM_PIN_TITLE;
+        parcel.connectSuccessCompanionAppInstalled = CONNECT_SUCCESS_COMPANION_APP_INSTALLED;
+        parcel.connectSuccessCompanionAppNotInstalled =
+                CONNECT_SUCCESS_COMPANION_APP_NOT_INSTALLED;
+        parcel.deviceType = DEVICE_TYPE;
+        parcel.downloadCompanionAppDescription = DOWNLOAD_COMPANION_APP_DESCRIPTION;
+        parcel.failConnectGoToSettingsDescription = FAIL_CONNECT_GOTO_SETTINGS_DESCRIPTION;
+        parcel.fastPairTvConnectDeviceNoAccountDescription =
+                FAST_PAIR_TV_CONNECT_DEVICE_NO_ACCOUNT_DESCRIPTION;
+        parcel.image = IMAGE;
+        parcel.imageUrl = IMAGE_URL;
+        parcel.initialNotificationDescription = INITIAL_NOTIFICATION_DESCRIPTION;
+        parcel.initialNotificationDescriptionNoAccount =
+                INITIAL_NOTIFICATION_DESCRIPTION_NO_ACCOUNT;
+        parcel.initialPairingDescription = INITIAL_PAIRING_DESCRIPTION;
+        parcel.intentUri = INTENT_URI;
+        parcel.locale = LOCALE;
+        parcel.openCompanionAppDescription = OPEN_COMPANION_APP_DESCRIPTION;
+        parcel.retroactivePairingDescription = RETRO_ACTIVE_PAIRING_DESCRIPTION;
+        parcel.subsequentPairingDescription = SUBSEQUENT_PAIRING_DESCRIPTION;
+        parcel.syncContactsDescription = SYNC_CONTACT_DESCRPTION;
+        parcel.syncContactsTitle = SYNC_CONTACTS_TITLE;
+        parcel.syncSmsDescription = SYNC_SMS_DESCRIPTION;
+        parcel.syncSmsTitle = SYNC_SMS_TITLE;
+        parcel.triggerDistance = TRIGGER_DISTANCE;
+        parcel.trueWirelessImageUrlCase = TRUE_WIRELESS_IMAGE_URL_CASE;
+        parcel.trueWirelessImageUrlLeftBud = TRUE_WIRELESS_IMAGE_URL_LEFT_BUD;
+        parcel.trueWirelessImageUrlRightBud = TRUE_WIRELESS_IMAGE_URL_RIGHT_BUD;
+        parcel.unableToConnectDescription = UNABLE_TO_CONNECT_DESCRIPTION;
+        parcel.unableToConnectTitle = UNABLE_TO_CONNECT_TITLE;
+        parcel.updateCompanionAppDescription = UPDATE_COMPANION_APP_DESCRIPTION;
+        parcel.waitLaunchCompanionAppDescription = WAIT_LAUNCH_COMPANION_APP_DESCRIPTION;
+
+        return parcel;
+    }
+
     /* Generates Happy Path FastPairEligibleAccount. */
     private static FastPairEligibleAccount genHappyPathFastPairEligibleAccount(
             Account account, boolean optIn) {
@@ -528,18 +776,35 @@
         assertEquals(REQUEST_MODEL_ID, request.getModelId());
     }
 
+    /* Verifies Happy Path AccountDevicesMetadataRequest. */
+    private static void ensureHappyPathAsExpected(
+            FastPairDataProviderBase.FastPairAccountDevicesMetadataRequest request) {
+        assertEquals(ACCOUNTDEVICES_METADATA_ACCOUNT, request.getAccount());
+    }
+
+    /* Verifies Happy Path FastPairEligibleAccountsRequest. */
     @SuppressWarnings("UnusedVariable")
     private static void ensureHappyPathAsExpected(
             FastPairDataProviderBase.FastPairEligibleAccountsRequest request) {
         // No fields since FastPairEligibleAccountsRequest is just a place holder now.
     }
 
+    /* Verifies Happy Path FastPairManageAccountRequest. */
     private static void ensureHappyPathAsExpected(
             FastPairDataProviderBase.FastPairManageAccountRequest request) {
         assertEquals(MANAGE_ACCOUNT, request.getAccount());
         assertEquals(MANAGE_ACCOUNT_REQUEST_TYPE, request.getRequestType());
     }
 
+    /* Verifies Happy Path FastPairManageAccountDeviceRequest. */
+    private static void ensureHappyPathAsExpected(
+            FastPairDataProviderBase.FastPairManageAccountDeviceRequest request) {
+        assertEquals(MANAGE_ACCOUNT, request.getAccount());
+        assertEquals(MANAGE_ACCOUNT_REQUEST_TYPE, request.getRequestType());
+        assertEquals(BLE_ADDRESS, request.getBleAddress());
+        ensureHappyPathAsExpected(request.getAccountKeyDeviceMetadata());
+    }
+
     /* Verifies Happy Path AntispoofkeyDeviceMetadataParcel. */
     private static void ensureHappyPathAsExpected(
             FastPairAntispoofkeyDeviceMetadataParcel metadataParcel) {
@@ -548,6 +813,37 @@
         ensureHappyPathAsExpected(metadataParcel.deviceMetadata);
     }
 
+    /* Verifies Happy Path FastPairAccountKeyDeviceMetadataParcel[]. */
+    private static void ensureHappyPathAsExpected(
+            FastPairAccountKeyDeviceMetadataParcel[] metadataParcels) {
+        assertNotNull(metadataParcels);
+        assertEquals(ACCOUNTKEY_DEVICE_NUM, metadataParcels.length);
+        for (FastPairAccountKeyDeviceMetadataParcel parcel: metadataParcels) {
+            ensureHappyPathAsExpected(parcel);
+        }
+    }
+
+    /* Verifies Happy Path FastPairAccountKeyDeviceMetadataParcel. */
+    private static void ensureHappyPathAsExpected(
+            FastPairAccountKeyDeviceMetadataParcel metadataParcel) {
+        assertNotNull(metadataParcel);
+        assertEquals(ACCOUNT_KEY, metadataParcel.accountKey);
+        assertEquals(SHA256_ACCOUNT_KEY_PUBLIC_ADDRESS,
+                metadataParcel.sha256AccountKeyPublicAddress);
+        ensureHappyPathAsExpected(metadataParcel.metadata);
+        ensureHappyPathAsExpected(metadataParcel.discoveryItem);
+    }
+
+    /* Verifies Happy Path FastPairAccountKeyDeviceMetadata. */
+    private static void ensureHappyPathAsExpected(
+            FastPairAccountKeyDeviceMetadata metadata) {
+        assertEquals(ACCOUNT_KEY, metadata.getAccountKey());
+        assertEquals(SHA256_ACCOUNT_KEY_PUBLIC_ADDRESS,
+                metadata.getSha256AccountKeyPublicAddress());
+        ensureHappyPathAsExpected(metadata.getFastPairDeviceMetadata());
+        ensureHappyPathAsExpected(metadata.getFastPairDiscoveryItem());
+    }
+
     /* Verifies Happy Path DeviceMetadataParcel. */
     private static void ensureHappyPathAsExpected(FastPairDeviceMetadataParcel metadataParcel) {
         assertNotNull(metadataParcel);
@@ -597,7 +893,129 @@
                 metadataParcel.waitLaunchCompanionAppDescription);
     }
 
-    /* Verifies Happy Path EligibleAccounts. */
+    /* Verifies Happy Path DeviceMetadata. */
+    private static void ensureHappyPathAsExpected(FastPairDeviceMetadata metadata) {
+        assertEquals(ASSISTANT_SETUP_HALFSHEET, metadata.getAssistantSetupHalfSheet());
+        assertEquals(ASSISTANT_SETUP_NOTIFICATION, metadata.getAssistantSetupNotification());
+        assertEquals(BLE_TX_POWER, metadata.getBleTxPower());
+        assertEquals(CONFIRM_PIN_DESCRIPTION, metadata.getConfirmPinDescription());
+        assertEquals(CONFIRM_PIN_TITLE, metadata.getConfirmPinTitle());
+        assertEquals(CONNECT_SUCCESS_COMPANION_APP_INSTALLED,
+                metadata.getConnectSuccessCompanionAppInstalled());
+        assertEquals(CONNECT_SUCCESS_COMPANION_APP_NOT_INSTALLED,
+                metadata.getConnectSuccessCompanionAppNotInstalled());
+        assertEquals(DEVICE_TYPE, metadata.getDeviceType());
+        assertEquals(DOWNLOAD_COMPANION_APP_DESCRIPTION,
+                metadata.getDownloadCompanionAppDescription());
+        assertEquals(FAIL_CONNECT_GOTO_SETTINGS_DESCRIPTION,
+                metadata.getFailConnectGoToSettingsDescription());
+        assertEquals(FAST_PAIR_TV_CONNECT_DEVICE_NO_ACCOUNT_DESCRIPTION,
+                metadata.getFastPairTvConnectDeviceNoAccountDescription());
+        assertArrayEquals(IMAGE, metadata.getImage());
+        assertEquals(IMAGE_URL, metadata.getImageUrl());
+        assertEquals(INITIAL_NOTIFICATION_DESCRIPTION,
+                metadata.getInitialNotificationDescription());
+        assertEquals(INITIAL_NOTIFICATION_DESCRIPTION_NO_ACCOUNT,
+                metadata.getInitialNotificationDescriptionNoAccount());
+        assertEquals(INITIAL_PAIRING_DESCRIPTION, metadata.getInitialPairingDescription());
+        assertEquals(INTENT_URI, metadata.getIntentUri());
+        assertEquals(LOCALE, metadata.getLocale());
+        assertEquals(OPEN_COMPANION_APP_DESCRIPTION, metadata.getOpenCompanionAppDescription());
+        assertEquals(RETRO_ACTIVE_PAIRING_DESCRIPTION,
+                metadata.getRetroactivePairingDescription());
+        assertEquals(SUBSEQUENT_PAIRING_DESCRIPTION, metadata.getSubsequentPairingDescription());
+        assertEquals(SYNC_CONTACT_DESCRPTION, metadata.getSyncContactsDescription());
+        assertEquals(SYNC_CONTACTS_TITLE, metadata.getSyncContactsTitle());
+        assertEquals(SYNC_SMS_DESCRIPTION, metadata.getSyncSmsDescription());
+        assertEquals(SYNC_SMS_TITLE, metadata.getSyncSmsTitle());
+        assertEquals(TRIGGER_DISTANCE, metadata.getTriggerDistance(), DELTA);
+        assertEquals(TRUE_WIRELESS_IMAGE_URL_CASE, metadata.getTrueWirelessImageUrlCase());
+        assertEquals(TRUE_WIRELESS_IMAGE_URL_LEFT_BUD, metadata.getTrueWirelessImageUrlLeftBud());
+        assertEquals(TRUE_WIRELESS_IMAGE_URL_RIGHT_BUD,
+                metadata.getTrueWirelessImageUrlRightBud());
+        assertEquals(UNABLE_TO_CONNECT_DESCRIPTION, metadata.getUnableToConnectDescription());
+        assertEquals(UNABLE_TO_CONNECT_TITLE, metadata.getUnableToConnectTitle());
+        assertEquals(UPDATE_COMPANION_APP_DESCRIPTION,
+                metadata.getUpdateCompanionAppDescription());
+        assertEquals(WAIT_LAUNCH_COMPANION_APP_DESCRIPTION,
+                metadata.getWaitLaunchCompanionAppDescription());
+    }
+
+    /* Verifies Happy Path FastPairDiscoveryItemParcel. */
+    private static void ensureHappyPathAsExpected(FastPairDiscoveryItemParcel itemParcel) {
+        assertEquals(ACTION_URL, itemParcel.actionUrl);
+        assertEquals(ACTION_URL_TYPE, itemParcel.actionUrlType);
+        assertEquals(APP_NAME, itemParcel.appName);
+        assertEquals(ATTACHMENT_TYPE, itemParcel.attachmentType);
+        assertArrayEquals(AUTHENTICATION_PUBLIC_KEY_SEC_P256R1,
+                itemParcel.authenticationPublicKeySecp256r1);
+        assertArrayEquals(BLE_RECORD_BYTES, itemParcel.bleRecordBytes);
+        assertEquals(DEBUG_CATEGORY, itemParcel.debugCategory);
+        assertEquals(DEBUG_MESSAGE, itemParcel.debugMessage);
+        assertEquals(DESCRIPTION, itemParcel.description);
+        assertEquals(DEVICE_NAME, itemParcel.deviceName);
+        assertEquals(DISPLAY_URL, itemParcel.displayUrl);
+        assertEquals(ENTITY_ID, itemParcel.entityId);
+        assertEquals(FEATURE_GRAPHIC_URL, itemParcel.featureGraphicUrl);
+        assertEquals(FIRST_OBSERVATION_TIMESTAMP_MILLIS,
+                itemParcel.firstObservationTimestampMillis);
+        assertEquals(GROUP_ID, itemParcel.groupId);
+        assertEquals(ICON_FIFE_URL, itemParcel.iconFifeUrl);
+        assertEquals(ICON_PNG, itemParcel.iconPng);
+        assertEquals(ID, itemParcel.id);
+        assertEquals(LAST_OBSERVATION_TIMESTAMP_MILLIS, itemParcel.lastObservationTimestampMillis);
+        assertEquals(LAST_USER_EXPERIENCE, itemParcel.lastUserExperience);
+        assertEquals(LOST_MILLIS, itemParcel.lostMillis);
+        assertEquals(MAC_ADDRESS, itemParcel.macAddress);
+        assertEquals(PACKAGE_NAME, itemParcel.packageName);
+        assertEquals(PENDING_APP_INSTALL_TIMESTAMP_MILLIS,
+                itemParcel.pendingAppInstallTimestampMillis);
+        assertEquals(RSSI, itemParcel.rssi);
+        assertEquals(STATE, itemParcel.state);
+        assertEquals(TITLE, itemParcel.title);
+        assertEquals(TRIGGER_ID, itemParcel.triggerId);
+        assertEquals(TX_POWER, itemParcel.txPower);
+        assertEquals(TYPE, itemParcel.type);
+    }
+
+    /* Verifies Happy Path FastPairDiscoveryItem. */
+    private static void ensureHappyPathAsExpected(FastPairDiscoveryItem item) {
+        assertEquals(ACTION_URL, item.getActionUrl());
+        assertEquals(ACTION_URL_TYPE, item.getActionUrlType());
+        assertEquals(APP_NAME, item.getAppName());
+        assertEquals(ATTACHMENT_TYPE, item.getAttachmentType());
+        assertArrayEquals(AUTHENTICATION_PUBLIC_KEY_SEC_P256R1,
+                item.getAuthenticationPublicKeySecp256r1());
+        assertArrayEquals(BLE_RECORD_BYTES, item.getBleRecordBytes());
+        assertEquals(DEBUG_CATEGORY, item.getDebugCategory());
+        assertEquals(DEBUG_MESSAGE, item.getDebugMessage());
+        assertEquals(DESCRIPTION, item.getDescription());
+        assertEquals(DEVICE_NAME, item.getDeviceName());
+        assertEquals(DISPLAY_URL, item.getDisplayUrl());
+        assertEquals(ENTITY_ID, item.getEntityId());
+        assertEquals(FEATURE_GRAPHIC_URL, item.getFeatureGraphicUrl());
+        assertEquals(FIRST_OBSERVATION_TIMESTAMP_MILLIS,
+                item.getFirstObservationTimestampMillis());
+        assertEquals(GROUP_ID, item.getGroupId());
+        assertEquals(ICON_FIFE_URL, item.getIconFfeUrl());
+        assertEquals(ICON_PNG, item.getIconPng());
+        assertEquals(ID, item.getId());
+        assertEquals(LAST_OBSERVATION_TIMESTAMP_MILLIS, item.getLastObservationTimestampMillis());
+        assertEquals(LAST_USER_EXPERIENCE, item.getLastUserExperience());
+        assertEquals(LOST_MILLIS, item.getLostMillis());
+        assertEquals(MAC_ADDRESS, item.getMacAddress());
+        assertEquals(PACKAGE_NAME, item.getPackageName());
+        assertEquals(PENDING_APP_INSTALL_TIMESTAMP_MILLIS,
+                item.getPendingAppInstallTimestampMillis());
+        assertEquals(RSSI, item.getRssi());
+        assertEquals(STATE, item.getState());
+        assertEquals(TITLE, item.getTitle());
+        assertEquals(TRIGGER_ID, item.getTriggerId());
+        assertEquals(TX_POWER, item.getTxPower());
+        assertEquals(TYPE, item.getType());
+    }
+
+    /* Verifies Happy Path EligibleAccountParcel[]. */
     private static void ensureHappyPathAsExpected(FastPairEligibleAccountParcel[] accountsParcel) {
         assertEquals(ELIGIBLE_ACCOUNTS_NUM, accountsParcel.length);
         assertEquals(ELIGIBLE_ACCOUNT_1, accountsParcel[0].account);
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceTest.java
new file mode 100644
index 0000000..b7a4690
--- /dev/null
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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 android.nearby.cts;
+
+import android.annotation.TargetApi;
+import android.nearby.FastPairDevice;
+import android.nearby.NearbyDevice;
+import android.os.Build;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.annotation.RequiresApi;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+@TargetApi(Build.VERSION_CODES.TIRAMISU)
+public class NearbyDeviceTest {
+
+    @Test
+    public void test_isValidMedium() {
+        assertThat(NearbyDevice.isValidMedium(1)).isTrue();
+        assertThat(NearbyDevice.isValidMedium(2)).isTrue();
+
+        assertThat(NearbyDevice.isValidMedium(0)).isFalse();
+        assertThat(NearbyDevice.isValidMedium(3)).isFalse();
+    }
+
+    @Test
+    public void test_getMedium_fromChild() {
+        FastPairDevice fastPairDevice = new FastPairDevice.Builder()
+                .setMedium(NearbyDevice.Medium.BLE)
+                .setRssi(-60)
+                .build();
+
+        assertThat(fastPairDevice.getMedium()).isEqualTo(1);
+        assertThat(fastPairDevice.getRssi()).isEqualTo(-60);
+    }
+}
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyFrameworkInitializerTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyFrameworkInitializerTest.java
new file mode 100644
index 0000000..c062e84
--- /dev/null
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyFrameworkInitializerTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2021 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 android.nearby.cts;
+
+import android.annotation.TargetApi;
+import android.nearby.NearbyFrameworkInitializer;
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+// NearbyFrameworkInitializer was added in T
+@RunWith(AndroidJUnit4.class)
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+@TargetApi(Build.VERSION_CODES.TIRAMISU)
+public class NearbyFrameworkInitializerTest {
+
+//    // TODO(b/215435710) This test cannot pass now because our test cannot access system API.
+//    // run "adb root && adb shell setenforce permissive" and uncomment testServicesRegistered,
+//    // test passes.
+//    @Test
+//    public void testServicesRegistered() {
+//        Context ctx = InstrumentationRegistry.getInstrumentation().getContext();
+//        assertNotNull( "NearbyManager not registered",
+//                ctx.getSystemService(Context.NEARBY_SERVICE));
+//    }
+
+    // registerServiceWrappers can only be called during initialization and should throw otherwise
+    @Test(expected = IllegalStateException.class)
+    public void testThrowsException() {
+        NearbyFrameworkInitializer.registerServiceWrappers();
+    }
+}
diff --git a/nearby/tests/unit/Android.bp b/nearby/tests/unit/Android.bp
index 53d9fb6..93ab20a 100644
--- a/nearby/tests/unit/Android.bp
+++ b/nearby/tests/unit/Android.bp
@@ -50,6 +50,6 @@
     ],
     test_suites: [
         "general-tests",
-        "mts",
+        "mts-tethering",
     ],
 }
diff --git a/nearby/tests/unit/src/com/android/server/nearby/fastpair/ModuleTest.java b/nearby/tests/unit/src/com/android/server/nearby/fastpair/ModuleTest.java
new file mode 100644
index 0000000..fafd3b4
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/fastpair/ModuleTest.java
@@ -0,0 +1,64 @@
+/*
+ * 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 src.com.android.server.nearby.fastpair;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.server.nearby.common.eventloop.EventLoop;
+import com.android.server.nearby.common.locator.Locator;
+import com.android.server.nearby.fastpair.FastPairAdvHandler;
+import com.android.server.nearby.fastpair.FastPairModule;
+import com.android.server.nearby.fastpair.cache.FastPairCacheManager;
+import com.android.server.nearby.fastpair.footprint.FootprintsDeviceManager;
+import com.android.server.nearby.fastpair.halfsheet.FastPairHalfSheetManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.MockitoAnnotations;
+
+import java.time.Clock;
+
+import src.com.android.server.nearby.fastpair.testing.MockingLocator;
+
+public class ModuleTest {
+    private Locator mLocator;
+
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mLocator = MockingLocator.withMocksOnly(ApplicationProvider.getApplicationContext());
+        mLocator.bind(new FastPairModule());
+    }
+
+    @Test
+    public void genericConstructor() {
+        assertThat(mLocator.get(FastPairCacheManager.class)).isNotNull();
+        assertThat(mLocator.get(FootprintsDeviceManager.class)).isNotNull();
+        assertThat(mLocator.get(EventLoop.class)).isNotNull();
+        assertThat(mLocator.get(FastPairHalfSheetManager.class)).isNotNull();
+        assertThat(mLocator.get(FastPairAdvHandler.class)).isNotNull();
+        assertThat(mLocator.get(Clock.class)).isNotNull();
+    }
+
+    @Test
+    public void genericDestroy() {
+        mLocator.destroy();
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/fastpair/testing/MockingLocator.java b/nearby/tests/unit/src/com/android/server/nearby/fastpair/testing/MockingLocator.java
new file mode 100644
index 0000000..b261b26
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/fastpair/testing/MockingLocator.java
@@ -0,0 +1,53 @@
+/*
+ * 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 src.com.android.server.nearby.fastpair.testing;
+
+import android.content.Context;
+
+import com.android.server.nearby.common.locator.Locator;
+import com.android.server.nearby.common.locator.LocatorContextWrapper;
+
+/** A locator for tests that, by default, installs mocks for everything that's requested of it. */
+public class MockingLocator extends Locator {
+    private final LocatorContextWrapper mLocatorContextWrapper;
+
+    /**
+     * Creates a MockingLocator with the explicit bindings already configured on the given locator.
+     */
+    public static MockingLocator withBindings(Context context, Locator locator) {
+        Locator mockingLocator = new Locator(context);
+        mockingLocator.bind(new MockingModule());
+        locator.attachParent(mockingLocator);
+        return new MockingLocator(context, locator);
+    }
+
+    /** Creates a MockingLocator with no explicit bindings. */
+    public static MockingLocator withMocksOnly(Context context) {
+        return withBindings(context, new Locator(context));
+    }
+
+    @SuppressWarnings("nullness") // due to passing in this before initialized.
+    private MockingLocator(Context context, Locator locator) {
+        super(context, locator);
+        this.mLocatorContextWrapper = new LocatorContextWrapper(context, this);
+    }
+
+    /** Returns a LocatorContextWrapper with this Locator attached. */
+    public LocatorContextWrapper getContextForTest() {
+        return mLocatorContextWrapper;
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/fastpair/testing/MockingModule.java b/nearby/tests/unit/src/com/android/server/nearby/fastpair/testing/MockingModule.java
new file mode 100644
index 0000000..7938c55
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/fastpair/testing/MockingModule.java
@@ -0,0 +1,39 @@
+/*
+ * 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 src.com.android.server.nearby.fastpair.testing;
+
+import android.content.Context;
+
+import com.android.server.nearby.common.locator.Locator;
+import com.android.server.nearby.common.locator.Module;
+
+
+import org.mockito.Mockito;
+
+/** Module for tests that just provides mocks for anything that's requested of it. */
+public class MockingModule extends Module {
+
+    @Override
+    public void configure(Context context, Class<?> type, Locator locator) {
+        configureMock(type, locator);
+    }
+
+    private <T> void configureMock(Class<T> type, Locator locator) {
+        T mock = Mockito.mock(type);
+        locator.bind(type, mock);
+    }
+}