From 4cb5e25fc546876ddcc500303c0f6c306e564f6b Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Mon, 14 Feb 2022 21:26:44 +0800 Subject: [PATCH 001/412] Fix proto invalid write type While dumpProtoLocked is called, InvalidProtocolBufferException occurred because types are mismatched between platform side and module side. netstats.proto was moved into connectivity module, both the platform(incident.proto) and the module uses protoc-gen-javastream to generate the Java classes from it. It should be fine since platform includes the source of the proto, and jarjar the generated classess in the module to avoid conflict with platform. Bug: 218566849 Test: adb shell incident 3001 adb shell dumpsys netstats --proto atest CtsIncidentHostTestCases:IncidentdTest#testIncidentReportDumpAuto Change-Id: I4654350a59dc1ca1a925785ad37f34aa7b481235 --- framework-t/src/android/net/NetworkIdentity.java | 10 +++++----- .../src/android/net/NetworkIdentitySet.java | 2 +- .../src/android/net/NetworkStatsCollection.java | 14 +++++++------- .../src/android/net/NetworkStatsHistory.java | 16 ++++++++-------- .../android/server/net/NetworkStatsRecorder.java | 4 ++-- .../android/server/net/NetworkStatsService.java | 16 ++++++++-------- 6 files changed, 31 insertions(+), 31 deletions(-) diff --git a/framework-t/src/android/net/NetworkIdentity.java b/framework-t/src/android/net/NetworkIdentity.java index a48f94b66d..da5f88dc3b 100644 --- a/framework-t/src/android/net/NetworkIdentity.java +++ b/framework-t/src/android/net/NetworkIdentity.java @@ -189,14 +189,14 @@ public class NetworkIdentity { public void dumpDebug(ProtoOutputStream proto, long tag) { final long start = proto.start(tag); - proto.write(NetworkIdentityProto.TYPE_FIELD_NUMBER, mType); + proto.write(NetworkIdentityProto.TYPE, mType); // TODO: dump mRatType as well. - proto.write(NetworkIdentityProto.ROAMING_FIELD_NUMBER, mRoaming); - proto.write(NetworkIdentityProto.METERED_FIELD_NUMBER, mMetered); - proto.write(NetworkIdentityProto.DEFAULT_NETWORK_FIELD_NUMBER, mDefaultNetwork); - proto.write(NetworkIdentityProto.OEM_MANAGED_NETWORK_FIELD_NUMBER, mOemManaged); + proto.write(NetworkIdentityProto.ROAMING, mRoaming); + proto.write(NetworkIdentityProto.METERED, mMetered); + proto.write(NetworkIdentityProto.DEFAULT_NETWORK, mDefaultNetwork); + proto.write(NetworkIdentityProto.OEM_MANAGED_NETWORK, mOemManaged); proto.end(start); } diff --git a/framework-t/src/android/net/NetworkIdentitySet.java b/framework-t/src/android/net/NetworkIdentitySet.java index 56461babfe..ad3a958a68 100644 --- a/framework-t/src/android/net/NetworkIdentitySet.java +++ b/framework-t/src/android/net/NetworkIdentitySet.java @@ -222,7 +222,7 @@ public class NetworkIdentitySet extends HashSet { final long start = proto.start(tag); for (NetworkIdentity ident : this) { - ident.dumpDebug(proto, NetworkIdentitySetProto.IDENTITIES_FIELD_NUMBER); + ident.dumpDebug(proto, NetworkIdentitySetProto.IDENTITIES); } proto.end(start); diff --git a/framework-t/src/android/net/NetworkStatsCollection.java b/framework-t/src/android/net/NetworkStatsCollection.java index 67d48f0000..735c44d5c8 100644 --- a/framework-t/src/android/net/NetworkStatsCollection.java +++ b/framework-t/src/android/net/NetworkStatsCollection.java @@ -732,19 +732,19 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W final long start = proto.start(tag); for (Key key : getSortedKeys()) { - final long startStats = proto.start(NetworkStatsCollectionProto.STATS_FIELD_NUMBER); + final long startStats = proto.start(NetworkStatsCollectionProto.STATS); // Key - final long startKey = proto.start(NetworkStatsCollectionStatsProto.KEY_FIELD_NUMBER); - key.ident.dumpDebug(proto, NetworkStatsCollectionKeyProto.IDENTITY_FIELD_NUMBER); - proto.write(NetworkStatsCollectionKeyProto.UID_FIELD_NUMBER, key.uid); - proto.write(NetworkStatsCollectionKeyProto.SET_FIELD_NUMBER, key.set); - proto.write(NetworkStatsCollectionKeyProto.TAG_FIELD_NUMBER, key.tag); + final long startKey = proto.start(NetworkStatsCollectionStatsProto.KEY); + key.ident.dumpDebug(proto, NetworkStatsCollectionKeyProto.IDENTITY); + proto.write(NetworkStatsCollectionKeyProto.UID, key.uid); + proto.write(NetworkStatsCollectionKeyProto.SET, key.set); + proto.write(NetworkStatsCollectionKeyProto.TAG, key.tag); proto.end(startKey); // Value final NetworkStatsHistory history = mStats.get(key); - history.dumpDebug(proto, NetworkStatsCollectionStatsProto.HISTORY_FIELD_NUMBER); + history.dumpDebug(proto, NetworkStatsCollectionStatsProto.HISTORY); proto.end(startStats); } diff --git a/framework-t/src/android/net/NetworkStatsHistory.java b/framework-t/src/android/net/NetworkStatsHistory.java index 822a16e0bb..301fef9441 100644 --- a/framework-t/src/android/net/NetworkStatsHistory.java +++ b/framework-t/src/android/net/NetworkStatsHistory.java @@ -915,18 +915,18 @@ public final class NetworkStatsHistory implements Parcelable { public void dumpDebug(ProtoOutputStream proto, long tag) { final long start = proto.start(tag); - proto.write(NetworkStatsHistoryProto.BUCKET_DURATION_MS_FIELD_NUMBER, bucketDuration); + proto.write(NetworkStatsHistoryProto.BUCKET_DURATION_MS, bucketDuration); for (int i = 0; i < bucketCount; i++) { - final long startBucket = proto.start(NetworkStatsHistoryProto.BUCKETS_FIELD_NUMBER); + final long startBucket = proto.start(NetworkStatsHistoryProto.BUCKETS); - proto.write(NetworkStatsHistoryBucketProto.BUCKET_START_MS_FIELD_NUMBER, + proto.write(NetworkStatsHistoryBucketProto.BUCKET_START_MS, bucketStart[i]); - dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_BYTES_FIELD_NUMBER, rxBytes, i); - dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_PACKETS_FIELD_NUMBER, rxPackets, i); - dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_BYTES_FIELD_NUMBER, txBytes, i); - dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_PACKETS_FIELD_NUMBER, txPackets, i); - dumpDebug(proto, NetworkStatsHistoryBucketProto.OPERATIONS_FIELD_NUMBER, operations, i); + dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_BYTES, rxBytes, i); + dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_PACKETS, rxPackets, i); + dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_BYTES, txBytes, i); + dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_PACKETS, txPackets, i); + dumpDebug(proto, NetworkStatsHistoryBucketProto.OPERATIONS, operations, i); proto.end(startBucket); } diff --git a/service-t/src/com/android/server/net/NetworkStatsRecorder.java b/service-t/src/com/android/server/net/NetworkStatsRecorder.java index a006cd5975..f62765d074 100644 --- a/service-t/src/com/android/server/net/NetworkStatsRecorder.java +++ b/service-t/src/com/android/server/net/NetworkStatsRecorder.java @@ -471,11 +471,11 @@ public class NetworkStatsRecorder { public void dumpDebugLocked(ProtoOutputStream proto, long tag) { final long start = proto.start(tag); if (mPending != null) { - proto.write(NetworkStatsRecorderProto.PENDING_TOTAL_BYTES_FIELD_NUMBER, + proto.write(NetworkStatsRecorderProto.PENDING_TOTAL_BYTES, mPending.getTotalBytes()); } getOrLoadCompleteLocked().dumpDebug(proto, - NetworkStatsRecorderProto.COMPLETE_HISTORY_FIELD_NUMBER); + NetworkStatsRecorderProto.COMPLETE_HISTORY); proto.end(start); } diff --git a/service-t/src/com/android/server/net/NetworkStatsService.java b/service-t/src/com/android/server/net/NetworkStatsService.java index e8b3d4cd13..c8f7f3d567 100644 --- a/service-t/src/com/android/server/net/NetworkStatsService.java +++ b/service-t/src/com/android/server/net/NetworkStatsService.java @@ -2016,15 +2016,15 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // TODO Right now it writes all history. Should it limit to the "since-boot" log? - dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_INTERFACES_FIELD_NUMBER, + dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_INTERFACES, mActiveIfaces); - dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_UID_INTERFACES_FIELD_NUMBER, + dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_UID_INTERFACES, mActiveUidIfaces); - mDevRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.DEV_STATS_FIELD_NUMBER); - mXtRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.XT_STATS_FIELD_NUMBER); - mUidRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.UID_STATS_FIELD_NUMBER); + mDevRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.DEV_STATS); + mXtRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.XT_STATS); + mUidRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.UID_STATS); mUidTagRecorder.dumpDebugLocked(proto, - NetworkStatsServiceDumpProto.UID_TAG_STATS_FIELD_NUMBER); + NetworkStatsServiceDumpProto.UID_TAG_STATS); proto.flush(); } @@ -2034,8 +2034,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { for (int i = 0; i < ifaces.size(); i++) { final long start = proto.start(tag); - proto.write(NetworkInterfaceProto.INTERFACE_FIELD_NUMBER, ifaces.keyAt(i)); - ifaces.valueAt(i).dumpDebug(proto, NetworkInterfaceProto.IDENTITIES_FIELD_NUMBER); + proto.write(NetworkInterfaceProto.INTERFACE, ifaces.keyAt(i)); + ifaces.valueAt(i).dumpDebug(proto, NetworkInterfaceProto.IDENTITIES); proto.end(start); } From 1d87cbdc88a82e95dcf88dcceecf6afb31018eeb Mon Sep 17 00:00:00 2001 From: paulhu Date: Tue, 8 Feb 2022 21:25:28 +0800 Subject: [PATCH 002/412] Rename framework-connectivity-tiramisu to framework-connectivity-t Bug: 215434166 Ignore-AOSP-First: Merge conflict. Will cherry-pick to AOSP afterwards. Test: build, flash, device boot to home. Change-Id: I9ebedf8813cbfa30d979bc35a3b2306715be682b --- Tethering/Android.bp | 2 +- Tethering/apex/Android.bp | 2 +- Tethering/tests/unit/Android.bp | 4 ++-- framework-t/Android.bp | 10 +++++----- framework/Android.bp | 4 ++-- service-t/Android.bp | 6 +++--- service/Android.bp | 2 +- tests/common/Android.bp | 2 +- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Tethering/Android.bp b/Tethering/Android.bp index a26ffa9e6a..2c34426601 100644 --- a/Tethering/Android.bp +++ b/Tethering/Android.bp @@ -50,7 +50,7 @@ java_defaults { ], libs: [ "framework-connectivity", - "framework-connectivity-tiramisu.stubs.module_lib", + "framework-connectivity-t.stubs.module_lib", "framework-statsd.stubs.module_lib", "framework-tethering.impl", "framework-wifi", diff --git a/Tethering/apex/Android.bp b/Tethering/apex/Android.bp index 2734d48517..36e05eeedb 100644 --- a/Tethering/apex/Android.bp +++ b/Tethering/apex/Android.bp @@ -104,7 +104,7 @@ bootclasspath_fragment { name: "com.android.tethering-bootclasspath-fragment", contents: [ "framework-connectivity", - "framework-connectivity-tiramisu", + "framework-connectivity-t", "framework-tethering", ], apex_available: ["com.android.tethering"], diff --git a/Tethering/tests/unit/Android.bp b/Tethering/tests/unit/Android.bp index 224d87a4f4..d1b8380f75 100644 --- a/Tethering/tests/unit/Android.bp +++ b/Tethering/tests/unit/Android.bp @@ -34,7 +34,7 @@ java_library { libs: [ "framework-minus-apex", "framework-connectivity.impl", - "framework-connectivity-tiramisu.impl", + "framework-connectivity-t.impl", "framework-tethering.impl", ], visibility: [ @@ -68,7 +68,7 @@ java_defaults { "framework-minus-apex", "framework-res", "framework-connectivity.impl", - "framework-connectivity-tiramisu.impl", + "framework-connectivity-t.impl", "framework-tethering.impl", "framework-wifi.stubs.module_lib", ], diff --git a/framework-t/Android.bp b/framework-t/Android.bp index 6a911ababc..2ab69b8405 100644 --- a/framework-t/Android.bp +++ b/framework-t/Android.bp @@ -30,7 +30,7 @@ java_defaults { // T, and were moved to the module in T. Other bootclasspath classes in connectivity should go to // framework-connectivity. java_defaults { - name: "framework-connectivity-tiramisu-defaults", + name: "framework-connectivity-t-defaults", sdk_version: "module_current", min_sdk_version: "Tiramisu", defaults: [ @@ -78,8 +78,8 @@ java_defaults { } java_library { - name: "framework-connectivity-tiramisu-pre-jarjar", - defaults: ["framework-connectivity-tiramisu-defaults"], + name: "framework-connectivity-t-pre-jarjar", + defaults: ["framework-connectivity-t-defaults"], libs: [ "framework-bluetooth", "framework-wifi", @@ -92,9 +92,9 @@ java_library { // T, and were moved to the module in T. Other bootclasspath classes in connectivity should go to // framework-connectivity. java_sdk_library { - name: "framework-connectivity-tiramisu", + name: "framework-connectivity-t", defaults: [ - "framework-connectivity-tiramisu-defaults", + "framework-connectivity-t-defaults", "enable-framework-connectivity-t-targets", ], // Do not add static_libs to this library: put them in framework-connectivity instead. diff --git a/framework/Android.bp b/framework/Android.bp index 481f3751ac..66b662b24f 100644 --- a/framework/Android.bp +++ b/framework/Android.bp @@ -77,7 +77,7 @@ java_defaults { ], }, stub_only_libs: [ - "framework-connectivity-tiramisu.stubs.module_lib", + "framework-connectivity-t.stubs.module_lib", ], impl_only_libs: [ "framework-tethering.stubs.module_lib", @@ -90,7 +90,7 @@ java_defaults { "modules-utils-preconditions", ], libs: [ - "framework-connectivity-tiramisu.stubs.module_lib", + "framework-connectivity-t.stubs.module_lib", "unsupportedappusage", ], apex_available: [ diff --git a/service-t/Android.bp b/service-t/Android.bp index 423795ac43..3d9820dd47 100644 --- a/service-t/Android.bp +++ b/service-t/Android.bp @@ -19,10 +19,10 @@ package { default_applicable_licenses: ["Android-Apache-2.0"], } -// This builds T+ services depending on framework-connectivity-tiramisu +// This builds T+ services depending on framework-connectivity-t // hidden symbols separately from the S+ services, to ensure that S+ // services cannot accidentally depend on T+ hidden symbols from -// framework-connectivity-tiramisu. +// framework-connectivity-t. java_library { name: "service-connectivity-tiramisu-pre-jarjar", sdk_version: "system_server_current", @@ -35,7 +35,7 @@ java_library { libs: [ "framework-annotations-lib", "framework-connectivity-pre-jarjar", - "framework-connectivity-tiramisu-pre-jarjar", + "framework-connectivity-t-pre-jarjar", "framework-tethering.stubs.module_lib", "service-connectivity-pre-jarjar", "service-nearby", diff --git a/service/Android.bp b/service/Android.bp index c55cfed0a3..3e9ef1af4b 100644 --- a/service/Android.bp +++ b/service/Android.bp @@ -100,7 +100,7 @@ java_library { libs: [ "framework-annotations-lib", "framework-connectivity-pre-jarjar", - "framework-connectivity-tiramisu.stubs.module_lib", + "framework-connectivity-t.stubs.module_lib", "framework-tethering.stubs.module_lib", "framework-wifi.stubs.module_lib", "unsupportedappusage", diff --git a/tests/common/Android.bp b/tests/common/Android.bp index 87826849da..b23074db09 100644 --- a/tests/common/Android.bp +++ b/tests/common/Android.bp @@ -115,7 +115,7 @@ java_defaults { // meaning @hide APIs in framework-connectivity are resolved before @SystemApi // stubs in framework "framework-connectivity.impl", - "framework-connectivity-tiramisu.impl", + "framework-connectivity-t.impl", "framework-tethering.impl", "framework", From a4cecf2312362f61ff722a6e0d8341f1c8698eb4 Mon Sep 17 00:00:00 2001 From: paulhu Date: Wed, 16 Feb 2022 09:09:19 +0800 Subject: [PATCH 003/412] Rename framework-connectivity-tiramisu to framework-connectivity-t Bug: 215434166 Test: build, flash, device boot to home. Change-Id: I36fdb2a67b9ae9dd67ec38b9e1fa8ffa02772e61 --- nearby/halfsheet/Android.bp | 2 +- nearby/service/Android.bp | 2 +- nearby/tests/cts/fastpair/Android.bp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/nearby/halfsheet/Android.bp b/nearby/halfsheet/Android.bp index 2b352546e1..486a3ff3af 100644 --- a/nearby/halfsheet/Android.bp +++ b/nearby/halfsheet/Android.bp @@ -28,7 +28,7 @@ android_app { certificate: ":com.android.nearby.halfsheetcertificate", libs: [ "framework-bluetooth", - "framework-connectivity-tiramisu", + "framework-connectivity-t", "nearby-service-string", ], static_libs: [ diff --git a/nearby/service/Android.bp b/nearby/service/Android.bp index 8f6a227120..6743c211c1 100644 --- a/nearby/service/Android.bp +++ b/nearby/service/Android.bp @@ -53,7 +53,7 @@ java_library { libs: [ "framework-bluetooth.stubs.module_lib", // TODO(b/215722418): Change to framework-bluetooth once fixed "error_prone_annotations", - "framework-connectivity-tiramisu.impl", + "framework-connectivity-t.impl", "framework-statsd.stubs.module_lib", ], static_libs: [ diff --git a/nearby/tests/cts/fastpair/Android.bp b/nearby/tests/cts/fastpair/Android.bp index 56dc682183..6cf455781c 100644 --- a/nearby/tests/cts/fastpair/Android.bp +++ b/nearby/tests/cts/fastpair/Android.bp @@ -29,7 +29,7 @@ android_test { ], libs: [ "android.test.base", - "framework-connectivity-tiramisu.impl", + "framework-connectivity-t.impl", ], srcs: ["src/**/*.java"], test_suites: [ From 6f9a6836cde92dd318d2ec84696a7d214ba11e30 Mon Sep 17 00:00:00 2001 From: Xinyi Zhou Date: Wed, 16 Feb 2022 17:00:42 -0800 Subject: [PATCH 004/412] Add DeviceName and account to initial paring description https://photos.app.goo.gl/Jwhge7hvKda2vY767 Test: Built and verified manually Bug: 196262706 Change-Id: I44481b8a65a9edeed858f5df66a7b49d76f5a7e2 --- .../nearby/fastpair/FastPairAdvHandler.java | 9 +++++---- .../android/server/nearby/util/DataUtils.java | 17 ++++++++++++----- 2 files changed, 17 insertions(+), 9 deletions(-) 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 f8d5a62e07..97eaab2db9 100644 --- a/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java +++ b/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java @@ -69,6 +69,8 @@ public class FastPairAdvHandler { public void handleBroadcast(NearbyDevice device) { FastPairDevice fastPairDevice = (FastPairDevice) device; mBleAddress = fastPairDevice.getBluetoothAddress(); + List accountList = + FastPairDataProvider.getInstance().loadFastPairEligibleAccounts(); if (FastPairDecoder.checkModelId(fastPairDevice.getData())) { byte[] model = FastPairDecoder.getModelId(fastPairDevice.getData()); Log.d("FastPairService", @@ -79,16 +81,15 @@ public class FastPairAdvHandler { FastPairDataProvider.getInstance() .loadFastPairAntispoofkeyDeviceMetadata(model); Locator.get(mContext, FastPairHalfSheetManager.class).showHalfSheet( - DataUtils.toScanFastPairStoreItem(response, mBleAddress)); + DataUtils.toScanFastPairStoreItem( + response, mBleAddress, + accountList.isEmpty() ? null : accountList.get(0).name)); } catch (IllegalStateException e) { Log.e(TAG, "OEM does not construct fast pair data proxy correctly"); } - } else { // Start to process bloom filter try { - List accountList = - FastPairDataProvider.getInstance().loadFastPairEligibleAccounts(); Log.d(TAG, "account list size" + accountList.size()); byte[] bloomFilterByteArray = FastPairDecoder .getBloomFilter(fastPairDevice.getData()); diff --git a/nearby/service/java/com/android/server/nearby/util/DataUtils.java b/nearby/service/java/com/android/server/nearby/util/DataUtils.java index ce738c8c66..bad14bf058 100644 --- a/nearby/service/java/com/android/server/nearby/util/DataUtils.java +++ b/nearby/service/java/com/android/server/nearby/util/DataUtils.java @@ -17,6 +17,7 @@ package com.android.server.nearby.util; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import service.proto.Cache.ScanFastPairStoreItem; import service.proto.Cache.StoredDiscoveryItem; @@ -36,16 +37,18 @@ public final class DataUtils { * Converts a {@link GetObservedDeviceResponse} to a {@link ScanFastPairStoreItem}. */ public static ScanFastPairStoreItem toScanFastPairStoreItem( - GetObservedDeviceResponse observedDeviceResponse, @NonNull String bleAddress) { + GetObservedDeviceResponse observedDeviceResponse, + @NonNull String bleAddress, @Nullable String account) { Device device = observedDeviceResponse.getDevice(); + String deviceName = device.getName(); return ScanFastPairStoreItem.newBuilder() .setAddress(bleAddress) .setActionUrl(device.getIntentUri()) - .setDeviceName(device.getName()) + .setDeviceName(deviceName) .setIconPng(observedDeviceResponse.getImage()) .setIconFifeUrl(device.getImageUrl()) .setAntiSpoofingPublicKey(device.getAntiSpoofingKeyPair().getPublicKey()) - .setFastPairStrings(getFastPairStrings(observedDeviceResponse)) + .setFastPairStrings(getFastPairStrings(observedDeviceResponse, deviceName, account)) .build(); } @@ -76,13 +79,17 @@ public final class DataUtils { + "]"; } - private static FastPairStrings getFastPairStrings(GetObservedDeviceResponse response) { + private static FastPairStrings getFastPairStrings(GetObservedDeviceResponse response, + String deviceName, @Nullable String account) { ObservedDeviceStrings strings = response.getStrings(); return FastPairStrings.newBuilder() .setTapToPairWithAccount(strings.getInitialNotificationDescription()) .setTapToPairWithoutAccount( strings.getInitialNotificationDescriptionNoAccount()) - .setInitialPairingDescription(strings.getInitialPairingDescription()) + .setInitialPairingDescription(account == null + ? strings.getInitialNotificationDescriptionNoAccount() + : String.format(strings.getInitialPairingDescription(), + deviceName, account)) .setPairingFinishedCompanionAppInstalled( strings.getConnectSuccessCompanionAppInstalled()) .setPairingFinishedCompanionAppNotInstalled( From 40c7e1d460b4c34a93f8b8e00e71d45c36ab85ab Mon Sep 17 00:00:00 2001 From: junyulai Date: Thu, 17 Feb 2022 14:48:26 +0800 Subject: [PATCH 005/412] Fix testDataMigrationUtils fail on R device Since the test is using JUnit3, which doesn't support rules or assumeTrue, the IgnoreUpTo rule does not take effect. Replace with a return statement as short term solution to unblock presumit. Test: atest CtsNetTestCasesLatestSdk:android.net.cts.NetworkStatsManagerTest on R device Bug: 219099881 Ignore-AOSP-First: Required API is not in AOSP yet Change-Id: I6056da19324715237c6fdac0975fb89de8a04416 --- .../net/src/android/net/cts/NetworkStatsManagerTest.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkStatsManagerTest.java b/tests/cts/net/src/android/net/cts/NetworkStatsManagerTest.java index de4f41b175..eba7a769e1 100644 --- a/tests/cts/net/src/android/net/cts/NetworkStatsManagerTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkStatsManagerTest.java @@ -33,8 +33,6 @@ import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_UID; import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_UID_TAG; import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_XT; -import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2; - import android.app.AppOpsManager; import android.app.usage.NetworkStats; import android.app.usage.NetworkStatsManager; @@ -63,7 +61,6 @@ import android.util.Log; import com.android.compatibility.common.util.ShellIdentityUtils; import com.android.compatibility.common.util.SystemUtil; import com.android.modules.utils.build.SdkLevel; -import com.android.testutils.DevSdkIgnoreRule; import java.io.IOException; import java.io.InputStream; @@ -852,8 +849,9 @@ public class NetworkStatsManagerTest extends InstrumentationTestCase { } @AppModeFull - @DevSdkIgnoreRule.IgnoreUpTo(SC_V2) public void testDataMigrationUtils() throws Exception { + if (!SdkLevel.isAtLeastT()) return; + final List prefixes = List.of(PREFIX_UID, PREFIX_XT, PREFIX_UID_TAG); for (final String prefix : prefixes) { final long duration = TextUtils.equals(PREFIX_XT, prefix) ? TimeUnit.HOURS.toMillis(1) From 72bcb41a66cb36742d9a76f8c930997be32ae059 Mon Sep 17 00:00:00 2001 From: Chun Zhang Date: Wed, 16 Feb 2022 23:26:32 -0800 Subject: [PATCH 006/412] Add AccountKeys to FastPairAccountDevicesMetadataRequest. Test: CTS test. Bug: 204780849 Change-Id: I57a529a476f04c78d95763562e61ae55fb774fa9 Ignore-AOSP-First: nearby_not_in_aosp_yet CTS-Coverage-Bug: 205591293 --- framework-t/api/system-current.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/framework-t/api/system-current.txt b/framework-t/api/system-current.txt index cc8f6b2a44..0cf488ef6c 100644 --- a/framework-t/api/system-current.txt +++ b/framework-t/api/system-current.txt @@ -101,6 +101,7 @@ package android.nearby { public static class FastPairDataProviderBase.FastPairAccountDevicesMetadataRequest { method @NonNull public android.accounts.Account getAccount(); + method @NonNull public java.util.Collection getAccountKeys(); } public static interface FastPairDataProviderBase.FastPairAntispoofkeyDeviceMetadataCallback { From b9ea92a15d7ab5816ee89c4934bccd001322f14b Mon Sep 17 00:00:00 2001 From: Xinyi Zhou Date: Thu, 17 Feb 2022 16:27:24 -0800 Subject: [PATCH 007/412] Add FastPairClient This works as an API interface for UX to communitcate with backend. Test: Built band verified flow manually Bug: 196262706 Change-Id: I018e0f967f50d58772b746618bbf15391072b490 --- .../java/android/nearby/FastPairClient.java | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 nearby/framework/java/android/nearby/FastPairClient.java diff --git a/nearby/framework/java/android/nearby/FastPairClient.java b/nearby/framework/java/android/nearby/FastPairClient.java new file mode 100644 index 0000000000..7ac048126c --- /dev/null +++ b/nearby/framework/java/android/nearby/FastPairClient.java @@ -0,0 +1,94 @@ +/* + * 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; + +import android.annotation.BinderThread; +import android.content.Context; +import android.nearby.aidl.IFastPairClient; +import android.nearby.aidl.IFastPairStatusCallback; +import android.os.Handler; +import android.os.IBinder; +import android.os.RemoteException; +import android.util.Log; + +import java.lang.ref.WeakReference; + +/** + * 0p API for controlling Fast Pair. It communicates between main thread and service. + * + * @hide + */ +public class FastPairClient { + + private static final String TAG = "FastPairClient"; + private final IBinder mBinder; + private final WeakReference mWeakContext; + IFastPairClient mFastPairClient; + PairStatusCallbackIBinder mPairStatusCallbackIBinder; + + public FastPairClient(Context context, IBinder binder) { + mBinder = binder; + mFastPairClient = IFastPairClient.Stub.asInterface(mBinder); + mWeakContext = new WeakReference<>(context); + } + + /** + * Registers a callback at service to get UI updates. + */ + public void registerHalfSheet(FastPairStatusCallback fastPairStatusCallback) { + if (mPairStatusCallbackIBinder != null) { + return; + } + mPairStatusCallbackIBinder = new PairStatusCallbackIBinder(fastPairStatusCallback); + try { + mFastPairClient.registerHalfSheet(mPairStatusCallbackIBinder); + } catch (RemoteException e) { + Log.w(TAG, "Failed to register fastPairStatusCallback", e); + } + } + + /** + * Pairs the device at service. + */ + public void connect(FastPairDevice fastPairDevice) { + try { + mFastPairClient.connect(fastPairDevice); + } catch (RemoteException e) { + Log.w(TAG, "Failed to connect Fast Pair device" + fastPairDevice, e); + } + } + + private class PairStatusCallbackIBinder extends IFastPairStatusCallback.Stub { + private final FastPairStatusCallback mStatusCallback; + + private PairStatusCallbackIBinder(FastPairStatusCallback fastPairStatusCallback) { + mStatusCallback = fastPairStatusCallback; + } + + @BinderThread + @Override + public synchronized void onPairUpdate(FastPairDevice fastPairDevice, + PairStatusMetadata pairStatusMetadata) { + Context context = mWeakContext.get(); + if (context != null) { + Handler handler = new Handler(context.getMainLooper()); + handler.post(() -> + mStatusCallback.onPairUpdate(fastPairDevice, pairStatusMetadata)); + } + } + } +} From e6a18d81afb10351b08b08fda5c9ff850164bbf8 Mon Sep 17 00:00:00 2001 From: Xinyi Zhou Date: Thu, 17 Feb 2022 16:48:12 -0800 Subject: [PATCH 008/412] toString method for ScanFastPairStoreItem helps debug Test: Build Bug: 218771606 Change-Id: If017c953602679a3dda8bbfc9137cc5483c19187 --- .../com/android/server/nearby/util/DataUtils.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/nearby/service/java/com/android/server/nearby/util/DataUtils.java b/nearby/service/java/com/android/server/nearby/util/DataUtils.java index bad14bf058..0b01bc0b49 100644 --- a/nearby/service/java/com/android/server/nearby/util/DataUtils.java +++ b/nearby/service/java/com/android/server/nearby/util/DataUtils.java @@ -52,6 +52,20 @@ public final class DataUtils { .build(); } + /** + * Prints readable string for a {@link ScanFastPairStoreItem}. + */ + public static String toString(ScanFastPairStoreItem item) { + return "ScanFastPairStoreItem=[address:" + item.getAddress() + + ", actionUr:" + item.getActionUrl() + + ", deviceName:" + item.getDeviceName() + + ", iconPng:" + item.getIconPng() + + ", iconFifeUrl:" + item.getIconFifeUrl() + + ", antiSpoofingKeyPair:" + item.getAntiSpoofingPublicKey() + + ", fastPairStrings:" + toString(item.getFastPairStrings()) + + "]"; + } + /** * Prints readable string for a {@link FastPairStrings} */ From 582f4d3989757b573c329b26522fa747977aaaeb Mon Sep 17 00:00:00 2001 From: Chun Zhang Date: Thu, 17 Feb 2022 14:20:47 -0800 Subject: [PATCH 009/412] Fix coverage issue. Somehow this cl can fix coverage build: https://android-build.googleplex.com/builds/abtd/run/L25300000953113292 Bug: 216634361 Test: atest NearbyUnitTests Change-Id: Ic3dcdb954c4bc0671d84d6b0c9dc577206064cb6 --- nearby/tests/unit/Android.bp | 2 +- .../nearby/common/ble/BleSightingTest.java | 98 ------------------- 2 files changed, 1 insertion(+), 99 deletions(-) delete mode 100644 nearby/tests/unit/src/com/android/server/nearby/common/ble/BleSightingTest.java diff --git a/nearby/tests/unit/Android.bp b/nearby/tests/unit/Android.bp index 55ec6459e0..50c395afc5 100644 --- a/nearby/tests/unit/Android.bp +++ b/nearby/tests/unit/Android.bp @@ -43,7 +43,7 @@ android_test { "platform-test-annotations", "service-nearby", "truth-prebuilt", - "Robolectric_all-target", + // "Robolectric_all-target", ], test_suites: [ "general-tests", diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/ble/BleSightingTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/ble/BleSightingTest.java deleted file mode 100644 index d356d8e652..0000000000 --- a/nearby/tests/unit/src/com/android/server/nearby/common/ble/BleSightingTest.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.nearby.common.ble; - -import static com.google.common.truth.Truth.assertThat; - -import static java.nio.charset.StandardCharsets.UTF_8; - -import android.bluetooth.BluetoothDevice; - -import androidx.test.ext.junit.runners.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.shadows.ShadowBluetoothDevice; - -import java.util.concurrent.TimeUnit; - - -@RunWith(AndroidJUnit4.class) -public class BleSightingTest { - private static final String DEVICE_NAME = "device1"; - private static final String OTHER_DEVICE_NAME = "device2"; - private static final long TIME_EPOCH_MILLIS = 123456; - private static final long OTHER_TIME_EPOCH_MILLIS = 456789; - private static final int RSSI = 1; - private static final int OTHER_RSSI = 2; - - private final BluetoothDevice mBluetoothDevice1 = - ShadowBluetoothDevice.newInstance("00:11:22:33:44:55"); - private final BluetoothDevice mBluetoothDevice2 = - ShadowBluetoothDevice.newInstance("AA:BB:CC:DD:EE:FF"); - - - @Test - public void testEquals() { - BleSighting sighting = buildBleSighting(mBluetoothDevice1, DEVICE_NAME, - TIME_EPOCH_MILLIS, RSSI); - BleSighting sighting2 = - buildBleSighting(mBluetoothDevice1, DEVICE_NAME, TIME_EPOCH_MILLIS, RSSI); - assertThat(sighting.equals(sighting2)).isTrue(); - assertThat(sighting2.equals(sighting)).isTrue(); - assertThat(sighting.hashCode()).isEqualTo(sighting2.hashCode()); - - // Transitive property. - BleSighting sighting3 = - buildBleSighting(mBluetoothDevice1, DEVICE_NAME, TIME_EPOCH_MILLIS, RSSI); - assertThat(sighting2.equals(sighting3)).isTrue(); - assertThat(sighting.equals(sighting3)).isTrue(); - - // Set different values for each field, one at a time. - sighting2 = buildBleSighting(mBluetoothDevice2, DEVICE_NAME, TIME_EPOCH_MILLIS, RSSI); - assertSightingsNotEquals(sighting, sighting2); - - sighting2 = buildBleSighting(mBluetoothDevice1, OTHER_DEVICE_NAME, TIME_EPOCH_MILLIS, RSSI); - assertSightingsNotEquals(sighting, sighting2); - - sighting2 = buildBleSighting(mBluetoothDevice1, DEVICE_NAME, OTHER_TIME_EPOCH_MILLIS, RSSI); - assertSightingsNotEquals(sighting, sighting2); - - sighting2 = buildBleSighting(mBluetoothDevice1, DEVICE_NAME, TIME_EPOCH_MILLIS, OTHER_RSSI); - assertSightingsNotEquals(sighting, sighting2); - } - - - /** Builds a BleSighting instance which will correctly match filters by device name. */ - private static BleSighting buildBleSighting( - BluetoothDevice bluetoothDevice, String deviceName, long timeEpochMillis, int rssi) { - byte[] nameBytes = deviceName.getBytes(UTF_8); - byte[] bleRecordBytes = new byte[nameBytes.length + 2]; - bleRecordBytes[0] = (byte) (nameBytes.length + 1); - bleRecordBytes[1] = 0x09; // Value of private BleRecord.DATA_TYPE_LOCAL_NAME_COMPLETE; - System.arraycopy(nameBytes, 0, bleRecordBytes, 2, nameBytes.length); - - return new BleSighting( - bluetoothDevice, bleRecordBytes, rssi, - TimeUnit.MILLISECONDS.toNanos(timeEpochMillis)); - } - - private static void assertSightingsNotEquals(BleSighting sighting1, BleSighting sighting2) { - assertThat(sighting1.equals(sighting2)).isFalse(); - assertThat(sighting1.hashCode()).isNotEqualTo(sighting2.hashCode()); - } -} From a474e32d770c946fe39e5fa62b1c0d08cd0293e4 Mon Sep 17 00:00:00 2001 From: weicesun Date: Wed, 23 Feb 2022 00:05:56 +0000 Subject: [PATCH 010/412] remove no use file Test: unit test Bug: 16851373 Change-Id: Iafac71d989805df8c88f794f0309446720d76131 --- .../nearby/fastpair/FastPairAdvHandler.java | 2 +- .../nearby/fastpair/FastPairManager.java | 2 +- .../server/nearby/util/FastPairDecoder.java | 258 ------------------ 3 files changed, 2 insertions(+), 260 deletions(-) delete mode 100644 nearby/service/java/com/android/server/nearby/util/FastPairDecoder.java 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 b12e2633a1..141d5d9a7e 100644 --- a/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java +++ b/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java @@ -27,13 +27,13 @@ import android.nearby.FastPairDevice; import android.nearby.NearbyDevice; import android.util.Log; +import com.android.server.nearby.common.ble.decode.FastPairDecoder; import com.android.server.nearby.common.bloomfilter.BloomFilter; import com.android.server.nearby.common.bloomfilter.FastPairBloomFilterHasher; 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.DataUtils; -import com.android.server.nearby.util.FastPairDecoder; import com.android.server.nearby.util.Hex; import java.util.List; 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 9e1a7181c0..ca5ac336ca 100644 --- a/nearby/service/java/com/android/server/nearby/fastpair/FastPairManager.java +++ b/nearby/service/java/com/android/server/nearby/fastpair/FastPairManager.java @@ -41,6 +41,7 @@ import android.util.Log; import androidx.annotation.NonNull; +import com.android.server.nearby.common.ble.decode.FastPairDecoder; import com.android.server.nearby.common.bluetooth.BluetoothException; import com.android.server.nearby.common.bluetooth.fastpair.FastPairConnection; import com.android.server.nearby.common.bluetooth.fastpair.FastPairDualConnection; @@ -57,7 +58,6 @@ 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.pairinghandler.PairingProgressHandlerBase; -import com.android.server.nearby.util.FastPairDecoder; import com.android.server.nearby.util.ForegroundThread; import com.android.server.nearby.util.Hex; diff --git a/nearby/service/java/com/android/server/nearby/util/FastPairDecoder.java b/nearby/service/java/com/android/server/nearby/util/FastPairDecoder.java deleted file mode 100644 index 6021ff6986..0000000000 --- a/nearby/service/java/com/android/server/nearby/util/FastPairDecoder.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.nearby.util; - -import android.annotation.Nullable; -import android.bluetooth.le.ScanRecord; -import android.os.ParcelUuid; -import android.util.SparseArray; - -import com.android.server.nearby.common.ble.BleFilter; -import com.android.server.nearby.common.ble.BleRecord; - -import java.util.Arrays; - -/** - * Parses Fast Pair information out of {@link BleRecord}s. - * - *

There are 2 different packet formats that are supported, which is used can be determined by - * packet length: - * - *

For 3-byte packets, the full packet is the model ID. - * - *

For all other packets, the first byte is the header, followed by the model ID, followed by - * zero or more extra fields. Each field has its own header byte followed by the field value. The - * packet header is formatted as 0bVVVLLLLR (V = version, L = model ID length, R = reserved) and - * each extra field header is 0bLLLLTTTT (L = field length, T = field type). - */ -public class FastPairDecoder { - - private static final int FIELD_TYPE_BLOOM_FILTER = 0; - private static final int FIELD_TYPE_BLOOM_FILTER_SALT = 1; - private static final int FIELD_TYPE_BLOOM_FILTER_NO_NOTIFICATION = 2; - private static final int FIELD_TYPE_BATTERY = 3; - private static final int FIELD_TYPE_BATTERY_NO_NOTIFICATION = 4; - public static final int FIELD_TYPE_CONNECTION_STATE = 5; - private static final int FIELD_TYPE_RANDOM_RESOLVABLE_DATA = 6; - - - /** FE2C is the 16-bit Service UUID. The rest is the base UUID. See BluetoothUuid (hidden). */ - private static final ParcelUuid FAST_PAIR_SERVICE_PARCEL_UUID = - ParcelUuid.fromString("0000FE2C-0000-1000-8000-00805F9B34FB"); - - /** The filter you use to scan for Fast Pair BLE advertisements. */ - public static final BleFilter FILTER = - new BleFilter.Builder().setServiceData(FAST_PAIR_SERVICE_PARCEL_UUID, - new byte[0]).build(); - - // NOTE: Ensure that all bitmasks are always ints, not bytes so that bitshifting works correctly - // without needing worry about signing errors. - private static final int HEADER_VERSION_BITMASK = 0b11100000; - private static final int HEADER_LENGTH_BITMASK = 0b00011110; - private static final int HEADER_VERSION_OFFSET = 5; - private static final int HEADER_LENGTH_OFFSET = 1; - - private static final int EXTRA_FIELD_LENGTH_BITMASK = 0b11110000; - private static final int EXTRA_FIELD_TYPE_BITMASK = 0b00001111; - private static final int EXTRA_FIELD_LENGTH_OFFSET = 4; - private static final int EXTRA_FIELD_TYPE_OFFSET = 0; - - private static final int MIN_ID_LENGTH = 3; - private static final int MAX_ID_LENGTH = 14; - private static final int HEADER_INDEX = 0; - private static final int HEADER_LENGTH = 1; - private static final int FIELD_HEADER_LENGTH = 1; - - // Not using java.util.IllegalFormatException because it is unchecked. - private static class IllegalFormatException extends Exception { - private IllegalFormatException(String message) { - super(message); - } - } - - /** - * Gets model id data from broadcast - */ - @Nullable - public static byte[] getModelId(@Nullable byte[] serviceData) { - if (serviceData == null) { - return null; - } - - if (serviceData.length >= MIN_ID_LENGTH) { - if (serviceData.length == MIN_ID_LENGTH) { - // If the length == 3, all bytes are the ID. See flag docs for more about - // endianness. - return serviceData; - } else { - // Otherwise, the first byte is a header which contains the length of the big-endian - // model ID that follows. The model ID will be trimmed if it contains leading zeros. - int idIndex = 1; - int end = idIndex + getIdLength(serviceData); - while (serviceData[idIndex] == 0 && end - idIndex > MIN_ID_LENGTH) { - idIndex++; - } - return Arrays.copyOfRange(serviceData, idIndex, end); - } - } - return null; - } - - /** Gets the FastPair service data array if available, otherwise returns null. */ - @Nullable - public static byte[] getServiceDataArray(BleRecord bleRecord) { - return bleRecord.getServiceData(FAST_PAIR_SERVICE_PARCEL_UUID); - } - - /** Gets the FastPair service data array if available, otherwise returns null. */ - @Nullable - public static byte[] getServiceDataArray(ScanRecord scanRecord) { - return scanRecord.getServiceData(FAST_PAIR_SERVICE_PARCEL_UUID); - } - - /** Gets the bloom filter from the extra fields if available, otherwise returns null. */ - @Nullable - public static byte[] getBloomFilter(@Nullable byte[] serviceData) { - return getExtraField(serviceData, FIELD_TYPE_BLOOM_FILTER); - } - - /** Gets the bloom filter salt from the extra fields if available, otherwise returns null. */ - @Nullable - public static byte[] getBloomFilterSalt(byte[] serviceData) { - return getExtraField(serviceData, FIELD_TYPE_BLOOM_FILTER_SALT); - } - - /** - * Gets the suppress notification with bloom filter from the extra fields if available, - * otherwise returns null. - */ - @Nullable - public static byte[] getBloomFilterNoNotification(@Nullable byte[] serviceData) { - return getExtraField(serviceData, FIELD_TYPE_BLOOM_FILTER_NO_NOTIFICATION); - } - - /** - * Get random resolvableData - */ - @Nullable - public static byte[] getRandomResolvableData(byte[] serviceData) { - return getExtraField(serviceData, FIELD_TYPE_RANDOM_RESOLVABLE_DATA); - } - - @Nullable - private static byte[] getExtraField(@Nullable byte[] serviceData, int fieldId) { - if (serviceData == null || serviceData.length < HEADER_INDEX + HEADER_LENGTH) { - return null; - } - try { - return getExtraFields(serviceData).get(fieldId); - } catch (IllegalFormatException e) { - return null; - } - } - - /** Gets extra field data at the end of the packet, defined by the extra field header. */ - private static SparseArray getExtraFields(byte[] serviceData) - throws IllegalFormatException { - SparseArray extraFields = new SparseArray<>(); - if (getVersion(serviceData) != 0) { - return extraFields; - } - int headerIndex = getFirstExtraFieldHeaderIndex(serviceData); - while (headerIndex < serviceData.length) { - int length = getExtraFieldLength(serviceData, headerIndex); - int index = headerIndex + FIELD_HEADER_LENGTH; - int type = getExtraFieldType(serviceData, headerIndex); - int end = index + length; - if (extraFields.get(type) == null) { - if (end <= serviceData.length) { - extraFields.put(type, Arrays.copyOfRange(serviceData, index, end)); - } else { - throw new IllegalFormatException( - "Invalid length, " + end + " is longer than service data size " - + serviceData.length); - } - } - headerIndex = end; - } - return extraFields; - } - - /** Checks whether or not a valid ID is included in the service data packet. */ - public static boolean hasBeaconIdBytes(BleRecord bleRecord) { - byte[] serviceData = bleRecord.getServiceData(FAST_PAIR_SERVICE_PARCEL_UUID); - return checkModelId(serviceData); - } - - /** Check whether byte array is FastPair model id or not. */ - public static boolean checkModelId(@Nullable byte[] scanResult) { - return scanResult != null - // The 3-byte format has no header byte (all bytes are the ID). - && (scanResult.length == MIN_ID_LENGTH - // Header byte exists. We support only format version 0. (A different version - // indicates - // a breaking change in the format.) - || (scanResult.length > MIN_ID_LENGTH - && getVersion(scanResult) == 0 - && isIdLengthValid(scanResult))); - } - - /** Checks whether or not bloom filter is included in the service data packet. */ - public static boolean hasBloomFilter(BleRecord bleRecord) { - return (getBloomFilter(getServiceDataArray(bleRecord)) != null - || getBloomFilterNoNotification(getServiceDataArray(bleRecord)) != null); - } - - /** Checks whether or not bloom filter is included in the service data packet. */ - public static boolean hasBloomFilter(ScanRecord scanRecord) { - return (getBloomFilter(getServiceDataArray(scanRecord)) != null - || getBloomFilterNoNotification(getServiceDataArray(scanRecord)) != null); - } - - private static int getVersion(byte[] serviceData) { - return serviceData.length == MIN_ID_LENGTH - ? 0 - : (serviceData[HEADER_INDEX] & HEADER_VERSION_BITMASK) >> HEADER_VERSION_OFFSET; - } - - private static int getIdLength(byte[] serviceData) { - return serviceData.length == MIN_ID_LENGTH - ? MIN_ID_LENGTH - : (serviceData[HEADER_INDEX] & HEADER_LENGTH_BITMASK) >> HEADER_LENGTH_OFFSET; - } - - private static int getFirstExtraFieldHeaderIndex(byte[] serviceData) { - return HEADER_INDEX + HEADER_LENGTH + getIdLength(serviceData); - } - - private static int getExtraFieldLength(byte[] serviceData, int extraFieldIndex) { - return (serviceData[extraFieldIndex] & EXTRA_FIELD_LENGTH_BITMASK) - >> EXTRA_FIELD_LENGTH_OFFSET; - } - - private static int getExtraFieldType(byte[] serviceData, int extraFieldIndex) { - return (serviceData[extraFieldIndex] & EXTRA_FIELD_TYPE_BITMASK) >> EXTRA_FIELD_TYPE_OFFSET; - } - - private static boolean isIdLengthValid(byte[] serviceData) { - int idLength = getIdLength(serviceData); - return MIN_ID_LENGTH <= idLength - && idLength <= MAX_ID_LENGTH - && idLength + HEADER_LENGTH <= serviceData.length; - } -} - From 1ae0343a5f7187f9a40c8a9329bb9c09b8bc8616 Mon Sep 17 00:00:00 2001 From: weicesun Date: Wed, 23 Feb 2022 00:00:36 +0000 Subject: [PATCH 011/412] Add unit test for fast pair manager Test: unit test Bug: 202335820 Change-Id: Ieed334c89b09a1e3525d46d6c6fa8ee92fdef89f --- .../nearby/fastpair/FastPairAdvHandler.java | 1 - .../halfsheet/FastPairHalfSheetManager.java | 25 ++- .../server/nearby/util/Environment.java | 4 +- .../FastPairHalfSheetManagerTest.java | 147 ++++++++++++++++++ 4 files changed, 168 insertions(+), 9 deletions(-) create mode 100644 nearby/tests/unit/src/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManagerTest.java 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 b12e2633a1..6a296c2753 100644 --- a/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java +++ b/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java @@ -47,7 +47,6 @@ import service.proto.Rpcs; public class FastPairAdvHandler { Context mContext; String mBleAddress; - /** The types about how the bloomfilter is processed. */ public enum ProcessBloomFilterType { IGNORE, // The bloomfilter is not handled. e.g. distance is too far away. diff --git a/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManager.java b/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManager.java index cfac90402f..42839b24f8 100644 --- a/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManager.java +++ b/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManager.java @@ -33,7 +33,7 @@ import android.os.Bundle; import android.os.UserHandle; import android.util.Log; -import com.android.server.nearby.common.locator.Locator; +import com.android.server.nearby.common.locator.LocatorContextWrapper; import com.android.server.nearby.fastpair.FastPairController; import com.android.server.nearby.fastpair.cache.DiscoveryItem; import com.android.server.nearby.util.Environment; @@ -47,20 +47,28 @@ import service.proto.Cache; * Fast Pair ux manager for half sheet. */ public class FastPairHalfSheetManager { - private static final String ACTIVITY_INTENT_ACTION = "android.nearby.SHOW_HALFSHEET"; + static final String ACTIVITY_INTENT_ACTION = "android.nearby.SHOW_HALFSHEET"; private static final String HALF_SHEET_CLASS_NAME = "com.android.nearby.halfsheet.HalfSheetActivity"; private String mHalfSheetApkPkgName; private Context mContext; + private LocatorContextWrapper mLocatorContextWrapper; /** * Construct function */ public FastPairHalfSheetManager(Context context) { mContext = context; + mLocatorContextWrapper = new LocatorContextWrapper(context); } + /** + * Construct function for test + */ + public FastPairHalfSheetManager(LocatorContextWrapper locatorContextWrapper) { + mLocatorContextWrapper = locatorContextWrapper; + } /** * Invokes half sheet in the other apk. This function can only be called in Nearby because other @@ -68,13 +76,18 @@ public class FastPairHalfSheetManager { */ public void showHalfSheet(Cache.ScanFastPairStoreItem scanFastPairStoreItem) { try { - if (mContext != null) { + if (mLocatorContextWrapper != null) { String packageName = getHalfSheetApkPkgName(); + if (packageName == null) { + Log.e("FastPairHalfSheetManager", "package name is null"); + return; + } HalfSheetCallback callback = new HalfSheetCallback(); - callback.setmFastPairController(Locator.get(mContext, FastPairController.class)); + callback.setmFastPairController( + mLocatorContextWrapper.getLocator().get(FastPairController.class)); Bundle bundle = new Bundle(); bundle.putBinder(EXTRA_BINDER, callback); - mContext + mLocatorContextWrapper .startActivityAsUser(new Intent(ACTIVITY_INTENT_ACTION) .putExtra(EXTRA_HALF_SHEET_INFO, scanFastPairStoreItem.toByteArray()) @@ -153,7 +166,7 @@ public class FastPairHalfSheetManager { if (mHalfSheetApkPkgName != null) { return mHalfSheetApkPkgName; } - List resolveInfos = mContext + List resolveInfos = mLocatorContextWrapper .getPackageManager().queryIntentActivities( new Intent(ACTION_RESOURCES_APK), PackageManager.MATCH_SYSTEM_ONLY); diff --git a/nearby/service/java/com/android/server/nearby/util/Environment.java b/nearby/service/java/com/android/server/nearby/util/Environment.java index e7277cd2d8..d397862b77 100644 --- a/nearby/service/java/com/android/server/nearby/util/Environment.java +++ b/nearby/service/java/com/android/server/nearby/util/Environment.java @@ -33,7 +33,7 @@ public class Environment { /** * The path where the Nearby apex is mounted. - * Current value = "/apex/com.android.nearby" + * Current value = "/apex/com.android.tethering" */ private static final String NEARBY_APEX_PATH = new File("/apex", NEARBY_APEX_NAME).getAbsolutePath(); @@ -55,7 +55,7 @@ public class Environment { /** * Returns true if the app is in the nearby apex, false otherwise. - * Checks if the app's path starts with "/apex/com.android.nearby". + * Checks if the app's path starts with "/apex/com.android.tethering". */ public static boolean isAppInNearbyApex(ApplicationInfo appInfo) { return appInfo.sourceDir.startsWith(NEARBY_APEX_PATH); diff --git a/nearby/tests/unit/src/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManagerTest.java b/nearby/tests/unit/src/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManagerTest.java new file mode 100644 index 0000000000..ab18f54344 --- /dev/null +++ b/nearby/tests/unit/src/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManagerTest.java @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.nearby.fastpair.halfsheet; + + +import static com.android.server.nearby.fastpair.halfsheet.FastPairHalfSheetManager.ACTIVITY_INTENT_ACTION; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.os.UserHandle; + +import com.android.server.nearby.common.locator.Locator; +import com.android.server.nearby.common.locator.LocatorContextWrapper; +import com.android.server.nearby.fastpair.FastPairController; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.ArrayList; +import java.util.List; + +import service.proto.Cache; + +public class FastPairHalfSheetManagerTest { + private static final String BLEADDRESS = "11:22:44:66"; + private static final String NAME = "device_name"; + private FastPairHalfSheetManager mFastPairHalfSheetManager; + private Cache.ScanFastPairStoreItem mScanFastPairStoreItem; + @Mock + LocatorContextWrapper mContextWrapper; + @Mock + ResolveInfo mResolveInfo; + @Mock + PackageManager mPackageManager; + @Mock + Locator mLocator; + @Mock + FastPairController mFastPairController; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + + + mScanFastPairStoreItem = Cache.ScanFastPairStoreItem.newBuilder() + .setAddress(BLEADDRESS) + .setDeviceName(NAME) + .build(); + } + + @Test + public void verifyFastPairHalfSheetManagerBehavior() { + mLocator.overrideBindingForTest(FastPairController.class, mFastPairController); + ResolveInfo resolveInfo = new ResolveInfo(); + List resolveInfoList = new ArrayList<>(); + + + mPackageManager = mock(PackageManager.class); + when(mContextWrapper.getPackageManager()).thenReturn(mPackageManager); + resolveInfo.activityInfo = new ActivityInfo(); + ApplicationInfo applicationInfo = new ApplicationInfo(); + applicationInfo.sourceDir = "/apex/com.android.tethering"; + applicationInfo.packageName = "test.package"; + resolveInfo.activityInfo.applicationInfo = applicationInfo; + resolveInfoList.add(resolveInfo); + when(mPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(resolveInfoList); + when(mPackageManager.canRequestPackageInstalls()).thenReturn(false); + + mFastPairHalfSheetManager = + new FastPairHalfSheetManager(mContextWrapper); + + when(mContextWrapper.getLocator()).thenReturn(mLocator); + + ArgumentCaptor intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class); + + mFastPairHalfSheetManager.showHalfSheet(mScanFastPairStoreItem); + + verify(mContextWrapper, atLeastOnce()) + .startActivityAsUser(intentArgumentCaptor.capture(), eq(UserHandle.CURRENT)); + Intent launchIntent = intentArgumentCaptor.getValue(); + assertThat(launchIntent.getAction()).isEqualTo(ACTIVITY_INTENT_ACTION); + } + + @Test + public void verifyFastPairHalfSheetManagerHalfSheetApkNotValidBehavior() { + mLocator.overrideBindingForTest(FastPairController.class, mFastPairController); + ResolveInfo resolveInfo = new ResolveInfo(); + List resolveInfoList = new ArrayList<>(); + + + mPackageManager = mock(PackageManager.class); + when(mContextWrapper.getPackageManager()).thenReturn(mPackageManager); + resolveInfo.activityInfo = new ActivityInfo(); + ApplicationInfo applicationInfo = new ApplicationInfo(); + // application directory is wrong + applicationInfo.sourceDir = "/apex/com.android.nearby"; + applicationInfo.packageName = "test.package"; + resolveInfo.activityInfo.applicationInfo = applicationInfo; + resolveInfoList.add(resolveInfo); + when(mPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(resolveInfoList); + when(mPackageManager.canRequestPackageInstalls()).thenReturn(false); + + mFastPairHalfSheetManager = + new FastPairHalfSheetManager(mContextWrapper); + + when(mContextWrapper.getLocator()).thenReturn(mLocator); + + ArgumentCaptor intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class); + + mFastPairHalfSheetManager.showHalfSheet(mScanFastPairStoreItem); + + verify(mContextWrapper, never()) + .startActivityAsUser(intentArgumentCaptor.capture(), eq(UserHandle.CURRENT)); + + } +} From e0eab9f8b26bbb98f6f01fee65ee7268287ccaf2 Mon Sep 17 00:00:00 2001 From: Xinyi Zhou Date: Thu, 17 Feb 2022 17:52:14 -0800 Subject: [PATCH 012/412] Add FastPairService in server Test: Built band verified flow manually Bug: 196262706 Change-Id: I391a4c8e7cd083f346c8c63a60d3e0edf2b9b06a --- .../java/android/nearby/FastPairClient.java | 5 ++ .../fastpair/halfsheet/FastPairService.java | 88 +++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairService.java diff --git a/nearby/framework/java/android/nearby/FastPairClient.java b/nearby/framework/java/android/nearby/FastPairClient.java index 7ac048126c..dc70d71133 100644 --- a/nearby/framework/java/android/nearby/FastPairClient.java +++ b/nearby/framework/java/android/nearby/FastPairClient.java @@ -40,6 +40,11 @@ public class FastPairClient { IFastPairClient mFastPairClient; PairStatusCallbackIBinder mPairStatusCallbackIBinder; + /** + * The Ibinder instance should be from + * {@link com.android.server.nearby.fastpair.halfsheet.FastPairService} so that the client can + * talk with the service. + */ public FastPairClient(Context context, IBinder binder) { mBinder = binder; mFastPairClient = IFastPairClient.Stub.asInterface(mBinder); diff --git a/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairService.java b/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairService.java new file mode 100644 index 0000000000..53c2c12870 --- /dev/null +++ b/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairService.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.nearby.fastpair.halfsheet; + +import static com.android.server.nearby.fastpair.Constant.TAG; + +import android.nearby.FastPairDevice; +import android.nearby.FastPairStatusCallback; +import android.nearby.PairStatusMetadata; +import android.nearby.aidl.IFastPairClient; +import android.nearby.aidl.IFastPairStatusCallback; +import android.os.IBinder; +import android.os.RemoteException; +import android.util.Log; + +import com.android.server.nearby.fastpair.FastPairController; + +/** + * Service implementing Fast Pair functionality. + * + * @hide + */ +public class FastPairService extends IFastPairClient.Stub { + + private IBinder mStatusCallbackProxy; + private FastPairController mFastPairController; + private FastPairStatusCallback mFastPairStatusCallback; + + /** + * Registers the Binder call back in the server notifies the proxy when there is an update + * in the server. + */ + @Override + public void registerHalfSheet(IFastPairStatusCallback iFastPairStatusCallback) { + mStatusCallbackProxy = iFastPairStatusCallback.asBinder(); + mFastPairStatusCallback = new FastPairStatusCallback() { + @Override + public void onPairUpdate(FastPairDevice fastPairDevice, + PairStatusMetadata pairStatusMetadata) { + try { + iFastPairStatusCallback.onPairUpdate(fastPairDevice, pairStatusMetadata); + } catch (RemoteException e) { + Log.w(TAG, "Failed to update pair status.", e); + } + } + }; + } + + /** + * Unregisters the Binder call back in the server. + */ + @Override + public void unregisterHalfSheet(IFastPairStatusCallback iFastPairStatusCallback) { + mStatusCallbackProxy = null; + mFastPairStatusCallback = null; + } + + /** + * Asks the Fast Pair service to pair the device. + */ + @Override + public void connect(FastPairDevice fastPairDevice) {} + + public FastPairStatusCallback getPairStatusCallback() { + return mFastPairStatusCallback; + } + + /** + * Sets function for Fast Pair controller. + */ + public void setFastPairController(FastPairController fastPairController) { + mFastPairController = fastPairController; + } +} From 5ceb6f5538fc6041c286ae072632b2c99cd60531 Mon Sep 17 00:00:00 2001 From: Chun Zhang Date: Wed, 16 Feb 2022 23:12:05 -0800 Subject: [PATCH 013/412] Add AccountKeys to FastPairAccountDevicesMetadataRequest. Test: CTS test. Bug: 204780849 Change-Id: I93d94a89e760189b9a537db4ceabfad75c759e52 --- .../nearby/FastPairDataProviderBase.java | 42 ++++++++++++++++++- .../android/nearby/aidl/ByteArrayParcel.aidl | 25 +++++++++++ ...irAccountDevicesMetadataRequestParcel.aidl | 2 + .../nearby/fastpair/FastPairAdvHandler.java | 4 +- .../nearby/provider/FastPairDataProvider.java | 28 ++++++++++++- .../cts/FastPairDataProviderBaseTest.java | 11 +++++ 6 files changed, 106 insertions(+), 6 deletions(-) create mode 100644 nearby/framework/java/android/nearby/aidl/ByteArrayParcel.aidl diff --git a/nearby/framework/java/android/nearby/FastPairDataProviderBase.java b/nearby/framework/java/android/nearby/FastPairDataProviderBase.java index f7af7b82c1..57467b7984 100644 --- a/nearby/framework/java/android/nearby/FastPairDataProviderBase.java +++ b/nearby/framework/java/android/nearby/FastPairDataProviderBase.java @@ -21,6 +21,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.nearby.aidl.ByteArrayParcel; import android.nearby.aidl.FastPairAccountDevicesMetadataRequestParcel; import android.nearby.aidl.FastPairAccountKeyDeviceMetadataParcel; import android.nearby.aidl.FastPairAntispoofkeyDeviceMetadataRequestParcel; @@ -40,7 +41,9 @@ import android.util.Log; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; /** * Base class for fast pair providers outside the system server. @@ -223,7 +226,18 @@ public abstract class FastPairDataProviderBase { } /** - * Class for reading FastPairAccountDevicesMetadataRequest. + * Class for reading FastPairAccountDevicesMetadataRequest, which specifies the Fast Pair + * account and the allow list of the FastPair device keys saved to the account (i.e., FastPair + * accountKeys). + * + * A Fast Pair accountKey is created when a Fast Pair device is saved to an account. It is per + * Fast Pair device per account. + * + * To retrieve all Fast Pair accountKeys saved to an account, the caller needs to set + * account with an empty allow list. + * + * To retrieve metadata of a selected list of Fast Pair devices saved to an account, the caller + * needs to set account with a non-empty allow list. */ public static class FastPairAccountDevicesMetadataRequest { @@ -233,10 +247,34 @@ public abstract class FastPairDataProviderBase { final FastPairAccountDevicesMetadataRequestParcel metaDataRequestParcel) { this.mMetadataRequestParcel = metaDataRequestParcel; } - /** Get account. */ + + /** + * Get FastPair account, whose Fast Pair devices' metadata is requested. + * + * @return a FastPair account. + */ public @NonNull Account getAccount() { return this.mMetadataRequestParcel.account; } + + /** + * Get allowlist of Fast Pair devices using a collection of accountKeys. + * Note that as a special case, empty list actually means all FastPair devices under the + * account instead of none. + * + * @return allowlist of Fast Pair devices using a collection of accountKeys. + */ + public @NonNull Collection getAccountKeys() { + if (this.mMetadataRequestParcel.accountKeys == null) { + return new ArrayList(0); + } + List accountKeys = + new ArrayList<>(this.mMetadataRequestParcel.accountKeys.length); + for (ByteArrayParcel accountKey : this.mMetadataRequestParcel.accountKeys) { + accountKeys.add(accountKey.byteArray); + } + return accountKeys; + } } /** Class for reading FastPairEligibleAccountsRequest. */ diff --git a/nearby/framework/java/android/nearby/aidl/ByteArrayParcel.aidl b/nearby/framework/java/android/nearby/aidl/ByteArrayParcel.aidl new file mode 100644 index 0000000000..53c73bdf6e --- /dev/null +++ b/nearby/framework/java/android/nearby/aidl/ByteArrayParcel.aidl @@ -0,0 +1,25 @@ +/* + * 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.aidl; + +/** + * This is to support 2D byte arrays. + * {@hide} + */ +parcelable ByteArrayParcel { + byte[] byteArray; +} \ No newline at end of file diff --git a/nearby/framework/java/android/nearby/aidl/FastPairAccountDevicesMetadataRequestParcel.aidl b/nearby/framework/java/android/nearby/aidl/FastPairAccountDevicesMetadataRequestParcel.aidl index 2cff6321da..5953935fef 100644 --- a/nearby/framework/java/android/nearby/aidl/FastPairAccountDevicesMetadataRequestParcel.aidl +++ b/nearby/framework/java/android/nearby/aidl/FastPairAccountDevicesMetadataRequestParcel.aidl @@ -17,6 +17,7 @@ package android.nearby.aidl; import android.accounts.Account; +import android.nearby.aidl.ByteArrayParcel; /** * Request details for Metadata of Fast Pair devices associated with an account. @@ -24,4 +25,5 @@ import android.accounts.Account; */ parcelable FastPairAccountDevicesMetadataRequestParcel { Account account; + ByteArrayParcel[] accountKeys; } \ No newline at end of file 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 556b60b09e..60db6f586f 100644 --- a/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java +++ b/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java @@ -100,8 +100,8 @@ public class FastPairAdvHandler { } for (Account account : accountList) { List listDevices = - FastPairDataProvider.getInstance().loadFastPairDevicesWithAccountKey( - account); + FastPairDataProvider.getInstance() + .loadFastPairDeviceWithAccountKey(account); Data.FastPairDeviceWithAccountKey recognizedDevice = findRecognizedDevice(listDevices, new BloomFilter(bloomFilterByteArray, 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 03484a02a9..f4db57822f 100644 --- a/nearby/service/java/com/android/server/nearby/provider/FastPairDataProvider.java +++ b/nearby/service/java/com/android/server/nearby/provider/FastPairDataProvider.java @@ -20,6 +20,7 @@ import android.accounts.Account; import android.annotation.Nullable; import android.content.Context; import android.nearby.FastPairDataProviderBase; +import android.nearby.aidl.ByteArrayParcel; import android.nearby.aidl.FastPairAccountDevicesMetadataRequestParcel; import android.nearby.aidl.FastPairAntispoofkeyDeviceMetadataRequestParcel; import android.nearby.aidl.FastPairEligibleAccountsRequestParcel; @@ -32,6 +33,7 @@ import androidx.annotation.WorkerThread; import com.android.server.nearby.common.bloomfilter.BloomFilter; import com.android.server.nearby.fastpair.footprint.FastPairUploadInfo; +import java.util.ArrayList; import java.util.List; import service.proto.Data; @@ -142,16 +144,38 @@ public class FastPairDataProvider { } /** - * Loads FastPair devices for a given account. + * Loads FastPair device accountKeys for a given account, but not other detailed fields. * * @throws IllegalStateException If ProxyFastPairDataProvider is not available. */ - public List loadFastPairDevicesWithAccountKey( + public List loadFastPairDeviceWithAccountKey( Account account) { + return loadFastPairDeviceWithAccountKey(account, new ArrayList(0)); + } + + /** + * Loads FastPair devices for a list of accountKeys of a given account. + * + * @param account The account of the FastPair devices. + * @param accountKeys The allow list of FastPair devices if it is not empty. Otherwise, the + * function returns accountKeys of all FastPair devices under the account, + * without detailed fields. + * + * @throws IllegalStateException If ProxyFastPairDataProvider is not available. + */ + public List loadFastPairDeviceWithAccountKey( + Account account, List accountKeys) { if (mProxyFastPairDataProvider != null) { FastPairAccountDevicesMetadataRequestParcel requestParcel = new FastPairAccountDevicesMetadataRequestParcel(); requestParcel.account = account; + requestParcel.accountKeys = new ByteArrayParcel[accountKeys.size()]; + int i = 0; + for (byte[] accountKey : accountKeys) { + requestParcel.accountKeys[i] = new ByteArrayParcel(); + requestParcel.accountKeys[i].byteArray = accountKey; + i = i + 1; + } return Utils.convertToFastPairDevicesWithAccountKey( mProxyFastPairDataProvider.loadFastPairAccountDevicesMetadata(requestParcel)); } 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 71fc3308a4..fd9e29439c 100644 --- a/nearby/tests/cts/fastpair/src/android/nearby/cts/FastPairDataProviderBaseTest.java +++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/FastPairDataProviderBaseTest.java @@ -30,6 +30,7 @@ import android.nearby.FastPairDataProviderBase; import android.nearby.FastPairDeviceMetadata; import android.nearby.FastPairDiscoveryItem; import android.nearby.FastPairEligibleAccount; +import android.nearby.aidl.ByteArrayParcel; import android.nearby.aidl.FastPairAccountDevicesMetadataRequestParcel; import android.nearby.aidl.FastPairAccountKeyDeviceMetadataParcel; import android.nearby.aidl.FastPairAntispoofkeyDeviceMetadataParcel; @@ -85,6 +86,7 @@ public class FastPairDataProviderBaseTest { private static final Account MANAGE_ACCOUNT = new Account("ghi@gmail.com", "type3"); private static final Account ACCOUNTDEVICES_METADATA_ACCOUNT = new Account("jk@gmail.com", "type4"); + private static final int NUM_ACCOUNT_DEVICES = 2; private static final int ERROR_CODE_BAD_REQUEST = FastPairDataProviderBase.ERROR_CODE_BAD_REQUEST; @@ -125,6 +127,7 @@ public class FastPairDataProviderBaseTest { 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[] ACCOUNT_KEY_2 = new byte[] {9, 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}; @@ -533,6 +536,11 @@ public class FastPairDataProviderBaseTest { new FastPairAccountDevicesMetadataRequestParcel(); requestParcel.account = ACCOUNTDEVICES_METADATA_ACCOUNT; + requestParcel.accountKeys = new ByteArrayParcel[NUM_ACCOUNT_DEVICES]; + requestParcel.accountKeys[0] = new ByteArrayParcel(); + requestParcel.accountKeys[1] = new ByteArrayParcel(); + requestParcel.accountKeys[0].byteArray = ACCOUNT_KEY; + requestParcel.accountKeys[1].byteArray = ACCOUNT_KEY_2; return requestParcel; } @@ -793,6 +801,9 @@ public class FastPairDataProviderBaseTest { private static void ensureHappyPathAsExpected( FastPairDataProviderBase.FastPairAccountDevicesMetadataRequest request) { assertThat(request.getAccount()).isEqualTo(ACCOUNTDEVICES_METADATA_ACCOUNT); + assertThat(request.getAccountKeys().size()).isEqualTo(ACCOUNTKEY_DEVICE_NUM); + assertThat(request.getAccountKeys()).contains(ACCOUNT_KEY); + assertThat(request.getAccountKeys()).contains(ACCOUNT_KEY_2); } /* Verifies Happy Path FastPairEligibleAccountsRequest. */ From a473e8d9342c9ab7f62fcccb52547d1b229003b6 Mon Sep 17 00:00:00 2001 From: Xinyi Zhou Date: Thu, 17 Feb 2022 21:32:38 -0800 Subject: [PATCH 014/412] Fast Pair Half Sheet server side implementation Refactor doc: go/fp-halfsheet-aosp Bug: 196262706 Bug: 196644352 Bug: 218771606 Test: Built band verified flow manually Change-Id: I86d81cd582482889946185a86399ebca21c84e56 --- .../server/nearby/fastpair/Constant.java | 11 -- .../nearby/fastpair/FastPairController.java | 117 ++++++++---------- .../nearby/fastpair/FastPairManager.java | 13 +- .../halfsheet/FastPairHalfSheetManager.java | 58 +++++---- .../fastpair/halfsheet/FastPairService.java | 8 +- .../fastpair/halfsheet/HalfSheetCallback.java | 52 -------- .../FastPairHalfSheetManagerTest.java | 11 -- 7 files changed, 103 insertions(+), 167 deletions(-) delete mode 100644 nearby/service/java/com/android/server/nearby/fastpair/halfsheet/HalfSheetCallback.java 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 5958007035..0695b5f7ca 100644 --- a/nearby/service/java/com/android/server/nearby/fastpair/Constant.java +++ b/nearby/service/java/com/android/server/nearby/fastpair/Constant.java @@ -33,22 +33,11 @@ public class Constant { 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"; - public static final String FAIL_STATE = "FAIL"; - public static final String DISMISS = "DISMISS"; - public static final String NEED_CONFIRM_PASSKEY = "NEED CONFIRM PASSKEY"; - // device support assistant additional setup - public static final String NEED_ADDITIONAL_SETUP = "NEED ADDITIONAL SETUP"; - public static final String SHOW_PAIRING_WITHOUT_INTERACTION = - "SHOW_PAIRING_WITHOUT_INTERACTION"; public static final String ACTION_FAST_PAIR_HALF_SHEET_CANCEL = "com.android.nearby.ACTION_FAST_PAIR_HALF_SHEET_CANCEL"; - public static final String ACTION_FAST_PAIR_HALF_SHEET_BAN_STATE_RESET = - "com.android.nearby.ACTION_FAST_PAIR_BAN_STATE_RESET"; public static final String EXTRA_HALF_SHEET_INFO = "com.android.nearby.halfsheet.HALF_SHEET"; public static final String EXTRA_HALF_SHEET_TYPE = "com.android.nearby.halfsheet.HALF_SHEET_TYPE"; public static final String DEVICE_PAIRING_FRAGMENT_TYPE = "DEVICE_PAIRING"; - } 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 793e126bf5..1264adedf6 100644 --- a/nearby/service/java/com/android/server/nearby/fastpair/FastPairController.java +++ b/nearby/service/java/com/android/server/nearby/fastpair/FastPairController.java @@ -16,21 +16,15 @@ package com.android.server.nearby.fastpair; -import static com.android.server.nearby.common.bluetooth.fastpair.BroadcastConstants.EXTRA_RETROACTIVE_PAIR; -import static com.android.server.nearby.common.fastpair.service.UserActionHandlerBase.EXTRA_COMPANION_APP; -import static com.android.server.nearby.fastpair.FastPairManager.EXTRA_NOTIFICATION_ID; - -import static com.google.common.io.BaseEncoding.base16; import static com.google.common.primitives.Bytes.concat; import android.accounts.Account; import android.annotation.Nullable; import android.content.Context; -import android.content.Intent; +import android.nearby.FastPairDevice; import android.text.TextUtils; import android.util.Log; -import androidx.annotation.UiThread; import androidx.annotation.WorkerThread; import com.android.server.nearby.common.bluetooth.fastpair.BluetoothAddress; @@ -110,73 +104,60 @@ public class FastPairController { /** * Pairing function. */ - @UiThread - public void pair(Intent intent) { - String itemId = intent.getStringExtra(UserActionHandler.EXTRA_ITEM_ID); - int notificationId = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1); - byte[] discoveryItem = intent.getByteArrayExtra(UserActionHandler.EXTRA_DISCOVERY_ITEM); - String accountKeyString = intent.getStringExtra(UserActionHandler.EXTRA_FAST_PAIR_SECRET); - String companionApp = trimCompanionApp(intent.getStringExtra(EXTRA_COMPANION_APP)); - byte[] accountKey = accountKeyString != null ? base16().decode(accountKeyString) : null; - boolean isRetroactivePair = intent.getBooleanExtra(EXTRA_RETROACTIVE_PAIR, false); + public void pair(FastPairDevice fastPairDevice) { + byte[] discoveryItem = fastPairDevice.getData(); + String modelId = fastPairDevice.getModelId(); + Log.v(TAG, "pair: fastPairDevice " + fastPairDevice); mEventLoop.postRunnable( - new NamedRunnable("fastPairWith=" + itemId) { + new NamedRunnable("fastPairWith=" + modelId) { @Override public void run() { - DiscoveryItem item = null; - if (discoveryItem != null) { - try { - item = new DiscoveryItem(mContext, - Cache.StoredDiscoveryItem.parseFrom(discoveryItem)); - } catch (InvalidProtocolBufferException e) { - Log.w(TAG, - "Error parsing serialized discovery item with size " - + discoveryItem.length); + try { + DiscoveryItem item = new DiscoveryItem(mContext, + Cache.StoredDiscoveryItem.parseFrom(discoveryItem)); + if (TextUtils.isEmpty(item.getMacAddress())) { + Log.w(TAG, "There is no mac address in the DiscoveryItem," + + " ignore pairing"); return; } + // Check enabled state to prevent multiple pair attempts if we get the + // intent more than once (this can happen due to an Android platform + // bug - b/31459521). + if (item.getState() + != Cache.StoredDiscoveryItem.State.STATE_ENABLED) { + Log.d(TAG, "Incorrect state, ignore pairing"); + return; + } + boolean useLargeNotifications = + item.getAuthenticationPublicKeySecp256R1() != null; + FastPairNotificationManager fastPairNotificationManager = + new FastPairNotificationManager(mContext, item, + useLargeNotifications); + FastPairHalfSheetManager fastPairHalfSheetManager = + Locator.get(mContext, FastPairHalfSheetManager.class); + mFastPairCacheManager.saveDiscoveryItem(item); + + PairingProgressHandlerBase pairingProgressHandlerBase = + PairingProgressHandlerBase.create( + mContext, + item, + /* companionApp= */ null, + /* accountKey= */ null, + mFootprintsDeviceManager, + fastPairNotificationManager, + fastPairHalfSheetManager, + /* isRetroactivePair= */ false); + + pair(item, + /* accountKey= */ null, + /* companionApp= */ null, + pairingProgressHandlerBase); + } catch (InvalidProtocolBufferException e) { + Log.w(TAG, + "Error parsing serialized discovery item with size " + + discoveryItem.length); } - - - if (item == null || TextUtils.isEmpty(item.getMacAddress())) { - Log.w(TAG, "Invalid DiscoveryItem, ignore pairing"); - return; - } - - // Check enabled state to prevent multiple pair attempts if we get the - // intent more than once (this can happen due to an Android platform - // bug - b/31459521). - if (item.getState() != Cache.StoredDiscoveryItem.State.STATE_ENABLED - && !isRetroactivePair) { - Log.d(TAG, "Incorrect state, ignore pairing"); - return; - } - - boolean useLargeNotifications = accountKey != null - || item.getAuthenticationPublicKeySecp256R1() != null; - FastPairNotificationManager fastPairNotificationManager = - notificationId == -1 - ? new FastPairNotificationManager(mContext, item, - useLargeNotifications) - : new FastPairNotificationManager(mContext, item, - useLargeNotifications, notificationId); - FastPairHalfSheetManager fastPairHalfSheetManager = - Locator.get(mContext, FastPairHalfSheetManager.class); - - mFastPairCacheManager.saveDiscoveryItem(item); - - PairingProgressHandlerBase pairingProgressHandlerBase = - PairingProgressHandlerBase.create( - mContext, - item, - companionApp, - accountKey, - mFootprintsDeviceManager, - fastPairNotificationManager, - fastPairHalfSheetManager, - isRetroactivePair); - - pair(item, accountKey, companionApp, pairingProgressHandlerBase); } }); } @@ -315,4 +296,4 @@ public class FastPairController { interface Callback { void fastPairUpdateDeviceItemsEnabled(boolean enabled); } -} +} \ No newline at end of file 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 ca5ac336ca..380c759341 100644 --- a/nearby/service/java/com/android/server/nearby/fastpair/FastPairManager.java +++ b/nearby/service/java/com/android/server/nearby/fastpair/FastPairManager.java @@ -57,6 +57,7 @@ import com.android.server.nearby.common.locator.LocatorContextWrapper; 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.util.ForegroundThread; import com.android.server.nearby.util.Hex; @@ -194,7 +195,7 @@ public class FastPairManager { @Nullable byte[] accountKey, FootprintsDeviceManager footprints, PairingProgressHandlerBase pairingProgressHandlerBase) { - + FastPairHalfSheetManager manager = Locator.get(context, FastPairHalfSheetManager.class); try { pairingProgressHandlerBase.onPairingStarted(); if (pairingProgressHandlerBase.skipWaitingScreenUnlock()) { @@ -279,6 +280,10 @@ public class FastPairManager { // Fast Pair one connection.pair(); } + + // TODO(b/213373051): Merge logic with pairingProgressHandlerBase or delete the + // pairingProgressHandlerBase class. + manager.showPairingSuccessHalfSheet(connection.getPublicAddress()); pairingProgressHandlerBase.onPairingSuccess(connection.getPublicAddress()); } catch (BluetoothException | InterruptedException @@ -287,7 +292,11 @@ public class FastPairManager { | ExecutionException | PairingException | GeneralSecurityException e) { - Log.e(TAG, "FastPair: Error"); + Log.e(TAG, "Failed to pair.", e); + + // TODO(b/213373051): Merge logic with pairingProgressHandlerBase or delete the + // pairingProgressHandlerBase class. + manager.showPairingFailed(); pairingProgressHandlerBase.onPairingFailed(e); } } diff --git a/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManager.java b/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManager.java index 42839b24f8..6f79e6e822 100644 --- a/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManager.java +++ b/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManager.java @@ -29,10 +29,14 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.nearby.FastPairDevice; +import android.nearby.FastPairStatusCallback; +import android.nearby.PairStatusMetadata; import android.os.Bundle; import android.os.UserHandle; import android.util.Log; +import com.android.internal.annotations.VisibleForTesting; import com.android.server.nearby.common.locator.LocatorContextWrapper; import com.android.server.nearby.fastpair.FastPairController; import com.android.server.nearby.fastpair.cache.DiscoveryItem; @@ -47,27 +51,24 @@ import service.proto.Cache; * Fast Pair ux manager for half sheet. */ public class FastPairHalfSheetManager { - static final String ACTIVITY_INTENT_ACTION = "android.nearby.SHOW_HALFSHEET"; + private static final String ACTIVITY_INTENT_ACTION = "android.nearby.SHOW_HALFSHEET"; private static final String HALF_SHEET_CLASS_NAME = "com.android.nearby.halfsheet.HalfSheetActivity"; + private static final String TAG = "FPHalfSheetManager"; private String mHalfSheetApkPkgName; - private Context mContext; - private LocatorContextWrapper mLocatorContextWrapper; + private final LocatorContextWrapper mLocatorContextWrapper; + + FastPairService mFastPairService; - /** - * Construct function - */ public FastPairHalfSheetManager(Context context) { - mContext = context; - mLocatorContextWrapper = new LocatorContextWrapper(context); + this(new LocatorContextWrapper(context)); } - /** - * Construct function for test - */ - public FastPairHalfSheetManager(LocatorContextWrapper locatorContextWrapper) { + @VisibleForTesting + FastPairHalfSheetManager(LocatorContextWrapper locatorContextWrapper) { mLocatorContextWrapper = locatorContextWrapper; + mFastPairService = new FastPairService(); } /** @@ -79,14 +80,13 @@ public class FastPairHalfSheetManager { if (mLocatorContextWrapper != null) { String packageName = getHalfSheetApkPkgName(); if (packageName == null) { - Log.e("FastPairHalfSheetManager", "package name is null"); + Log.e(TAG, "package name is null"); return; } - HalfSheetCallback callback = new HalfSheetCallback(); - callback.setmFastPairController( + mFastPairService.setFastPairController( mLocatorContextWrapper.getLocator().get(FastPairController.class)); Bundle bundle = new Bundle(); - bundle.putBinder(EXTRA_BINDER, callback); + bundle.putBinder(EXTRA_BINDER, mFastPairService); mLocatorContextWrapper .startActivityAsUser(new Intent(ACTIVITY_INTENT_ACTION) .putExtra(EXTRA_HALF_SHEET_INFO, @@ -97,11 +97,9 @@ public class FastPairHalfSheetManager { .setComponent(new ComponentName(packageName, HALF_SHEET_CLASS_NAME)), UserHandle.CURRENT); - } } catch (IllegalStateException e) { - Log.e("FastPairHalfSheetManager", - "Can't resolve package that contains half sheet"); + Log.e(TAG, "Can't resolve package that contains half sheet"); } } @@ -109,7 +107,15 @@ public class FastPairHalfSheetManager { * Shows pairing fail half sheet. */ public void showPairingFailed() { - Log.d("FastPairHalfSheetManager", "show fail half sheet"); + FastPairStatusCallback pairStatusCallback = mFastPairService.getPairStatusCallback(); + if (pairStatusCallback != null) { + Log.v(TAG, "showPairingFailed: pairStatusCallback not NULL"); + pairStatusCallback.onPairUpdate(new FastPairDevice.Builder().build(), + new PairStatusMetadata(PairStatusMetadata.Status.FAIL)); + } else { + Log.w(TAG, "FastPairHalfSheetManager failed to show success half sheet because " + + "the pairStatusCallback is null"); + } } /** @@ -129,14 +135,22 @@ public class FastPairHalfSheetManager { * This function will handle pairing steps for half sheet. */ public void showPairingHalfSheet(DiscoveryItem item) { - Log.d("FastPairHalfSheetManager", "show pairing half sheet"); + Log.d(TAG, "show pairing half sheet"); } /** * Shows pairing success info. */ public void showPairingSuccessHalfSheet(String address) { - Log.d("FastPairHalfSheetManager", "show success half sheet"); + FastPairStatusCallback pairStatusCallback = mFastPairService.getPairStatusCallback(); + if (pairStatusCallback != null) { + pairStatusCallback.onPairUpdate( + new FastPairDevice.Builder().setBluetoothAddress(address).build(), + new PairStatusMetadata(PairStatusMetadata.Status.SUCCESS)); + } else { + Log.w(TAG, "FastPairHalfSheetManager failed to show success half sheet because " + + "the pairStatusCallback is null"); + } } /** diff --git a/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairService.java b/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairService.java index 53c2c12870..8c0d5721cc 100644 --- a/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairService.java +++ b/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairService.java @@ -73,7 +73,13 @@ public class FastPairService extends IFastPairClient.Stub { * Asks the Fast Pair service to pair the device. */ @Override - public void connect(FastPairDevice fastPairDevice) {} + public void connect(FastPairDevice fastPairDevice) { + if (mFastPairController != null) { + mFastPairController.pair(fastPairDevice); + } else { + Log.w(TAG, "Failed to connect because there is no FastPairController."); + } + } public FastPairStatusCallback getPairStatusCallback() { return mFastPairStatusCallback; diff --git a/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/HalfSheetCallback.java b/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/HalfSheetCallback.java deleted file mode 100644 index 2c792ed62c..0000000000 --- a/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/HalfSheetCallback.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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 com.android.server.nearby.fastpair.halfsheet; - -import android.content.Intent; -import android.nearby.IFastPairHalfSheetCallback; -import android.util.Log; - -import com.android.server.nearby.fastpair.FastPairController; - - -/** - * Callback to send ux action back to nearby service. - */ -public class HalfSheetCallback extends IFastPairHalfSheetCallback.Stub { - private FastPairController mFastPairController; - - public HalfSheetCallback() { - } - - /** - * Set function for Fast Pair controller. - */ - public void setmFastPairController(FastPairController fastPairController) { - mFastPairController = fastPairController; - } - - /** - * Half Sheet connection button clicked. - */ - @Override - public void onHalfSheetConnectionConfirm(Intent intent) { - Log.d("FastPairHalfSheet", "Call back receiver"); - if (mFastPairController != null) { - mFastPairController.pair(intent); - } - } -} diff --git a/nearby/tests/unit/src/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManagerTest.java b/nearby/tests/unit/src/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManagerTest.java index ab18f54344..58e4c47e4c 100644 --- a/nearby/tests/unit/src/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManagerTest.java +++ b/nearby/tests/unit/src/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManagerTest.java @@ -16,11 +16,6 @@ package com.android.server.nearby.fastpair.halfsheet; - -import static com.android.server.nearby.fastpair.halfsheet.FastPairHalfSheetManager.ACTIVITY_INTENT_ACTION; - -import static com.google.common.truth.Truth.assertThat; - import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; @@ -72,7 +67,6 @@ public class FastPairHalfSheetManagerTest { public void setup() { MockitoAnnotations.initMocks(this); - mScanFastPairStoreItem = Cache.ScanFastPairStoreItem.newBuilder() .setAddress(BLEADDRESS) .setDeviceName(NAME) @@ -85,7 +79,6 @@ public class FastPairHalfSheetManagerTest { ResolveInfo resolveInfo = new ResolveInfo(); List resolveInfoList = new ArrayList<>(); - mPackageManager = mock(PackageManager.class); when(mContextWrapper.getPackageManager()).thenReturn(mPackageManager); resolveInfo.activityInfo = new ActivityInfo(); @@ -108,8 +101,6 @@ public class FastPairHalfSheetManagerTest { verify(mContextWrapper, atLeastOnce()) .startActivityAsUser(intentArgumentCaptor.capture(), eq(UserHandle.CURRENT)); - Intent launchIntent = intentArgumentCaptor.getValue(); - assertThat(launchIntent.getAction()).isEqualTo(ACTIVITY_INTENT_ACTION); } @Test @@ -118,7 +109,6 @@ public class FastPairHalfSheetManagerTest { ResolveInfo resolveInfo = new ResolveInfo(); List resolveInfoList = new ArrayList<>(); - mPackageManager = mock(PackageManager.class); when(mContextWrapper.getPackageManager()).thenReturn(mPackageManager); resolveInfo.activityInfo = new ActivityInfo(); @@ -142,6 +132,5 @@ public class FastPairHalfSheetManagerTest { verify(mContextWrapper, never()) .startActivityAsUser(intentArgumentCaptor.capture(), eq(UserHandle.CURRENT)); - } } From 3a07097bd5e9cac52cf054dec11322bdc381d82e Mon Sep 17 00:00:00 2001 From: Xinyi Zhou Date: Thu, 17 Feb 2022 20:48:00 -0800 Subject: [PATCH 015/412] Fast Pair Half Sheet UI implementation Refactor doc: go/fp-halfsheet-aosp Fix: 196262706 Fix: 196644352 Fix: 218771606 Test: Built band verified flow manually Change-Id: I2496d111410e9bc715547b8fdbe708730304df8c --- .../res/drawable/fast_pair_ic_info.xml | 3 +- .../fast_pair_device_pairing_fragment.xml | 43 +- nearby/halfsheet/res/values/strings.xml | 56 +- nearby/halfsheet/res/values/styles.xml | 7 +- .../nearby/halfsheet/HalfSheetActivity.java | 93 +-- .../fragment/DevicePairingFragment.java | 558 ++++++++++-------- .../fragment/HalfSheetModuleFragment.java | 51 +- .../halfsheet/utils/BroadcastUtils.java | 17 - .../nearby/halfsheet/utils/FastPairUtils.java | 2 - .../nearby/halfsheet/utils/IconUtils.java | 2 +- 10 files changed, 433 insertions(+), 399 deletions(-) diff --git a/nearby/halfsheet/res/drawable/fast_pair_ic_info.xml b/nearby/halfsheet/res/drawable/fast_pair_ic_info.xml index cc514e5ee1..7d61d1c970 100644 --- a/nearby/halfsheet/res/drawable/fast_pair_ic_info.xml +++ b/nearby/halfsheet/res/drawable/fast_pair_ic_info.xml @@ -17,7 +17,8 @@ android:width="24dp" android:height="24dp" android:viewportWidth="24.0" - android:viewportHeight="24.0"> + android:viewportHeight="24.0" + android:tint="@color/fast_pair_half_sheet_subtitle_color"> diff --git a/nearby/halfsheet/res/layout/fast_pair_device_pairing_fragment.xml b/nearby/halfsheet/res/layout/fast_pair_device_pairing_fragment.xml index 24fcd83909..7fbe229cfd 100644 --- a/nearby/halfsheet/res/layout/fast_pair_device_pairing_fragment.xml +++ b/nearby/halfsheet/res/layout/fast_pair_device_pairing_fragment.xml @@ -73,50 +73,67 @@ + -