Return UNKNOWN code when CHRE is not ready
Test: Unit test
Ignore-AOSP-First: nearby_not_in_aosp_yet
Fix: 263890209
Change-Id: I45b3eec6c83848e129704ed9ec5f2c4a49f982fb
(cherry picked from commit 89346d479390e7bf68f77e0be122da2eaec637be)
diff --git a/nearby/framework/java/android/nearby/NearbyManager.java b/nearby/framework/java/android/nearby/NearbyManager.java
index ea53ab8..fba6ae5 100644
--- a/nearby/framework/java/android/nearby/NearbyManager.java
+++ b/nearby/framework/java/android/nearby/NearbyManager.java
@@ -62,7 +62,7 @@
ScanStatus.ERROR,
})
public @interface ScanStatus {
- // Default, invalid state.
+ // The undetermined status, some modules may be initializing. Retry is suggested.
int UNKNOWN = 0;
// The successful state.
int SUCCESS = 1;
diff --git a/nearby/service/java/com/android/server/nearby/NearbyService.java b/nearby/service/java/com/android/server/nearby/NearbyService.java
index be3b84e..a1bca19 100644
--- a/nearby/service/java/com/android/server/nearby/NearbyService.java
+++ b/nearby/service/java/com/android/server/nearby/NearbyService.java
@@ -108,10 +108,7 @@
CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag);
DiscoveryPermissions.enforceDiscoveryPermission(mContext, identity);
- if (mProviderManager.registerScanListener(scanRequest, listener, identity)) {
- return NearbyManager.ScanStatus.SUCCESS;
- }
- return NearbyManager.ScanStatus.ERROR;
+ return mProviderManager.registerScanListener(scanRequest, listener, identity);
}
@Override
diff --git a/nearby/service/java/com/android/server/nearby/provider/ChreCommunication.java b/nearby/service/java/com/android/server/nearby/provider/ChreCommunication.java
index 00e1cb6..9d93843 100644
--- a/nearby/service/java/com/android/server/nearby/provider/ChreCommunication.java
+++ b/nearby/service/java/com/android/server/nearby/provider/ChreCommunication.java
@@ -69,6 +69,8 @@
private final Executor mExecutor;
private boolean mStarted = false;
+ // null when CHRE availability result has not been returned
+ @Nullable private Boolean mChreSupport = null;
@Nullable private ContextHubCommsCallback mCallback;
@Nullable private ContextHubClient mContextHubClient;
@@ -78,8 +80,13 @@
mExecutor = executor;
}
- public boolean available() {
- return mContextHubClient != null;
+ /**
+ * @return {@code true} if NanoApp is available and {@code null} when CHRE availability result
+ * has not been returned
+ */
+ @Nullable
+ public Boolean available() {
+ return mChreSupport;
}
/**
@@ -138,6 +145,7 @@
if (mContextHubClient != null) {
mContextHubClient.close();
mContextHubClient = null;
+ mChreSupport = null;
}
}
@@ -245,6 +253,7 @@
"Found valid contexthub: %s", mQueriedContextHub.getId()));
mContextHubClient = mManager.createClient(mContext, mQueriedContextHub,
mExecutor, ChreCommunication.this);
+ mChreSupport = true;
mCallback.started(true);
return;
}
@@ -267,6 +276,7 @@
// there isn't a valid context available on this device.
if (mContextHubs.isEmpty()) {
mCallback.started(false);
+ mChreSupport = false;
}
}
}
diff --git a/nearby/service/java/com/android/server/nearby/provider/ChreDiscoveryProvider.java b/nearby/service/java/com/android/server/nearby/provider/ChreDiscoveryProvider.java
index 105051a..d0d0de0 100644
--- a/nearby/service/java/com/android/server/nearby/provider/ChreDiscoveryProvider.java
+++ b/nearby/service/java/com/android/server/nearby/provider/ChreDiscoveryProvider.java
@@ -24,6 +24,7 @@
import static service.proto.Blefilter.DataElement.ElementType.DE_CONNECTION_STATUS;
import static service.proto.Blefilter.DataElement.ElementType.DE_FAST_PAIR_ACCOUNT_KEY;
+import android.annotation.Nullable;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -59,7 +60,6 @@
/** @hide */
@VisibleForTesting public static final int NANOAPP_MESSAGE_TYPE_CONFIG = 5;
- private static final int PRESENCE_UUID = 0xFCF1;
private static final int FP_ACCOUNT_KEY_LENGTH = 16;
private final ChreCommunication mChreCommunication;
@@ -114,7 +114,12 @@
onStart();
}
- public boolean available() {
+ /**
+ * @return {@code true} if CHRE is available and {@code null} when CHRE availability result
+ * has not been returned
+ */
+ @Nullable
+ public Boolean available() {
return mChreCommunication.available();
}
diff --git a/nearby/service/java/com/android/server/nearby/provider/DiscoveryProviderManager.java b/nearby/service/java/com/android/server/nearby/provider/DiscoveryProviderManager.java
index e4c56e4..b7574c9 100644
--- a/nearby/service/java/com/android/server/nearby/provider/DiscoveryProviderManager.java
+++ b/nearby/service/java/com/android/server/nearby/provider/DiscoveryProviderManager.java
@@ -26,6 +26,7 @@
import android.nearby.DataElement;
import android.nearby.IScanListener;
import android.nearby.NearbyDeviceParcelable;
+import android.nearby.NearbyManager;
import android.nearby.PresenceScanFilter;
import android.nearby.ScanFilter;
import android.nearby.ScanRequest;
@@ -148,7 +149,8 @@
/**
* Registers the listener in the manager and starts scan according to the requested scan mode.
*/
- public boolean registerScanListener(ScanRequest scanRequest, IScanListener listener,
+ @NearbyManager.ScanStatus
+ public int registerScanListener(ScanRequest scanRequest, IScanListener listener,
CallerIdentity callerIdentity) {
synchronized (mLock) {
ScanListenerDeathRecipient deathRecipient = (listener != null)
@@ -166,23 +168,26 @@
mScanTypeScanListenerRecordMap.get(listenerBinder).getScanRequest();
if (scanRequest.equals(savedScanRequest)) {
Log.d(TAG, "Already registered the scanRequest: " + scanRequest);
- return true;
+ return NearbyManager.ScanStatus.SUCCESS;
}
}
ScanListenerRecord scanListenerRecord =
new ScanListenerRecord(scanRequest, listener, callerIdentity, deathRecipient);
mScanTypeScanListenerRecordMap.put(listenerBinder, scanListenerRecord);
- if (!startProviders(scanRequest)) {
- return false;
+ Boolean started = startProviders(scanRequest);
+ if (started == null) {
+ return NearbyManager.ScanStatus.UNKNOWN;
}
-
+ if (!started) {
+ return NearbyManager.ScanStatus.ERROR;
+ }
NearbyMetrics.logScanStarted(scanListenerRecord.hashCode(), scanRequest);
if (mScanMode < scanRequest.getScanMode()) {
mScanMode = scanRequest.getScanMode();
invalidateProviderScanMode();
}
- return true;
+ return NearbyManager.ScanStatus.SUCCESS;
}
}
@@ -237,18 +242,33 @@
}
}
- // Returns false when fail to start all the providers. Returns true if any one of the provider
- // starts successfully.
+ /**
+ * @return {@code null} when all providers are initializing
+ * {@code false} when fail to start all the providers
+ * {@code true} when any one of the provider starts successfully
+ */
@VisibleForTesting
- boolean startProviders(ScanRequest scanRequest) {
+ @Nullable
+ Boolean startProviders(ScanRequest scanRequest) {
if (!scanRequest.isBleEnabled()) {
Log.w(TAG, "failed to start any provider because client disabled BLE");
return false;
}
List<ScanFilter> scanFilters = getPresenceScanFilters();
+ boolean chreOnly = isChreOnly(scanFilters);
+ Boolean chreAvailable = mChreDiscoveryProvider.available();
+ if (chreAvailable == null) {
+ if (chreOnly) {
+ Log.w(TAG, "client wants CHRE only and Nearby service is still querying CHRE"
+ + " status");
+ return null;
+ }
+ startBleProvider(scanFilters);
+ return true;
+ }
- if (!mChreDiscoveryProvider.available()) {
- if (scanRequest.getScanType() == SCAN_TYPE_NEARBY_PRESENCE && isChreOnly(scanFilters)) {
+ if (!chreAvailable) {
+ if (chreOnly) {
Log.w(TAG, "failed to start any provider because client wants CHRE only and CHRE"
+ " is not available");
return false;
diff --git a/nearby/tests/unit/src/com/android/server/nearby/provider/DiscoveryProviderManagerTest.java b/nearby/tests/unit/src/com/android/server/nearby/provider/DiscoveryProviderManagerTest.java
index b1737e9..8591b60 100644
--- a/nearby/tests/unit/src/com/android/server/nearby/provider/DiscoveryProviderManagerTest.java
+++ b/nearby/tests/unit/src/com/android/server/nearby/provider/DiscoveryProviderManagerTest.java
@@ -45,7 +45,6 @@
import org.mockito.MockitoAnnotations;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
public class DiscoveryProviderManagerTest {
@@ -76,6 +75,7 @@
when(mInjector.getAppOpsManager()).thenReturn(mAppOpsManager);
when(mBleDiscoveryProvider.getController()).thenReturn(mBluetoothController);
when(mChreDiscoveryProvider.getController()).thenReturn(mChreController);
+
mScanTypeScanListenerRecordMap = new HashMap<>();
mDiscoveryProviderManager =
new DiscoveryProviderManager(mContext, mInjector, mBleDiscoveryProvider,
@@ -108,10 +108,9 @@
mCallerIdentity, mScanListenerDeathRecipient);
mScanTypeScanListenerRecordMap.put(mIBinder, record);
-
- boolean startProviders = mDiscoveryProviderManager.startProviders(scanRequest);
+ Boolean start = mDiscoveryProviderManager.startProviders(scanRequest);
verify(mBluetoothController, never()).start();
- assertThat(startProviders).isTrue();
+ assertThat(start).isTrue();
}
@Test
@@ -127,9 +126,9 @@
mCallerIdentity, mScanListenerDeathRecipient);
mScanTypeScanListenerRecordMap.put(mIBinder, record);
- boolean startProviders = mDiscoveryProviderManager.startProviders(scanRequest);
+ Boolean start = mDiscoveryProviderManager.startProviders(scanRequest);
verify(mBluetoothController, never()).start();
- assertThat(startProviders).isTrue();
+ assertThat(start).isTrue();
}
@Test
@@ -144,9 +143,9 @@
mCallerIdentity, mScanListenerDeathRecipient);
mScanTypeScanListenerRecordMap.put(mIBinder, record);
- boolean startProviders = mDiscoveryProviderManager.startProviders(scanRequest);
+ Boolean start = mDiscoveryProviderManager.startProviders(scanRequest);
verify(mBluetoothController, never()).start();
- assertThat(startProviders).isFalse();
+ assertThat(start).isFalse();
}
@Test
@@ -161,9 +160,9 @@
mCallerIdentity, mScanListenerDeathRecipient);
mScanTypeScanListenerRecordMap.put(mIBinder, record);
- boolean startProviders = mDiscoveryProviderManager.startProviders(scanRequest);
+ Boolean start = mDiscoveryProviderManager.startProviders(scanRequest);
verify(mBluetoothController, never()).start();
- assertThat(startProviders).isTrue();
+ assertThat(start).isTrue();
}
@Test
@@ -178,14 +177,43 @@
mCallerIdentity, mScanListenerDeathRecipient);
mScanTypeScanListenerRecordMap.put(mIBinder, record);
- boolean startProviders = mDiscoveryProviderManager.startProviders(scanRequest);
+ Boolean start = mDiscoveryProviderManager.startProviders(scanRequest);
verify(mBluetoothController, atLeastOnce()).start();
- assertThat(startProviders).isTrue();
+ assertThat(start).isTrue();
}
@Test
- public void testStartChreProvider() {
- mDiscoveryProviderManager.startChreProvider(List.of(getPresenceScanFilter()));
+ public void testStartProviders_chreOnlyChreUndetermined_bleProviderNotStarted() {
+ when(mChreDiscoveryProvider.available()).thenReturn(null);
+
+ ScanRequest scanRequest = new ScanRequest.Builder()
+ .setScanType(SCAN_TYPE_NEARBY_PRESENCE)
+ .addScanFilter(getChreOnlyPresenceScanFilter()).build();
+ DiscoveryProviderManager.ScanListenerRecord record =
+ new DiscoveryProviderManager.ScanListenerRecord(scanRequest, mScanListener,
+ mCallerIdentity, mScanListenerDeathRecipient);
+ mScanTypeScanListenerRecordMap.put(mIBinder, record);
+
+ Boolean start = mDiscoveryProviderManager.startProviders(scanRequest);
+ verify(mBluetoothController, never()).start();
+ assertThat(start).isNull();
+ }
+
+ @Test
+ public void testStartProviders_notChreOnlyChreUndetermined_bleProviderStarted() {
+ when(mChreDiscoveryProvider.available()).thenReturn(null);
+
+ ScanRequest scanRequest = new ScanRequest.Builder()
+ .setScanType(SCAN_TYPE_NEARBY_PRESENCE)
+ .addScanFilter(getPresenceScanFilter()).build();
+ DiscoveryProviderManager.ScanListenerRecord record =
+ new DiscoveryProviderManager.ScanListenerRecord(scanRequest, mScanListener,
+ mCallerIdentity, mScanListenerDeathRecipient);
+ mScanTypeScanListenerRecordMap.put(mIBinder, record);
+
+ Boolean start = mDiscoveryProviderManager.startProviders(scanRequest);
+ verify(mBluetoothController, atLeastOnce()).start();
+ assertThat(start).isTrue();
}
private static PresenceScanFilter getPresenceScanFilter() {