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

Commit a40ff7ed authored by pramod kotreshappa's avatar pramod kotreshappa Committed by Bruno Martins
Browse files

PAST feature implementation

- Add support for Periodic Adv Sync Transfer feature
- Add support for cancel periodic sync

CRs-Fixed: 2814452
Change-Id: Ie957bcf32dc2365e9ae7f52f49bd7e0d9fe9505d
parent 3bff355f
Loading
Loading
Loading
Loading
+41 −0
Original line number Diff line number Diff line
@@ -184,6 +184,7 @@ static jmethodID method_onPeriodicAdvertisingEnabled;
static jmethodID method_onSyncLost;
static jmethodID method_onSyncReport;
static jmethodID method_onSyncStarted;
static jmethodID method_onSyncTransferedCallback;

/**
 * Static variables
@@ -2204,6 +2205,8 @@ static void periodicScanClassInitNative(JNIEnv* env, jclass clazz) {
      env->GetMethodID(clazz, "onSyncStarted", "(IIIILjava/lang/String;III)V");
  method_onSyncReport = env->GetMethodID(clazz, "onSyncReport", "(IIII[B)V");
  method_onSyncLost = env->GetMethodID(clazz, "onSyncLost", "(I)V");
  method_onSyncTransferedCallback =
      env->GetMethodID(clazz, "onSyncTransferedCallback", "(IILjava/lang/String;)V");
}

static void periodicScanInitializeNative(JNIEnv* env, jobject object) {
@@ -2278,6 +2281,39 @@ static void stopSyncNative(JNIEnv* env, jobject object, jint sync_handle) {
  sGattIf->scanner->StopSync(sync_handle);
}

static void cancelSyncNative(JNIEnv* env, jobject object, jint sid, jstring address) {
  if (!sGattIf) return;
  sGattIf->scanner->CancelCreateSync(sid, str2addr(env, address));
}
static void onSyncTransferedCb(int pa_source,uint8_t status, RawAddress address) {
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!mPeriodicScanCallbacksObj) {
    ALOGE("mPeriodicScanCallbacksObj is NULL. Return.");
    return;
  }
  ScopedLocalRef<jstring> addr(sCallbackEnv.get(),
                                 bdaddr2newjstr(sCallbackEnv.get(), &address));

  sCallbackEnv->CallVoidMethod(mPeriodicScanCallbacksObj, method_onSyncTransferedCallback, pa_source,
                              status, addr.get());

}

static void syncTransferNative(JNIEnv* env, jobject object, jint pa_source,
                                       jstring addr,jint service_data, jint sync_handle) {
  if (!sGattIf) return;
  sGattIf->scanner->TransferSync(str2addr(env,addr), service_data, sync_handle,
                                 base::Bind(&onSyncTransferedCb, pa_source));
}

static void TransferSetInfoNative(JNIEnv* env, jobject object, jint pa_source,
                                       jstring addr,jint service_data, jint adv_handle) {
  if (!sGattIf) return;
  sGattIf->scanner->TransferSetInfo(str2addr(env,addr), service_data, adv_handle,
                                 base::Bind(&onSyncTransferedCb, pa_source));
}

static void gattTestNative(JNIEnv* env, jobject object, jint command,
                           jlong uuid1_lsb, jlong uuid1_msb, jstring bda1,
                           jint p1, jint p2, jint p3, jint p4, jint p5) {
@@ -2336,6 +2372,11 @@ static JNINativeMethod sPeriodicScanMethods[] = {
    {"cleanupNative", "()V", (void*)periodicScanCleanupNative},
    {"startSyncNative", "(ILjava/lang/String;III)V", (void*)startSyncNative},
    {"stopSyncNative", "(I)V", (void*)stopSyncNative},
    {"cancelSyncNative", "(ILjava/lang/String;)V", (void*)cancelSyncNative},
    {"syncTransferNative", "(ILjava/lang/String;II)V",
      (void*)syncTransferNative},
    {"TransferSetInfoNative", "(ILjava/lang/String;II)V",
      (void*)TransferSetInfoNative},
};

// JNI functions defined in ScanManager class.
+33 −0
Original line number Diff line number Diff line
@@ -1037,6 +1037,25 @@ public class GattService extends ProfileService {
            service.registerSync(scanResult, skip, timeout, callback, attributionSource);
        }

        @Override
        public void transferSync(BluetoothDevice bda, int service_data , int sync_handle) {
            GattService service = getService();
            if (service == null) {
                return;
            }
            service.transferSync(bda, service_data , sync_handle);
        }

        @Override
        public void transferSetInfo(BluetoothDevice bda, int service_data , int adv_handle,
                IPeriodicAdvertisingCallback callback) {
            GattService service = getService();
            if (service == null) {
                return;
            }
            service.transferSetInfo(bda, service_data , adv_handle, callback);
        }

        @Override
        public void unregisterSync(
                IPeriodicAdvertisingCallback callback, AttributionSource attributionSource) {
@@ -2502,6 +2521,20 @@ public class GattService extends ProfileService {
        mPeriodicScanManager.stopSync(callback);
    }

    void transferSync(BluetoothDevice bda, int service_data, int sync_handle) {
        if (!Utils.checkScanPermissionForPreflight(this)) {
            return;
        }
        mPeriodicScanManager.transferSync(bda, service_data, sync_handle);
    }

    void transferSetInfo(BluetoothDevice bda, int service_data,
                  int adv_handle, IPeriodicAdvertisingCallback callback) {
        if (!Utils.checkScanPermissionForPreflight(this)) {
            return;
        }
        mPeriodicScanManager.transferSetInfo(bda, service_data, adv_handle, callback);
    }
    /**************************************************************************
     * ADVERTISING SET
     *************************************************************************/
+76 −2
Original line number Diff line number Diff line
@@ -46,8 +46,11 @@ class PeriodicScanManager {
    private final AdapterService mAdapterService;
    private final BluetoothAdapter mAdapter;
    Map<IBinder, SyncInfo> mSyncs = new ConcurrentHashMap<>();
    Map<IBinder, SyncTransferInfo> mSyncTransfers = Collections.synchronizedMap(new HashMap<>());

    static int sTempRegistrationId = -1;
    private int PA_SOURCE_LOCAL = 1;
    private int PA_SOURCE_REMOTE = 2;

    /**
     * Constructor of {@link SyncManager}.
@@ -98,6 +101,28 @@ class PeriodicScanManager {
        }
    }

    class SyncTransferInfo {
        public String address;
        public SyncDeathRecipient deathRecipient;
        public IPeriodicAdvertisingCallback callback;

        SyncTransferInfo(String address, IPeriodicAdvertisingCallback callback) {
            this.address = address;
            this.callback = callback;
        }
    }

    Map.Entry<IBinder, SyncTransferInfo> findSyncTransfer(String address) {
        Map.Entry<IBinder, SyncTransferInfo> entry = null;
        for (Map.Entry<IBinder, SyncTransferInfo> e : mSyncTransfers.entrySet()) {
            if (e.getValue().address.equals(address)) {
                entry = e;
                break;
            }
        }
        return entry;
    }

    IBinder toBinder(IPeriodicAdvertisingCallback e) {
        return ((IInterface) e).asBinder();
    }
@@ -300,10 +325,53 @@ class PeriodicScanManager {
        Log.d(TAG,"calling stopSyncNative: " + syncHandle.intValue());
        if (syncHandle < 0) {
            Log.i(TAG, "cancelSync() - sync not established yet");
            return;
        }
            // Sync will be freed once initiated in onSyncStarted()
            cancelSyncNative(sync.adv_sid, sync.address);
        } else {
            stopSyncNative(syncHandle.intValue());
        }
    }

    void onSyncTransferedCallback(int pa_source, int status, String bda) {
        Log.d(TAG, "onSyncTransferedCallback()");
        Map.Entry<IBinder, SyncTransferInfo>entry = findSyncTransfer(bda);
        if (entry != null) {
            mSyncTransfers.remove(entry);
            IPeriodicAdvertisingCallback callback = entry.getValue().callback;
            try {
                callback.onSyncTransfered(mAdapter.getRemoteDevice(bda), status);
            } catch (RemoteException e) {
                throw new IllegalArgumentException("Can't find callback for sync transfer");
            }
        }
    }
    void transferSync(BluetoothDevice bda, int service_data, int sync_handle) {
        Log.d(TAG, "transferSync()");
        Map.Entry<IBinder, SyncInfo> entry = findSync(sync_handle);
        if (entry == null) {
            Log.d(TAG,"transferSync: callback not registered");
        }
        //check for duplicate transfers
        mSyncTransfers.put(entry.getKey(), new SyncTransferInfo(bda.getAddress(),
                entry.getValue().callback));
        syncTransferNative(PA_SOURCE_REMOTE, bda.getAddress(), service_data, sync_handle);
    }

    void transferSetInfo(BluetoothDevice bda, int service_data,
                  int adv_handle, IPeriodicAdvertisingCallback callback) {
        SyncDeathRecipient deathRecipient = new SyncDeathRecipient(callback);
        IBinder binder = toBinder(callback);
        if (DBG) {
            Log.d(TAG, "transferSetInfo() " + binder);
        }
        try {
            binder.linkToDeath(deathRecipient, 0);
        } catch (RemoteException e) {
            throw new IllegalArgumentException("Can't link to periodic scanner death");
        }
        mSyncTransfers.put(binder, new SyncTransferInfo(bda.getAddress(), callback));
        TransferSetInfoNative(PA_SOURCE_LOCAL, bda.getAddress(), service_data, adv_handle);
    }

    static {
        classInitNative();
@@ -318,4 +386,10 @@ class PeriodicScanManager {
    private native void startSyncNative(int sid, String address, int skip, int timeout, int regId);

    private native void stopSyncNative(int syncHandle);

    private native void cancelSyncNative(int sid, String address);

    private native void syncTransferNative(int pa_source, String address, int service_data, int sync_handle);

    private native void TransferSetInfoNative(int pa_source, String address, int service_data, int adv_handle);
}