From fa2c9c16772d5287642f6edd2bd1eae721a0ef7a Mon Sep 17 00:00:00 2001 From: Guojing Yuan Date: Thu, 16 May 2024 19:55:46 +0000 Subject: Avoid throwing a runtime exception for duplicate association requests Fix: 340998672 Test: CTS Change-Id: I94a8d3e448dfc3bbb190c36750b35fa415d78348 --- .../CompanionAssociationActivity.java | 5 +- .../CompanionDeviceDiscoveryService.java | 53 +++++++++++++++------- 2 files changed, 40 insertions(+), 18 deletions(-) (limited to 'packages/CompanionDeviceManager/src') diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionAssociationActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionAssociationActivity.java index bf81d3f85ac9..f98908cf2d56 100644 --- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionAssociationActivity.java +++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionAssociationActivity.java @@ -211,7 +211,10 @@ public class CompanionAssociationActivity extends FragmentActivity implements // Start discovery services if needed. if (!mRequest.isSelfManaged()) { - CompanionDeviceDiscoveryService.startForRequest(this, mRequest); + boolean started = CompanionDeviceDiscoveryService.startForRequest(this, mRequest); + if (!started) { + return; + } // TODO(b/217749191): Create the ViewModel for the LiveData CompanionDeviceDiscoveryService.getDiscoveryState().observe( /* LifeCycleOwner */ this, this::onDiscoveryStateChanged); diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDiscoveryService.java index a5bb34f4422b..e809433a1261 100644 --- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDiscoveryService.java +++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDiscoveryService.java @@ -60,6 +60,8 @@ import android.util.Slog; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; +import com.android.internal.annotations.GuardedBy; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -88,6 +90,9 @@ public class CompanionDeviceDiscoveryService extends Service { new MutableLiveData<>(Collections.emptyList()); private static MutableLiveData sStateLiveData = new MutableLiveData<>(DiscoveryState.NOT_STARTED); + private static final Object LOCK = new Object(); + @GuardedBy("LOCK") + private static boolean sDiscoveryStarted = false; private BluetoothManager mBtManager; private BluetoothAdapter mBtAdapter; @@ -98,8 +103,6 @@ public class CompanionDeviceDiscoveryService extends Service { private BluetoothBroadcastReceiver mBtReceiver; private WifiBroadcastReceiver mWifiReceiver; - private boolean mDiscoveryStarted = false; - private boolean mDiscoveryStopped = false; private final List> mDevicesFound = new ArrayList<>(); private final Runnable mTimeoutRunnable = this::timeout; @@ -111,22 +114,27 @@ public class CompanionDeviceDiscoveryService extends Service { */ enum DiscoveryState { NOT_STARTED, - STARTING, - DISCOVERY_IN_PROGRESS, + IN_PROGRESS, FINISHED_STOPPED, FINISHED_TIMEOUT } - static void startForRequest( + static boolean startForRequest( @NonNull Context context, @NonNull AssociationRequest associationRequest) { + synchronized (LOCK) { + if (sDiscoveryStarted) { + Slog.e(TAG, "Discovery is already started. Ignoring this request..."); + return false; + } + } requireNonNull(associationRequest); final Intent intent = new Intent(context, CompanionDeviceDiscoveryService.class); intent.setAction(ACTION_START_DISCOVERY); intent.putExtra(EXTRA_ASSOCIATION_REQUEST, associationRequest); - sStateLiveData.setValue(DiscoveryState.STARTING); - sScanResultsLiveData.setValue(Collections.emptyList()); context.startService(intent); + + return true; } static void stop(@NonNull Context context) { @@ -176,10 +184,16 @@ public class CompanionDeviceDiscoveryService extends Service { Slog.d(TAG, "startDiscovery() request=" + request); requireNonNull(request); - if (mDiscoveryStarted) throw new RuntimeException("Discovery in progress."); + synchronized (LOCK) { + if (sDiscoveryStarted) { + Slog.e(TAG, "Discovery is already started. Returning..."); + return; + } + sDiscoveryStarted = true; + } mStopAfterFirstMatch = request.isSingleDevice(); - mDiscoveryStarted = true; - sStateLiveData.setValue(DiscoveryState.DISCOVERY_IN_PROGRESS); + sScanResultsLiveData.setValue(Collections.emptyList()); + sStateLiveData.setValue(DiscoveryState.IN_PROGRESS); final List> allFilters = request.getDeviceFilters(); final List btFilters = @@ -211,14 +225,13 @@ public class CompanionDeviceDiscoveryService extends Service { private void stopDiscoveryAndFinish(boolean timeout) { Slog.d(TAG, "stopDiscoveryAndFinish(" + timeout + ")"); - if (!mDiscoveryStarted) { - stopSelf(); - return; + synchronized (LOCK) { + if (!sDiscoveryStarted) { + stopSelf(); + return; + } } - if (mDiscoveryStopped) return; - mDiscoveryStopped = true; - // Stop BT discovery. if (mBtReceiver != null) { // Cancel discovery. @@ -249,6 +262,10 @@ public class CompanionDeviceDiscoveryService extends Service { sStateLiveData.setValue(DiscoveryState.FINISHED_STOPPED); } + synchronized (LOCK) { + sDiscoveryStarted = false; + } + // "Finish". stopSelf(); } @@ -340,7 +357,9 @@ public class CompanionDeviceDiscoveryService extends Service { private void onDeviceFound(@NonNull DeviceFilterPair device) { runOnMainThread(() -> { - if (mDiscoveryStopped) return; + synchronized (LOCK) { + if (!sDiscoveryStarted) return; + } if (mDevicesFound.contains(device)) { // TODO: update the device instead of ignoring (new found device may contain // additional/updated info, eg. name of the device). -- cgit v1.2.3-59-g8ed1b