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

Commit 0d60415f authored by Jakub Pawlowski's avatar Jakub Pawlowski Committed by android-build-merger
Browse files

Merge "Separate advertiser from GATT client (1/4)" am: 5f87c4539a

am: 40a16ea242

Change-Id: I0d08f623e78fdd779b39083d0da3a45aee72ff3c
parents 7183caa2 2e7f4ae7
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -82,11 +82,6 @@ public class BluetoothGattCallbackWrapper extends IBluetoothGattCallback.Stub {
    public void onReadRemoteRssi(String address, int rssi, int status) throws RemoteException {
    }

    @Override
    public void onMultiAdvertiseCallback(int status, boolean isStart,
            AdvertiseSettings advertiseSettings) throws RemoteException {
    }

    @Override
    public void onConfigureMTU(String address, int mtu, int status) throws RemoteException {
    }
+7 −2
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.os.WorkSource;

import android.bluetooth.IBluetoothGattCallback;
import android.bluetooth.IBluetoothGattServerCallback;
import android.bluetooth.le.IAdvertiserCallback;

/**
 * API for interacting with BLE / GATT
@@ -41,11 +42,15 @@ interface IBluetoothGatt {
                   in String callingPackage);
    void stopScan(in int appIf, in boolean isServer);
    void flushPendingBatchResults(in int appIf, in boolean isServer);
    void startMultiAdvertising(in int appIf,

    void registerAdvertiser(in IAdvertiserCallback callback);
    void unregisterAdvertiser(in int advertiserId);
    void startMultiAdvertising(in int advertiserId,
                               in AdvertiseData advertiseData,
                               in AdvertiseData scanResponse,
                               in AdvertiseSettings settings);
    void stopMultiAdvertising(in int appIf);
    void stopMultiAdvertising(in int advertiserId);

    void registerClient(in ParcelUuid appId, in IBluetoothGattCallback callback);
    void unregisterClient(in int clientIf);
    void clientConnect(in int clientIf, in String address, in boolean isDirect, in int transport);
+0 −2
Original line number Diff line number Diff line
@@ -38,8 +38,6 @@ oneway interface IBluetoothGattCallback {
    void onDescriptorWrite(in String address, in int status, in int handle);
    void onNotify(in String address, in int handle, in byte[] value);
    void onReadRemoteRssi(in String address, in int rssi, in int status);
    void onMultiAdvertiseCallback(in int status, boolean isStart,
                                  in AdvertiseSettings advertiseSettings);
    void onScanManagerErrorCallback(in int errorCode);
    void onConfigureMTU(in String address, in int mtu, in int status);
    void onFoundOrLost(in boolean onFound, in ScanResult scanResult);
+26 −26
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.bluetooth.BluetoothGattCallbackWrapper;
import android.bluetooth.BluetoothUuid;
import android.bluetooth.IBluetoothGatt;
import android.bluetooth.IBluetoothManager;
import android.bluetooth.le.IAdvertiserCallback;
import android.os.Handler;
import android.os.Looper;
import android.os.ParcelUuid;
@@ -162,7 +163,7 @@ public final class BluetoothLeAdvertiser {
    }

    /**
     * Cleans up advertise clients. Should be called when bluetooth is down.
     * Cleans up advertisers. Should be called when bluetooth is down.
     *
     * @hide
     */
@@ -228,7 +229,7 @@ public final class BluetoothLeAdvertiser {
    /**
     * Bluetooth GATT interface callbacks for advertising.
     */
    private class AdvertiseCallbackWrapper extends BluetoothGattCallbackWrapper {
    private class AdvertiseCallbackWrapper extends IAdvertiserCallback.Stub {
        private static final int LE_CALLBACK_TIMEOUT_MILLIS = 2000;
        private final AdvertiseCallback mAdvertiseCallback;
        private final AdvertiseData mAdvertisement;
@@ -236,10 +237,10 @@ public final class BluetoothLeAdvertiser {
        private final AdvertiseSettings mSettings;
        private final IBluetoothGatt mBluetoothGatt;

        // mClientIf 0: not registered
        // mAdvertiserId 0: not registered
        // -1: advertise stopped or registration timeout
        // >0: registered and advertising started
        private int mClientIf;
        private int mAdvertiserId;
        private boolean mIsAdvertising = false;

        public AdvertiseCallbackWrapper(AdvertiseCallback advertiseCallback,
@@ -251,35 +252,34 @@ public final class BluetoothLeAdvertiser {
            mScanResponse = scanResponse;
            mSettings = settings;
            mBluetoothGatt = bluetoothGatt;
            mClientIf = 0;
            mAdvertiserId = 0;
        }

        public void startRegisteration() {
            synchronized (this) {
                if (mClientIf == -1) return;
                if (mAdvertiserId == -1) return;

                try {
                    UUID uuid = UUID.randomUUID();
                    mBluetoothGatt.registerClient(new ParcelUuid(uuid), this);
                    mBluetoothGatt.registerAdvertiser(this);
                    wait(LE_CALLBACK_TIMEOUT_MILLIS);
                } catch (InterruptedException | RemoteException e) {
                    Log.e(TAG, "Failed to start registeration", e);
                }
                if (mClientIf > 0 && mIsAdvertising) {
                if (mAdvertiserId > 0 && mIsAdvertising) {
                    mLeAdvertisers.put(mAdvertiseCallback, this);
                } else if (mClientIf <= 0) {
                } else if (mAdvertiserId <= 0) {

                    // Registration timeout, reset mClientIf to -1 so no subsequent operations can
                    // proceed.
                    if (mClientIf == 0) mClientIf = -1;
                    if (mAdvertiserId == 0) mAdvertiserId = -1;
                    // Post internal error if registration failed.
                    postStartFailure(mAdvertiseCallback,
                            AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
                } else {
                    // Unregister application if it's already registered but advertise failed.
                    try {
                        mBluetoothGatt.unregisterClient(mClientIf);
                        mClientIf = -1;
                        mBluetoothGatt.unregisterAdvertiser(mAdvertiserId);
                        mAdvertiserId = -1;
                    } catch (RemoteException e) {
                        Log.e(TAG, "remote exception when unregistering", e);
                    }
@@ -290,7 +290,7 @@ public final class BluetoothLeAdvertiser {
        public void stopAdvertising() {
            synchronized (this) {
                try {
                    mBluetoothGatt.stopMultiAdvertising(mClientIf);
                    mBluetoothGatt.stopMultiAdvertising(mAdvertiserId);
                    wait(LE_CALLBACK_TIMEOUT_MILLIS);
                } catch (InterruptedException | RemoteException e) {
                    Log.e(TAG, "Failed to stop advertising", e);
@@ -305,20 +305,20 @@ public final class BluetoothLeAdvertiser {
        }

        /**
         * Application interface registered - app is ready to go
         * Advertiser interface registered - app is ready to go
         */
        @Override
        public void onClientRegistered(int status, int clientIf) {
            Log.d(TAG, "onClientRegistered() - status=" + status + " clientIf=" + clientIf);
        public void onAdvertiserRegistered(int status, int advertiserId) {
            Log.d(TAG, "onAdvertiserRegistered() - status=" + status + " advertiserId=" + advertiserId);
            synchronized (this) {
                if (status == BluetoothGatt.GATT_SUCCESS) {
                    try {
                        if (mClientIf == -1) {
                            // Registration succeeds after timeout, unregister client.
                            mBluetoothGatt.unregisterClient(clientIf);
                        if (mAdvertiserId == -1) {
                            // Registration succeeds after timeout, unregister advertiser.
                            mBluetoothGatt.unregisterAdvertiser(advertiserId);
                        } else {
                            mClientIf = clientIf;
                            mBluetoothGatt.startMultiAdvertising(mClientIf, mAdvertisement,
                            mAdvertiserId = advertiserId;
                            mBluetoothGatt.startMultiAdvertising(mAdvertiserId, mAdvertisement,
                                    mScanResponse, mSettings);
                        }
                        return;
@@ -327,7 +327,7 @@ public final class BluetoothLeAdvertiser {
                    }
                }
                // Registration failed.
                mClientIf = -1;
                mAdvertiserId = -1;
                notifyAll();
            }
        }
@@ -346,10 +346,10 @@ public final class BluetoothLeAdvertiser {
                        postStartFailure(mAdvertiseCallback, status);
                    }
                } else {
                    // unregister client for stop.
                    // unregister advertiser for stop.
                    try {
                        mBluetoothGatt.unregisterClient(mClientIf);
                        mClientIf = -1;
                        mBluetoothGatt.unregisterAdvertiser(mAdvertiserId);
                        mAdvertiserId = -1;
                        mIsAdvertising = false;
                        mLeAdvertisers.remove(mAdvertiseCallback);
                    } catch (RemoteException e) {
+29 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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 android.bluetooth.le;

import android.bluetooth.le.AdvertiseSettings;

/**
 * Callback definitions for interacting with Advertiser
 * @hide
 */
oneway interface IAdvertiserCallback {
    void onAdvertiserRegistered(in int status, in int advertiserId);

    void onMultiAdvertiseCallback(in int status, boolean isStart,
                                  in AdvertiseSettings advertiseSettings);
}