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

Commit 9835f684 authored by Hemant Gupta's avatar Hemant Gupta Committed by Jack He
Browse files

Add scan filter for Transport Discovery data

Snapshot of:
e34905bdfd2e0064b8c4d0332234f590e1cafac3
325e5fb544757097b32d9bb3ef2793c114b90ec6
91b711eb0d46f5b05c3a6d7d68f817eb917e08f1
cfd02ab820ac7869aee7ab9b3349d4bcab914d52
060b1c3e022d1350012b2776b2e1b3e8dd9f3cbd

Bug: 262744495
Tag: #feature
Test: Manual end-to-end testing (Need BT Controller Support for sub opcode 0x08 in APCF Scan Filter)
API-Coverage-Bug: 270510247
Test: atest LeScanningManagerAndroidHciTest
Test: atest CtsBluetoothTestCases

Change-Id: I84b791d7424620bc7db5b19e8f6a14938b1524af
parent cdc0d841
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -1771,6 +1771,9 @@ static void gattClientScanFilterAddNative(JNIEnv* env, jobject object,
  jfieldID adTypeFid = env->GetFieldID(entryClazz, "ad_type", "I");
  jfieldID dataFid = env->GetFieldID(entryClazz, "data", "[B");
  jfieldID dataMaskFid = env->GetFieldID(entryClazz, "data_mask", "[B");
  jfieldID orgFid = env->GetFieldID(entryClazz, "org_id", "I");
  jfieldID TDSFlagsFid = env->GetFieldID(entryClazz, "tds_flags", "I");
  jfieldID TDSFlagsMaskFid = env->GetFieldID(entryClazz, "tds_flags_mask", "I");

  for (int i = 0; i < numFilters; ++i) {
    ApcfCommand curr{};
@@ -1863,6 +1866,10 @@ static void gattClientScanFilterAddNative(JNIEnv* env, jobject object,
        env->ReleaseByteArrayElements(data_mask.get(), data_array, JNI_ABORT);
      }
    }
    curr.org_id = env->GetIntField(current.get(), orgFid);
    curr.tds_flags = env->GetIntField(current.get(), TDSFlagsFid);
    curr.tds_flags_mask = env->GetIntField(current.get(), TDSFlagsMaskFid);

    native_filters.push_back(curr);
  }

+13 −1
Original line number Diff line number Diff line
@@ -130,6 +130,7 @@ class AdapterProperties {
    private boolean mIsLeExtendedAdvertisingSupported;
    private boolean mIsLePeriodicAdvertisingSupported;
    private int mLeMaximumAdvertisingDataLength;
    private boolean mIsOffloadedTransportDiscoveryDataScanSupported;

    private int mIsDynamicAudioBufferSizeSupported;
    private int mDynamicAudioBufferSizeSupportedCodecsGroup1;
@@ -579,6 +580,14 @@ class AdapterProperties {
        return mTotNumOfTrackableAdv;
    }


    /**
     * @return the isOffloadedTransportDiscoveryDataScanSupported
     */
    public boolean isOffloadedTransportDiscoveryDataScanSupported() {
        return mIsOffloadedTransportDiscoveryDataScanSupported;
    }

    /**
     * @return the maximum number of connected audio devices
     */
@@ -1081,6 +1090,7 @@ class AdapterProperties {
        mIsLeConnectedIsochronousStreamCentralSupported = ((0xFF & ((int) val[25])) != 0);
        mIsLeIsochronousBroadcasterSupported = ((0xFF & ((int) val[26])) != 0);
        mIsLePeriodicAdvertisingSyncTransferRecipientSupported = ((0xFF & ((int) val[27])) != 0);
        mIsOffloadedTransportDiscoveryDataScanSupported = ((0x01 & ((int) val[28])) != 0);

        Log.d(TAG, "BT_PROPERTY_LOCAL_LE_FEATURES: update from BT controller"
                + " mNumOfAdvertisementInstancesSupported = "
@@ -1108,7 +1118,9 @@ class AdapterProperties {
                + " mIsLeIsochronousBroadcasterSupported = "
                + mIsLeIsochronousBroadcasterSupported
                + " mIsLePeriodicAdvertisingSyncTransferRecipientSupported = "
                + mIsLePeriodicAdvertisingSyncTransferRecipientSupported);
                + mIsLePeriodicAdvertisingSyncTransferRecipientSupported
                + " mIsOffloadedTransportDiscoveryDataScanSupported = "
                + mIsOffloadedTransportDiscoveryDataScanSupported);
        invalidateIsOffloadedFilteringSupportedCache();
    }

+39 −0
Original line number Diff line number Diff line
@@ -4525,6 +4525,7 @@ public class AdapterService extends Service {
                receiver.propagateException(e);
            }
        }

        @RequiresPermission(allOf = {
                android.Manifest.permission.BLUETOOTH_CONNECT,
                android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -4587,6 +4588,33 @@ public class AdapterService extends Service {
            }
            return BluetoothStatusCodes.SUCCESS;
        }

        @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
        @Override
        public void isOffloadedTransportDiscoveryDataScanSupported(
                AttributionSource source, SynchronousResultReceiver receiver) {
            try {
                receiver.send(isOffloadedTransportDiscoveryDataScanSupported(source));
            } catch (RuntimeException e) {
                receiver.propagateException(e);
            }
        }

        private int isOffloadedTransportDiscoveryDataScanSupported(
                AttributionSource attributionSource) {
            AdapterService service = getService();
            if (service == null
                    || !callerIsSystemOrActiveOrManagedUser(service, TAG,
                            "isOffloadedTransportDiscoveryDataScanSupported")
                    || !Utils.checkScanPermissionForDataDelivery(
                            service, attributionSource,
                            "isOffloadedTransportDiscoveryDataScanSupported")) {
                return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_SCAN_PERMISSION;
            }
            enforceBluetoothPrivilegedPermission(service);

            return service.isOffloadedTransportDiscoveryDataScanSupported();
        }
    }

    /**
@@ -5809,6 +5837,17 @@ public class AdapterService extends Service {
        return mAdapterProperties.getTotalNumOfTrackableAdvertisements();
    }

    /**
     * Return if offloaded TDS filter is supported.
     * @return true if supported
     */
    public int isOffloadedTransportDiscoveryDataScanSupported() {
        if (mAdapterProperties.isOffloadedTransportDiscoveryDataScanSupported()) {
            return BluetoothStatusCodes.FEATURE_SUPPORTED;
        }
        return BluetoothStatusCodes.FEATURE_NOT_SUPPORTED;
    }

    /**
     * Notify the UID and package name of the app, and the address of associated active device
     *
+33 −0
Original line number Diff line number Diff line
@@ -16,8 +16,10 @@

package com.android.bluetooth.gatt;

import android.bluetooth.BluetoothAssignedNumbers.OrganizationId;
import android.bluetooth.BluetoothUuid;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.TransportBlockFilter;
import android.os.ParcelUuid;

import java.util.Arrays;
@@ -39,6 +41,7 @@ import java.util.UUID;
    public static final int TYPE_LOCAL_NAME = 4;
    public static final int TYPE_MANUFACTURER_DATA = 5;
    public static final int TYPE_SERVICE_DATA = 6;
    public static final int TYPE_TRANSPORT_DISCOVERY_DATA = 7;
    public static final int TYPE_ADVERTISING_DATA_TYPE = 8;

    // Max length is 31 - 3(flags) - 2 (one byte for length and one byte for type).
@@ -60,6 +63,9 @@ import java.util.UUID;
        public int ad_type;
        public byte[] data;
        public byte[] data_mask;
        public int org_id;
        public int tds_flags;
        public int tds_flags_mask;
    }

    private Set<Entry> mEntries = new HashSet<Entry>();
@@ -147,6 +153,18 @@ import java.util.UUID;
        mEntries.add(entry);
    }

    void addTransportDiscoveryData(int orgId, int tdsFlags, int tdsFlagsMask,
            byte[] transportData, byte[] transportDataMask) {
        Entry entry = new Entry();
        entry.type = TYPE_TRANSPORT_DISCOVERY_DATA;
        entry.org_id = orgId;
        entry.tds_flags = tdsFlags;
        entry.tds_flags_mask = tdsFlagsMask;
        entry.data = transportData;
        entry.data_mask = transportDataMask;
        mEntries.add(entry);
    }

    void addAdvertisingDataType(int adType, byte[] data, byte[] dataMask) {
        Entry entry = new Entry();
        entry.type = TYPE_ADVERTISING_DATA_TYPE;
@@ -241,6 +259,21 @@ import java.util.UUID;
            addAdvertisingDataType(filter.getAdvertisingDataType(),
                    filter.getAdvertisingData(), filter.getAdvertisingDataMask());
        }
        final TransportBlockFilter transportBlockFilter = filter.getTransportBlockFilter();
        if (transportBlockFilter != null) {
            if (transportBlockFilter.getOrgId()
                    == OrganizationId.WIFI_ALLIANCE_NEIGHBOR_AWARENESS_NETWORKING) {
                addTransportDiscoveryData(transportBlockFilter.getOrgId(),
                        transportBlockFilter.getTdsFlags(), transportBlockFilter.getTdsFlagsMask(),
                        transportBlockFilter.getWifiNanHash(), null);
            } else {
                addTransportDiscoveryData(transportBlockFilter.getOrgId(),
                        transportBlockFilter.getTdsFlags(), transportBlockFilter.getTdsFlagsMask(),
                        transportBlockFilter.getTransportData(),
                        transportBlockFilter.getTransportDataMask());
            }

        }
    }

    private byte[] concate(ParcelUuid serviceDataUuid, byte[] serviceData) {
+6 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static android.bluetooth.le.ScanSettings.SCAN_MODE_SCREEN_OFF_BALANCED;

import static com.google.common.truth.Truth.assertThat;

import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.anyString;
@@ -40,9 +41,13 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.ActivityManager;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProtoEnums;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanRecord;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.bluetooth.le.TransportDiscoveryData;
import android.content.Context;
import android.location.LocationManager;
import android.os.Binder;
@@ -61,6 +66,7 @@ import com.android.bluetooth.TestUtils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.BluetoothAdapterProxy;
import com.android.bluetooth.btservice.MetricsLogger;
import com.android.internal.util.ArrayUtils;

import java.util.ArrayList;
import java.util.List;
Loading