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

Commit 10e75c47 authored by Wei Wang's avatar Wei Wang
Browse files

Fix race condition when advertising app dies.

Bug: 16565960
Change-Id: Ica801a1186e62fcba666deabe5989dd47d404b68
parent 3f059683
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@ import java.util.Objects;
 */
class AdvertiseClient {
    int clientIf;
    // Associated application died.
    boolean appDied;
    AdvertiseSettings settings;
    AdvertiseData advertiseData;
    @Nullable
@@ -37,7 +39,7 @@ class AdvertiseClient {
    /**
     * @param clientIf - Identifier of the client.
     */
    public AdvertiseClient(int clientIf) {
    AdvertiseClient(int clientIf) {
        this.clientIf = clientIf;
    }

+6 −2
Original line number Diff line number Diff line
@@ -206,9 +206,13 @@ class AdvertiseManager {
            if (client == null) {
                return;
            }
            logd("advertise clients size " + mAdvertiseClients.size());
            if (mAdvertiseClients.contains(client)) {
            logd("stop advertise for client " + client.clientIf);
            mAdvertiseNative.stopAdvertising(client);
            if (client.appDied) {
                logd("app died - unregistering client : " + client.clientIf);
                mService.unregisterClient(client.clientIf);
            }
            if (mAdvertiseClients.contains(client)) {
                mAdvertiseClients.remove(client);
            }
        }
+15 −12
Original line number Diff line number Diff line
@@ -220,16 +220,19 @@ public class GattService extends ProfileService {
            mAppIf = appIf;
        }

        @Override
        public void binderDied() {
            if (DBG) Log.d(TAG, "Binder is dead - unregistering client (" + mAppIf + ")!");

            if (isScanClient(mAppIf)) {
                stopScan(mAppIf, false);
                ScanClient client = new ScanClient(mAppIf, false);
                client.appDied = true;
                stopScan(client);
            } else {
                stopMultiAdvertising(mAppIf);
                AdvertiseClient client = new AdvertiseClient(mAppIf);
                client.appDied = true;
                stopMultiAdvertising(client);
            }
            // TODO: Move unregisterClient after stop scan/advertise callback to avoid race
            // condition.
            unregisterClient(mAppIf);
        }

        private boolean isScanClient(int clientIf) {
@@ -310,7 +313,7 @@ public class GattService extends ProfileService {
        public void stopScan(int appIf, boolean isServer) {
            GattService service = getService();
            if (service == null) return;
            service.stopScan(appIf, isServer);
            service.stopScan(new ScanClient(appIf, isServer));
        }

        @Override
@@ -542,7 +545,7 @@ public class GattService extends ProfileService {
        public void stopMultiAdvertising(int clientIf) {
            GattService service = getService();
            if (service == null) return;
            service.stopMultiAdvertising(clientIf);
            service.stopMultiAdvertising(new AdvertiseClient(clientIf));
        }
    };

@@ -1202,7 +1205,7 @@ public class GattService extends ProfileService {

    // Callback when advertise instance is disabled
    void onAdvertiseInstanceDisabled(int status, int clientIf) throws RemoteException {
        if (DBG) Log.d(TAG, "onAdvertiseInstanceEnabled() - clientIf=" + clientIf
        if (DBG) Log.d(TAG, "onAdvertiseInstanceDisabled() - clientIf=" + clientIf
            + ", status=" + status);
        ClientMap.App app = mClientMap.getById(clientIf);
        if (app != null) {
@@ -1289,12 +1292,12 @@ public class GattService extends ProfileService {
        mScanManager.flushBatchScanResults(new ScanClient(clientIf, isServer));
    }

    void stopScan(int appIf, boolean isServer) {
    void stopScan(ScanClient client) {
        enforceAdminPermission();
        int scanQueueSize = mScanManager.getBatchScanQueue().size() +
                mScanManager.getRegularScanQueue().size();
        if (DBG) Log.d(TAG, "stopScan() - queue size =" + scanQueueSize);
        mScanManager.stopScan(new ScanClient(appIf, isServer));
        mScanManager.stopScan(client);
    }

    /**************************************************************************
@@ -1341,9 +1344,9 @@ public class GattService extends ProfileService {
                scanResponse));
    }

    void stopMultiAdvertising(int clientIf) {
    void stopMultiAdvertising(AdvertiseClient client) {
        enforceAdminPermission();
        mAdvertiseManager.stopAdvertising(new AdvertiseClient(clientIf));
        mAdvertiseManager.stopAdvertising(client);
    }


+3 −2
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@ import java.util.UUID;
    ScanSettings settings;
    List<ScanFilter> filters;
    List<List<ResultStorageDescriptor>> storages;
    // App associated with the scan client died.
    boolean appDied;

    private static final ScanSettings DEFAULT_SCAN_SETTINGS = new ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
@@ -53,7 +55,6 @@ import java.util.UUID;
        this(appIf, isServer, new UUID[0], settings, filters, null);
    }


    ScanClient(int appIf, boolean isServer, ScanSettings settings,
            List<ScanFilter> filters, List<List<ResultStorageDescriptor>> storages) {
        this(appIf, isServer, new UUID[0], settings, filters, storages);
+5 −0
Original line number Diff line number Diff line
@@ -198,12 +198,17 @@ public class ScanManager {

        void handleStopScan(ScanClient client) {
            Utils.enforceAdminPermission(mService);
            if (client == null) return;
            if (mRegularScanClients.contains(client)) {
                mScanNative.configureRegularScanParams();
                mScanNative.stopRegularScan(client);
            } else {
                mScanNative.stopBatchScan(client);
            }
            if (client.appDied) {
                logd("app died, unregister client - " + client.clientIf);
                mService.unregisterClient(client.clientIf);
            }
        }

        void handleFlushBatchResults(ScanClient client) {