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

Commit 396bb198 authored by Wei Wang's avatar Wei Wang Committed by Android Git Automerger
Browse files

am 5dcf9bb6: Merge "Add support of advertising through standard instance.(2/4)" into lmp-sprout-dev

* commit '5dcf9bb6':
  Add support of advertising through standard instance.(2/4)
parents ea027e28 5dcf9bb6
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -1715,6 +1715,8 @@ static JNINativeMethod sAdvertiseMethods[] = {
    {"gattClientUpdateAdvNative", "(IIIIIII)V", (void *) gattClientUpdateAdvNative},
    {"gattClientSetAdvDataNative", "(IZZZI[B[B[B)V", (void *) gattClientSetAdvDataNative},
    {"gattClientDisableAdvNative", "(I)V", (void *) gattClientDisableAdvNative},
    {"gattSetAdvDataNative", "(IZZZIII[B[B[B)V", (void *) gattSetAdvDataNative},
    {"gattAdvertiseNative", "(IZ)V", (void *) gattAdvertiseNative},
};

// JNI functions defined in ScanManager class.
@@ -1758,7 +1760,6 @@ static JNINativeMethod sMethods[] = {
    {"gattClientExecuteWriteNative", "(IZ)V", (void *) gattClientExecuteWriteNative},
    {"gattClientRegisterForNotificationsNative", "(ILjava/lang/String;IIJJIJJZ)V", (void *) gattClientRegisterForNotificationsNative},
    {"gattClientReadRemoteRssiNative", "(ILjava/lang/String;)V", (void *) gattClientReadRemoteRssiNative},
    {"gattAdvertiseNative", "(IZ)V", (void *) gattAdvertiseNative},
    {"gattClientConfigureMTUNative", "(II)V", (void *) gattClientConfigureMTUNative},
    {"gattConnectionParameterUpdateNative", "(ILjava/lang/String;IIII)V", (void *) gattConnectionParameterUpdateNative},
    {"gattServerRegisterAppNative", "(JJ)V", (void *) gattServerRegisterAppNative},
@@ -1776,7 +1777,6 @@ static JNINativeMethod sMethods[] = {
    {"gattServerSendNotificationNative", "(III[B)V", (void *) gattServerSendNotificationNative},
    {"gattServerSendResponseNative", "(IIIIII[BI)V", (void *) gattServerSendResponseNative},

    {"gattSetAdvDataNative", "(IZZZIII[B[B[B)V", (void *) gattSetAdvDataNative},
    {"gattTestNative", "(IJJLjava/lang/String;IIIII)V", (void *) gattTestNative},
};

+21 −4
Original line number Diff line number Diff line
@@ -54,14 +54,16 @@ import android.os.SystemClock;
import android.provider.Settings;
import android.util.Log;
import android.util.Pair;

import com.android.bluetooth.a2dp.A2dpService;
import com.android.bluetooth.hid.HidService;
import com.android.bluetooth.hfp.HeadsetService;
import com.android.bluetooth.hdp.HealthService;
import com.android.bluetooth.pan.PanService;
import com.android.bluetooth.R;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.RemoteDevices.DeviceProperties;
import com.android.internal.R;

import java.io.FileDescriptor;
import java.io.IOException;
import java.util.ArrayList;
@@ -71,6 +73,7 @@ import java.util.Map;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.List;

import android.content.pm.PackageManager;
import android.os.ServiceManager;

@@ -1071,8 +1074,13 @@ public class AdapterService extends Service {
         public boolean isMultiAdvertisementSupported() {
             AdapterService service = getService();
             if (service == null) return false;
             int val = service.getNumOfAdvertisementInstancesSupported();
             return (val >= MIN_ADVT_INSTANCES_FOR_MA);
             return service.isMultiAdvertisementSupported();
         }

         public boolean isPeripheralModeSupported() {
             AdapterService service = getService();
             if (service == null) return false;
             return service.isPeripheralModeSupported();
         }

         public boolean isOffloadedFilteringSupported() {
@@ -1632,6 +1640,11 @@ public class AdapterService extends Service {
        return mAdapterProperties.getNumOfAdvertisementInstancesSupported();
    }

    public boolean isMultiAdvertisementSupported() {
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
        return getNumOfAdvertisementInstancesSupported() >= MIN_ADVT_INSTANCES_FOR_MA;
    }

    public boolean isRpaOffloadSupported() {
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
        return mAdapterProperties.isRpaOffloadSupported();
@@ -1647,6 +1660,10 @@ public class AdapterService extends Service {
        return mAdapterProperties.getNumOfOffloadedScanFilterSupported();
    }

    public boolean isPeripheralModeSupported() {
        return getResources().getBoolean(R.bool.config_bluetooth_le_peripheral_mode_supported);
    }

    public int getOffloadedScanResultStorage() {
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
        return mAdapterProperties.getOffloadedScanResultStorage();
+79 −23
Original line number Diff line number Diff line
@@ -40,7 +40,7 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * Manages Bluetooth LE advertising operations and interacts with bluedroid stack.
 * Manages Bluetooth LE advertising operations and interacts with bluedroid stack. TODO: add tests.
 *
 * @hide
 */
@@ -56,6 +56,7 @@ class AdvertiseManager {
    private static final int MSG_STOP_ADVERTISING = 1;

    private final GattService mService;
    private final AdapterService mAdapterService;
    private final Set<AdvertiseClient> mAdvertiseClients;
    private final AdvertiseNative mAdvertiseNative;

@@ -68,9 +69,10 @@ class AdvertiseManager {
    /**
     * Constructor of {@link AdvertiseManager}.
     */
    AdvertiseManager(GattService service) {
        mService = service;
    AdvertiseManager(GattService service, AdapterService adapterService) {
        logd("advertise manager created");
        mService = service;
        mAdapterService = adapterService;
        mAdvertiseClients = new HashSet<AdvertiseClient>();
        mAdvertiseNative = new AdvertiseNative();
    }
@@ -218,13 +220,17 @@ class AdvertiseManager {
        }

        // Returns maximum advertise instances supported by controller.
        private int maxAdvertiseInstances() {
            AdapterService adapter = AdapterService.getAdapterService();
            int numOfAdvtInstances = adapter.getNumOfAdvertisementInstancesSupported();
        int maxAdvertiseInstances() {
            // Note numOfAdvtInstances includes the standard advertising instance.
            // TODO: remove - 1 once the stack is able to include standard instance for multiple
            // advertising.
            return numOfAdvtInstances - 1;
            if (mAdapterService.isMultiAdvertisementSupported()) {
                return mAdapterService.getNumOfAdvertisementInstancesSupported() - 1;
            }
            if (mAdapterService.isPeripheralModeSupported()) {
                return 1;
            }
            return 0;
        }
    }

@@ -258,21 +264,33 @@ class AdvertiseManager {
        private static final int ADVERTISING_EVENT_TYPE_SCANNABLE = 2;
        private static final int ADVERTISING_EVENT_TYPE_NON_CONNECTABLE = 3;

        // TODO: Extract advertising logic into interface as we have multiple implementations now.
        boolean startAdverising(AdvertiseClient client) {
            int clientIf = client.clientIf;
            if (!mAdapterService.isMultiAdvertisementSupported() &&
                    !mAdapterService.isPeripheralModeSupported()) {
                return false;
            }
            if (mAdapterService.isMultiAdvertisementSupported()) {
                return startMultiAdvertising(client);
            }
            return startSingleAdvertising(client);
        }

        boolean startMultiAdvertising(AdvertiseClient client) {
            logd("starting multi advertising");
            resetCountDownLatch();
            mAdvertiseNative.enableAdvertising(client);
            enableAdvertising(client);
            if (!waitForCallback()) {
                return false;
            }
            resetCountDownLatch();
            mAdvertiseNative.setAdvertisingData(clientIf, client.advertiseData, false);
            setAdvertisingData(client, client.advertiseData, false);
            if (!waitForCallback()) {
                return false;
            }
            if (client.scanResponse != null) {
                resetCountDownLatch();
                mAdvertiseNative.setAdvertisingData(clientIf, client.scanResponse, true);
                setAdvertisingData(client, client.scanResponse, true);
                if (!waitForCallback()) {
                    return false;
                }
@@ -280,8 +298,29 @@ class AdvertiseManager {
            return true;
        }

        boolean startSingleAdvertising(AdvertiseClient client) {
            logd("starting single advertising");
            resetCountDownLatch();
            enableAdvertising(client);
            if (!waitForCallback()) {
                return false;
            }
            setAdvertisingData(client, client.advertiseData, false);
            return true;
        }

        void stopAdvertising(AdvertiseClient client) {
            if (mAdapterService.isMultiAdvertisementSupported()) {
                gattClientDisableAdvNative(client.clientIf);
            } else {
                gattAdvertiseNative(client.clientIf, false);
                try {
                    mService.onAdvertiseInstanceDisabled(
                            AdvertiseCallback.ADVERTISE_SUCCESS, client.clientIf);
                } catch (RemoteException e) {
                    Log.d(TAG, "failed onAdvertiseInstanceDisabled", e);
                }
            }
        }

        private void resetCountDownLatch() {
@@ -305,6 +344,7 @@ class AdvertiseManager {
            int txPowerLevel = getTxPowerLevel(client.settings);
            int advertiseTimeoutSeconds = (int) TimeUnit.MILLISECONDS.toSeconds(
                    client.settings.getTimeout());
            if (mAdapterService.isMultiAdvertisementSupported()) {
                gattClientEnableAdvNative(
                        clientIf,
                        minAdvertiseUnit, maxAdvertiseUnit,
@@ -312,9 +352,13 @@ class AdvertiseManager {
                        ADVERTISING_CHANNEL_ALL,
                        txPowerLevel,
                        advertiseTimeoutSeconds);
            } else {
                gattAdvertiseNative(client.clientIf, true);
            }
        }

        private void setAdvertisingData(int clientIf, AdvertiseData data, boolean isScanResponse) {
        private void setAdvertisingData(AdvertiseClient client, AdvertiseData data,
                boolean isScanResponse) {
            if (data == null) {
                return;
            }
@@ -340,10 +384,16 @@ class AdvertiseManager {
                }
                serviceUuids = advertisingUuidBytes.array();
            }
            gattClientSetAdvDataNative(clientIf, isScanResponse, includeName, includeTxPower,
                    appearance,
            if (mAdapterService.isMultiAdvertisementSupported()) {
                gattClientSetAdvDataNative(client.clientIf, isScanResponse, includeName,
                        includeTxPower, appearance,
                        manufacturerData, serviceData, serviceUuids);
            } else {
                gattSetAdvDataNative(client.clientIf, isScanResponse, includeName,
                        includeTxPower, 0, 0, appearance,
                        manufacturerData, serviceData, serviceUuids);
            }
        }

        // Combine manufacturer id and manufacturer data.
        private byte[] getManufacturerData(AdvertiseData advertiseData) {
@@ -441,6 +491,12 @@ class AdvertiseManager {
        private native void gattClientSetAdvDataNative(int client_if,
                boolean set_scan_rsp, boolean incl_name, boolean incl_txpower, int appearance,
                byte[] manufacturer_data, byte[] service_data, byte[] service_uuid);

        private native void gattSetAdvDataNative(int serverIf, boolean setScanRsp, boolean inclName,
                boolean inclTxPower, int minSlaveConnectionInterval, int maxSlaveConnectionInterval,
                int appearance, byte[] manufacturerData, byte[] serviceData, byte[] serviceUuid);

        private native void gattAdvertiseNative(int client_if, boolean start);
    }

    private void logd(String s) {
+3 −8
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import android.os.SystemClock;
import android.util.Log;

import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.ProfileService;

import java.util.ArrayList;
@@ -160,7 +161,7 @@ public class GattService extends ProfileService {
    protected boolean start() {
        if (DBG) Log.d(TAG, "start()");
        initializeNative();
        mAdvertiseManager = new AdvertiseManager(this);
        mAdvertiseManager = new AdvertiseManager(this, AdapterService.getAdapterService());
        mAdvertiseManager.start();

        mScanManager = new ScanManager(this);
@@ -546,7 +547,6 @@ public class GattService extends ProfileService {
    void onScanResult(String address, int rssi, byte[] adv_data) {
        if (VDBG) Log.d(TAG, "onScanResult() - address=" + address
                    + ", rssi=" + rssi);
        ScanRecord record = ScanRecord.parseFromBytes(adv_data);
        List<UUID> remoteUuids = parseUuids(adv_data);
        for (ScanClient client : mScanManager.getRegularScanQueue()) {
            if (client.uuids.length > 0) {
@@ -1175,6 +1175,7 @@ public class GattService extends ProfileService {
    // Callback for standard advertising instance.
    void onAdvertiseCallback(int status, int clientIf) {
        if (DBG) Log.d(TAG, "onAdvertiseCallback,- clientIf=" + clientIf + ", status=" + status);
        mAdvertiseManager.callbackDone(clientIf, status);
    }

    // Followings are callbacks for Bluetooth LE Advertise operations.
@@ -2274,17 +2275,11 @@ public class GattService extends ProfileService {
    private native void gattClientReadRemoteRssiNative(int clientIf,
            String address);

    private native void gattAdvertiseNative(int client_if, boolean start);

    private native void gattClientConfigureMTUNative(int conn_id, int mtu);

    private native void gattConnectionParameterUpdateNative(int client_if, String address,
            int minInterval, int maxInterval, int latency, int timeout);

    private native void gattSetAdvDataNative(int serverIf, boolean setScanRsp, boolean inclName,
            boolean inclTxPower, int minInterval, int maxInterval,
            int appearance, byte[] manufacturerData, byte[] serviceData, byte[] serviceUuid);

    private native void gattServerRegisterAppNative(long app_uuid_lsb,
                                                    long app_uuid_msb);