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

Commit aefdfa8f authored by Andre Eisenbach's avatar Andre Eisenbach Committed by Android (Google) Code Review
Browse files

Merge "Defer callbacks if the transport is congested" into lmp-dev

parents 0c03f962 8db30c72
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
/*
 * 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;
    }
}
+15 −0
Original line number Diff line number Diff line
@@ -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 */
+38 −8
Original line number Diff line number Diff line
@@ -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));
        } 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;

        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);
        }
    }