summaryrefslogtreecommitdiffstats
path: root/src/com/android/bluetooth/gatt
diff options
context:
space:
mode:
authorPrerepa Viswanadham <dham@google.com>2014-09-19 12:54:04 -0700
committerAndre Eisenbach <eisenbach@google.com>2014-09-23 19:04:13 -0700
commit934dee789c0c68607a704c5c31ae2e4b956dc227 (patch)
tree24eff58e7d1b36c3409957bee9c91778b17d3d96 /src/com/android/bluetooth/gatt
parent7532f1cdeca345db5a959c6f570bec0f19f0b820 (diff)
downloadandroid_packages_apps_Bluetooth-934dee789c0c68607a704c5c31ae2e4b956dc227.tar.gz
android_packages_apps_Bluetooth-934dee789c0c68607a704c5c31ae2e4b956dc227.tar.bz2
android_packages_apps_Bluetooth-934dee789c0c68607a704c5c31ae2e4b956dc227.zip
Defer callbacks if the transport is congested
Hold client characteristic write callbacks and server notification callbacks if the transport is congested. When the congestion clears up, all queued callbacks are sent to the application. Bug: 17289507 Change-Id: Ib22d7857ac3990fd3cc922aedd4258013e1af54c
Diffstat (limited to 'src/com/android/bluetooth/gatt')
-rw-r--r--src/com/android/bluetooth/gatt/CallbackInfo.java52
-rw-r--r--src/com/android/bluetooth/gatt/ContextMap.java15
-rw-r--r--src/com/android/bluetooth/gatt/GattService.java46
3 files changed, 105 insertions, 8 deletions
diff --git a/src/com/android/bluetooth/gatt/CallbackInfo.java b/src/com/android/bluetooth/gatt/CallbackInfo.java
new file mode 100644
index 000000000..25dfd4cc1
--- /dev/null
+++ b/src/com/android/bluetooth/gatt/CallbackInfo.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.bluetooth.gatt;
+
+import java.util.UUID;
+
+/**
+ * Helper class that keeps track of callback parameters for app callbacks.
+ * These are held during congestion and reported when congestion clears.
+ * @hide
+ */
+/*package*/
+
+class CallbackInfo {
+ String address;
+ int status;
+ int srvcType;
+ int srvcInstId;
+ UUID srvcUuid;
+ int charInstId;
+ UUID charUuid;
+
+ CallbackInfo(String address, int status, int srvcType, int srvcInstId,
+ UUID srvcUuid, int charInstId, UUID charUuid) {
+ this.address = address;
+ this.status = status;
+ this.srvcType = srvcType;
+ this.srvcInstId = srvcInstId;
+ this.srvcUuid = srvcUuid;
+ this.charInstId = charInstId;
+ this.charUuid = charUuid;
+ }
+
+ CallbackInfo(String address, int status) {
+ this.address = address;
+ this.status = status;
+ }
+}
+
diff --git a/src/com/android/bluetooth/gatt/ContextMap.java b/src/com/android/bluetooth/gatt/ContextMap.java
index 62a488a36..65f8dce89 100644
--- a/src/com/android/bluetooth/gatt/ContextMap.java
+++ b/src/com/android/bluetooth/gatt/ContextMap.java
@@ -67,6 +67,12 @@ import java.util.UUID;
/** Death receipient */
private IBinder.DeathRecipient mDeathRecipient;
+ /** Flag to signal that transport is congested */
+ Boolean isCongested = false;
+
+ /** Internal callback info queue, waiting to be send on congestion clear */
+ private List<CallbackInfo> congestionQueue = new ArrayList<CallbackInfo>();
+
/**
* Creates a new app context.
*/
@@ -101,6 +107,15 @@ import java.util.UUID;
}
}
}
+
+ void queueCallback(CallbackInfo callbackInfo) {
+ congestionQueue.add(callbackInfo);
+ }
+
+ CallbackInfo popQueuedCallback() {
+ if (congestionQueue.size() == 0) return null;
+ return congestionQueue.remove(0);
+ }
}
/** Our internal application list */
diff --git a/src/com/android/bluetooth/gatt/GattService.java b/src/com/android/bluetooth/gatt/GattService.java
index 8c2115ce0..982fd16e7 100644
--- a/src/com/android/bluetooth/gatt/GattService.java
+++ b/src/com/android/bluetooth/gatt/GattService.java
@@ -849,10 +849,19 @@ public class GattService extends ProfileService {
+ ", status=" + status);
ClientMap.App app = mClientMap.getByConnId(connId);
- if (app != null) {
+ if (app == null) return;
+
+ if (!app.isCongested) {
app.callback.onCharacteristicWrite(address, status, srvcType,
- srvcInstId, new ParcelUuid(srvcUuid),
- charInstId, new ParcelUuid(charUuid));
+ srvcInstId, new ParcelUuid(srvcUuid),
+ charInstId, new ParcelUuid(charUuid));
+ } else {
+ if (status == BluetoothGatt.GATT_CONNECTION_CONGESTED) {
+ status = BluetoothGatt.GATT_SUCCESS;
+ }
+ CallbackInfo callbackInfo = new CallbackInfo(address, status, srvcType,
+ srvcInstId, srvcUuid, charInstId, charUuid);
+ app.queueCallback(callbackInfo);
}
}
@@ -1213,11 +1222,20 @@ public class GattService extends ProfileService {
}
void onClientCongestion(int connId, boolean congested) throws RemoteException {
- if (DBG) Log.d(TAG, "onClientCongestion() - connId=" + connId + ", congested=" + congested);
+ if (VDBG) Log.d(TAG, "onClientCongestion() - connId=" + connId + ", congested=" + congested);
ClientMap.App app = mClientMap.getByConnId(connId);
+
if (app != null) {
- app.callback.onConnectionCongested(mClientMap.addressByConnId(connId), congested);
+ app.isCongested = congested;
+ while(!app.isCongested) {
+ CallbackInfo callbackInfo = app.popQueuedCallback();
+ if (callbackInfo == null) return;
+ app.callback.onCharacteristicWrite(callbackInfo.address,
+ callbackInfo.status, callbackInfo.srvcType,
+ callbackInfo.srvcInstId, new ParcelUuid(callbackInfo.srvcUuid),
+ callbackInfo.charInstId, new ParcelUuid(callbackInfo.charUuid));
+ }
}
}
@@ -1783,15 +1801,27 @@ public class GattService extends ProfileService {
ServerMap.App app = mServerMap.getByConnId(connId);
if (app == null) return;
- app.callback.onNotificationSent(address, status);
+ if (!app.isCongested) {
+ app.callback.onNotificationSent(address, status);
+ } else {
+ if (status == BluetoothGatt.GATT_CONNECTION_CONGESTED) {
+ status = BluetoothGatt.GATT_SUCCESS;
+ }
+ app.queueCallback(new CallbackInfo(address, status));
+ }
}
void onServerCongestion(int connId, boolean congested) throws RemoteException {
if (DBG) Log.d(TAG, "onServerCongestion() - connId=" + connId + ", congested=" + congested);
ServerMap.App app = mServerMap.getByConnId(connId);
- if (app != null) {
- app.callback.onConnectionCongested(mServerMap.addressByConnId(connId), congested);
+ if (app == null) return;
+
+ app.isCongested = congested;
+ while(!app.isCongested) {
+ CallbackInfo callbackInfo = app.popQueuedCallback();
+ if (callbackInfo == null) return;
+ app.callback.onNotificationSent(callbackInfo.address, callbackInfo.status);
}
}