Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7cf82126 authored by Kyunglyul Hyun's avatar Kyunglyul Hyun Committed by Gerrit Code Review
Browse files

Merge "Unregister scan client when RemoteException raises" into main

parents 6c2f9c21 edbe38f8
Loading
Loading
Loading
Loading
+28 −6
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ import com.android.bluetooth.btservice.MetricsLogger;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.flags.FeatureFlags;
import com.android.bluetooth.flags.FeatureFlagsImpl;
import com.android.bluetooth.flags.Flags;
import com.android.bluetooth.util.NumberUtils;
import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.utils.SynchronousResultReceiver;
@@ -534,10 +535,14 @@ public class GattService extends ProfileService {

            ScanClient client = getScanClient(mScannerId);
            if (client != null) {
                if (Flags.leScanFixRemoteException()) {
                    handleDeadScanClient(client);
                } else {
                    client.appDied = true;
                    stopScan(client.scannerId, getAttributionSource());
                }
            }
        }

        private ScanClient getScanClient(int clientIf) {
            for (ScanClient client : mScanManager.getRegularScanQueue()) {
@@ -2097,11 +2102,15 @@ public class GattService extends ProfileService {
                }
            } catch (RemoteException | PendingIntent.CanceledException e) {
                Log.e(TAG, "Exception: " + e);
                if (Flags.leScanFixRemoteException()) {
                    handleDeadScanClient(client);
                } else {
                    mScannerMap.remove(client.scannerId);
                    mScanManager.stopScan(client.scannerId);
                }
            }
        }
    }

    private void sendResultByPendingIntent(PendingIntentInfo pii, ScanResult result,
            int callbackType, ScanClient client) {
@@ -2203,6 +2212,15 @@ public class GattService extends ProfileService {
        return new MatchResult(false, MatchOrigin.PSEUDO_ADDRESS);
    }

    private void handleDeadScanClient(ScanClient client) {
        if (client.appDied) {
            Log.w(TAG, "Already dead client " + client.scannerId);
            return;
        }
        client.appDied = true;
        stopScan(client.scannerId, getAttributionSource());
    }

    void onClientRegistered(int status, int clientIf, long uuidLsb, long uuidMsb)
            throws RemoteException {
        UUID uuid = new UUID(uuidMsb, uuidLsb);
@@ -2848,10 +2866,14 @@ public class GattService extends ProfileService {
            }
        } catch (RemoteException | PendingIntent.CanceledException e) {
            Log.e(TAG, "Exception: " + e);
            if (Flags.leScanFixRemoteException()) {
                handleDeadScanClient(client);
            } else {
                mScannerMap.remove(client.scannerId);
                mScanManager.stopScan(client.scannerId);
            }
        }
    }

    // Check and deliver scan results for different scan clients.
    private void deliverBatchScan(ScanClient client, Set<ScanResult> allResults)
+62 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import android.os.Binder;
import android.os.RemoteException;
import android.os.WorkSource;

import android.platform.test.annotations.RequiresFlagsEnabled;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.rule.ServiceTestRule;
@@ -55,8 +56,10 @@ import com.android.bluetooth.TestUtils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.CompanionManager;

import com.android.bluetooth.flags.Flags;
import org.junit.After;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -66,6 +69,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -487,6 +491,64 @@ public class GattServiceTest {
        verify(mScanManager).flushBatchScanResults(new ScanClient(scannerId));
    }

    @RequiresFlagsEnabled(Flags.FLAG_LE_SCAN_FIX_REMOTE_EXCEPTION)
    @Test
    public void onScanResult_remoteException_clientDied() throws Exception {
        Assume.assumeTrue(Flags.leScanFixRemoteException());
        int scannerId = 1;

        int eventType = 0;
        int addressType = 0;
        String address = "02:00:00:00:00:00";
        int primaryPhy = 0;
        int secondPhy = 0;
        int advertisingSid = 0;
        int txPower = 0;
        int rssi = 0;
        int periodicAdvInt = 0;
        byte[] advData = new byte[0];

        ScanClient scanClient = new ScanClient(scannerId);
        scanClient.scannerId = scannerId;
        scanClient.hasNetworkSettingsPermission = true;
        scanClient.settings =
                new ScanSettings.Builder()
                        .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
                        .setLegacy(false)
                        .build();

        AppScanStats appScanStats = mock(AppScanStats.class);
        IScannerCallback callback = mock(IScannerCallback.class);

        mApp.callback = callback;
        mApp.appScanStats = appScanStats;
        Set<ScanClient> scanClientSet = Collections.singleton(scanClient);

        doReturn(address).when(mAdapterService).getIdentityAddress(anyString());
        doReturn(scanClientSet).when(mScanManager).getRegularScanQueue();
        doReturn(mApp).when(mScannerMap).getById(scanClient.scannerId);
        doReturn(appScanStats).when(mScannerMap).getAppScanStatsById(scanClient.scannerId);

        // Simulate remote client crash
        doThrow(new RemoteException()).when(callback).onScanResult(any());

        mService.onScanResult(
                eventType,
                addressType,
                address,
                primaryPhy,
                secondPhy,
                advertisingSid,
                txPower,
                rssi,
                periodicAdvInt,
                advData,
                address);

        assertThat(scanClient.appDied).isTrue();
        verify(appScanStats).recordScanStop(scannerId);
    }

    @Test
    public void readCharacteristic() {
        int clientIf = 1;