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

Commit 60420421 authored by Calvin On's avatar Calvin On Committed by Andre Eisenbach
Browse files

Synchronize access to ServiceDeclaration fields.

ServiceDeclaration objects are accessed by both the binder thread
(addService, addCharacteristic, etc) and the GattService callback thread
(onServiceAdded, etc) and so must be made thread-safe.

Bug: 28201656
Change-Id: Ic2e4b5c21dafceb62f33738b781f908f502f60b3
parent 6da15439
Loading
Loading
Loading
Loading
+46 −36
Original line number Diff line number Diff line
@@ -15,9 +15,7 @@
 */
package com.android.bluetooth.gatt;

import android.util.Log;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;

@@ -71,15 +69,14 @@ class ServiceDeclaration {
        }
    }

    List<Entry> mEntries = null;
    int mNumHandles = 0;

    ServiceDeclaration() {
        mEntries = new ArrayList<Entry>();
    }
    // guards access to mEntries and mNumHandles in order to make this class thread-safe
    private final Object mLock = new Object();
    private final List<Entry> mEntries = new ArrayList<>();
    private int mNumHandles = 0;

    void addService(UUID uuid, int serviceType, int instance, int minHandles,
            boolean advertisePreferred) {
        synchronized (mLock) {
            mEntries.add(new Entry(uuid, serviceType, instance, advertisePreferred));
            if (minHandles == 0) {
                ++mNumHandles;
@@ -87,32 +84,42 @@ class ServiceDeclaration {
                mNumHandles = minHandles;
            }
        }
    }

    void addIncludedService(UUID uuid, int serviceType, int instance) {
        Entry entry = new Entry(uuid, serviceType, instance);
        entry.type = TYPE_INCLUDED_SERVICE;
        synchronized (mLock) {
            mEntries.add(entry);
            ++mNumHandles;
        }
    }

    void addCharacteristic(UUID uuid, int properties, int permissions) {
        synchronized (mLock) {
            mEntries.add(new Entry(uuid, properties, permissions, 0 /*instance*/));
            mNumHandles += 2;
        }
    }

    void addDescriptor(UUID uuid, int permissions) {
        synchronized (mLock) {
            mEntries.add(new Entry(uuid, permissions));
            ++mNumHandles;
        }
    }

    Entry getNext() {
        synchronized (mLock) {
            if (mEntries.isEmpty()) return null;
            Entry entry = mEntries.get(0);
            mEntries.remove(0);
            return entry;
        }
    }

    boolean isServiceAdvertisePreferred(UUID uuid) {
        synchronized (mLock) {
            for (Entry entry : mEntries) {
                if (entry.uuid.equals(uuid)) {
                    return entry.advertisePreferred;
@@ -120,8 +127,11 @@ class ServiceDeclaration {
            }
            return false;
        }
    }

    int getNumHandles() {
        synchronized (mLock) {
            return mNumHandles;
        }
    }
}