From f8ecbbb375c6a41895e0144d8d8cd42587891570 Mon Sep 17 00:00:00 2001 From: Calvin On Date: Tue, 19 Apr 2016 19:17:50 -0700 Subject: [PATCH] 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 --- .../android/bluetooth/gatt/ServiceDeclaration.java | 82 ++++++++++++---------- 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/src/com/android/bluetooth/gatt/ServiceDeclaration.java b/src/com/android/bluetooth/gatt/ServiceDeclaration.java index 1d0bc4e9..37316b1b 100644 --- a/src/com/android/bluetooth/gatt/ServiceDeclaration.java +++ b/src/com/android/bluetooth/gatt/ServiceDeclaration.java @@ -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; @@ -49,11 +47,11 @@ class ServiceDeclaration { } Entry(UUID uuid, int serviceType, int instance, boolean advertisePreferred) { - this.type = TYPE_SERVICE; - this.uuid = uuid; - this.instance = instance; - this.serviceType = serviceType; - this.advertisePreferred = advertisePreferred; + this.type = TYPE_SERVICE; + this.uuid = uuid; + this.instance = instance; + this.serviceType = serviceType; + this.advertisePreferred = advertisePreferred; } Entry(UUID uuid, int properties, int permissions, int instance) { @@ -71,57 +69,69 @@ class ServiceDeclaration { } } - List mEntries = null; - int mNumHandles = 0; - - ServiceDeclaration() { - mEntries = new ArrayList(); - } + // guards access to mEntries and mNumHandles in order to make this class thread-safe + private final Object mLock = new Object(); + private final List mEntries = new ArrayList<>(); + private int mNumHandles = 0; void addService(UUID uuid, int serviceType, int instance, int minHandles, - boolean advertisePreferred) { - mEntries.add(new Entry(uuid, serviceType, instance, advertisePreferred)); - if (minHandles == 0) { - ++mNumHandles; - } else { - mNumHandles = minHandles; + boolean advertisePreferred) { + synchronized (mLock) { + mEntries.add(new Entry(uuid, serviceType, instance, advertisePreferred)); + if (minHandles == 0) { + ++mNumHandles; + } else { + mNumHandles = minHandles; + } } } void addIncludedService(UUID uuid, int serviceType, int instance) { Entry entry = new Entry(uuid, serviceType, instance); entry.type = TYPE_INCLUDED_SERVICE; - mEntries.add(entry); - ++mNumHandles; + synchronized (mLock) { + mEntries.add(entry); + ++mNumHandles; + } } void addCharacteristic(UUID uuid, int properties, int permissions) { - mEntries.add(new Entry(uuid, properties, permissions, 0 /*instance*/)); - mNumHandles += 2; + synchronized (mLock) { + mEntries.add(new Entry(uuid, properties, permissions, 0 /*instance*/)); + mNumHandles += 2; + } } void addDescriptor(UUID uuid, int permissions) { - mEntries.add(new Entry(uuid, permissions)); - ++mNumHandles; + synchronized (mLock) { + mEntries.add(new Entry(uuid, permissions)); + ++mNumHandles; + } } Entry getNext() { - if (mEntries.isEmpty()) return null; - Entry entry = mEntries.get(0); - mEntries.remove(0); - return entry; + synchronized (mLock) { + if (mEntries.isEmpty()) return null; + Entry entry = mEntries.get(0); + mEntries.remove(0); + return entry; + } } boolean isServiceAdvertisePreferred(UUID uuid) { - for (Entry entry : mEntries) { - if (entry.uuid.equals(uuid)) { - return entry.advertisePreferred; - } - } - return false; + synchronized (mLock) { + for (Entry entry : mEntries) { + if (entry.uuid.equals(uuid)) { + return entry.advertisePreferred; + } + } + return false; + } } int getNumHandles() { - return mNumHandles; + synchronized (mLock) { + return mNumHandles; + } } } -- 2.11.0