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

Commit 766c3e3e authored by Chienyuan Huang's avatar Chienyuan Huang Committed by Automerger Merge Worker
Browse files

Merge "CS: Handle start/stop request" into main am: ebe3489f

parents 5b55f2fc ebe3489f
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -2531,11 +2531,11 @@ static void distanceMeasurementCleanupNative(JNIEnv* env,
}
}


static void startDistanceMeasurementNative(JNIEnv* env, jobject /* object */,
static void startDistanceMeasurementNative(JNIEnv* env, jobject /* object */,
                                           jstring address, jint frequency,
                                           jstring address, jint interval,
                                           jint method) {
                                           jint method) {
  if (!sGattIf) return;
  if (!sGattIf) return;
  sGattIf->distance_measurement_manager->StartDistanceMeasurement(
  sGattIf->distance_measurement_manager->StartDistanceMeasurement(
      str2addr(env, address), frequency, method);
      str2addr(env, address), interval, method);
}
}


static void stopDistanceMeasurementNative(JNIEnv* env, jobject /* object */,
static void stopDistanceMeasurementNative(JNIEnv* env, jobject /* object */,
+153 −18
Original line number Original line Diff line number Diff line
@@ -45,15 +45,20 @@ public class DistanceMeasurementManager {
    private static final boolean DBG = GattServiceConfig.DBG;
    private static final boolean DBG = GattServiceConfig.DBG;
    private static final String TAG = "DistanceMeasurementManager";
    private static final String TAG = "DistanceMeasurementManager";


    private static final int RSSI_FREQUENCY_LOW = 3000;
    private static final int RSSI_LOW_FREQUENCY_INTERVAL_MS = 3000;
    private static final int RSSI_FREQUENCY_MEDIUM = 1000;
    private static final int RSSI_MEDIUM_FREQUENCY_INTERVAL_MS = 1000;
    private static final int RSSI_FREQUENCY_HIGH = 500;
    private static final int RSSI_HIGH_FREQUENCY_INTERVAL_MS = 500;
    private static final int CS_LOW_FREQUENCY_INTERVAL_MS = 5000;
    private static final int CS_MEDIUM_FREQUENCY_INTERVAL_MS = 3000;
    private static final int CS_HIGH_FREQUENCY_INTERVAL_MS = 1000;


    private final AdapterService mAdapterService;
    private final AdapterService mAdapterService;
    private HandlerThread mHandlerThread;
    private HandlerThread mHandlerThread;
    DistanceMeasurementNativeInterface mDistanceMeasurementNativeInterface;
    DistanceMeasurementNativeInterface mDistanceMeasurementNativeInterface;
    private final ConcurrentHashMap<String, CopyOnWriteArraySet<DistanceMeasurementTracker>>
    private final ConcurrentHashMap<String, CopyOnWriteArraySet<DistanceMeasurementTracker>>
            mRssiTrackers = new ConcurrentHashMap<>();
            mRssiTrackers = new ConcurrentHashMap<>();
    private final ConcurrentHashMap<String, CopyOnWriteArraySet<DistanceMeasurementTracker>>
            mCsTrackers = new ConcurrentHashMap<>();


    /** Constructor of {@link DistanceMeasurementManager}. */
    /** Constructor of {@link DistanceMeasurementManager}. */
    DistanceMeasurementManager(AdapterService adapterService) {
    DistanceMeasurementManager(AdapterService adapterService) {
@@ -84,24 +89,39 @@ public class DistanceMeasurementManager {
                + ", method: " + params.getMethodId());
                + ", method: " + params.getMethodId());
        String identityAddress = mAdapterService.getIdentityAddress(
        String identityAddress = mAdapterService.getIdentityAddress(
                params.getDevice().getAddress());
                params.getDevice().getAddress());
        if (identityAddress == null) {
            identityAddress = params.getDevice().getAddress();
        }
        logd("Get identityAddress: " + params.getDevice().getAnonymizedAddress() + " => "
        logd("Get identityAddress: " + params.getDevice().getAnonymizedAddress() + " => "
                + BluetoothUtils.toAnonymizedAddress(identityAddress));
                + BluetoothUtils.toAnonymizedAddress(identityAddress));


        int frequencyValue = getFrequencyValue(params.getFrequency(), params.getMethodId());
        int interval = getIntervalValue(params.getFrequency(), params.getMethodId());
        if (frequencyValue == -1) {
        if (interval == -1) {
            invokeStartFail(callback, params.getDevice(),
            invokeStartFail(callback, params.getDevice(),
                    BluetoothStatusCodes.ERROR_BAD_PARAMETERS);
                    BluetoothStatusCodes.ERROR_BAD_PARAMETERS);
            return;
            return;
        }
        }


        DistanceMeasurementTracker tracker = new DistanceMeasurementTracker(
        DistanceMeasurementTracker tracker =
                this, params, identityAddress, uuid, frequencyValue, callback);
                new DistanceMeasurementTracker(
                        this, params, identityAddress, uuid, interval, callback);


        switch (params.getMethodId()) {
        switch (params.getMethodId()) {
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_AUTO:
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_AUTO:
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI:
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI:
                startRssiTracker(tracker);
                startRssiTracker(tracker);
                break;
                break;
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING:
                if (!params.getDevice().isConnected()) {
                    Log.e(TAG, "no le connection");
                    invokeStartFail(
                            callback,
                            params.getDevice(),
                            BluetoothStatusCodes.ERROR_NO_LE_CONNECTION);
                    return;
                }
                startCsTracker(tracker);
                break;
            default:
            default:
                invokeStartFail(callback, params.getDevice(),
                invokeStartFail(callback, params.getDevice(),
                        BluetoothStatusCodes.ERROR_BAD_PARAMETERS);
                        BluetoothStatusCodes.ERROR_BAD_PARAMETERS);
@@ -116,8 +136,24 @@ public class DistanceMeasurementManager {
            Log.w(TAG, "Already registered");
            Log.w(TAG, "Already registered");
            return;
            return;
        }
        }
        mDistanceMeasurementNativeInterface.startDistanceMeasurement(tracker.mIdentityAddress,
        mDistanceMeasurementNativeInterface.startDistanceMeasurement(
                tracker.mFrequency, DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI);
                tracker.mIdentityAddress,
                tracker.mInterval,
                DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI);
    }

    private synchronized void startCsTracker(DistanceMeasurementTracker tracker) {
        mCsTrackers.putIfAbsent(tracker.mIdentityAddress, new CopyOnWriteArraySet<>());
        CopyOnWriteArraySet<DistanceMeasurementTracker> set =
                mCsTrackers.get(tracker.mIdentityAddress);
        if (!set.add(tracker)) {
            Log.w(TAG, "Already registered");
            return;
        }
        mDistanceMeasurementNativeInterface.startDistanceMeasurement(
                tracker.mIdentityAddress,
                tracker.mInterval,
                DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING);
    }
    }


    int stopDistanceMeasurement(UUID uuid, BluetoothDevice device, int method,
    int stopDistanceMeasurement(UUID uuid, BluetoothDevice device, int method,
@@ -125,6 +161,9 @@ public class DistanceMeasurementManager {
        Log.i(TAG, "stopDistanceMeasurement device:" + device.getAnonymizedAddress()
        Log.i(TAG, "stopDistanceMeasurement device:" + device.getAnonymizedAddress()
                + ", method: " + method + " timeout " + timeout);
                + ", method: " + method + " timeout " + timeout);
        String identityAddress = mAdapterService.getIdentityAddress(device.getAddress());
        String identityAddress = mAdapterService.getIdentityAddress(device.getAddress());
        if (identityAddress == null) {
            identityAddress = device.getAddress();
        }
        logd("Get identityAddress: " + device.getAnonymizedAddress() + " => "
        logd("Get identityAddress: " + device.getAnonymizedAddress() + " => "
                + BluetoothUtils.toAnonymizedAddress(identityAddress));
                + BluetoothUtils.toAnonymizedAddress(identityAddress));


@@ -132,6 +171,8 @@ public class DistanceMeasurementManager {
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_AUTO:
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_AUTO:
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI:
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI:
                return stopRssiTracker(uuid, identityAddress, timeout);
                return stopRssiTracker(uuid, identityAddress, timeout);
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING:
                return stopCsTracker(uuid, identityAddress, timeout);
            default:
            default:
                Log.w(TAG, "stopDistanceMeasurement with invalid method:" + method);
                Log.w(TAG, "stopDistanceMeasurement with invalid method:" + method);
                return BluetoothStatusCodes.ERROR_DISTANCE_MEASUREMENT_INTERNAL;
                return BluetoothStatusCodes.ERROR_DISTANCE_MEASUREMENT_INTERNAL;
@@ -174,6 +215,36 @@ public class DistanceMeasurementManager {
        return BluetoothStatusCodes.SUCCESS;
        return BluetoothStatusCodes.SUCCESS;
    }
    }


    private synchronized int stopCsTracker(UUID uuid, String identityAddress, boolean timeout) {
        CopyOnWriteArraySet<DistanceMeasurementTracker> set = mCsTrackers.get(identityAddress);
        if (set == null) {
            Log.w(TAG, "Can't find CS tracker");
            return BluetoothStatusCodes.ERROR_DISTANCE_MEASUREMENT_INTERNAL;
        }

        for (DistanceMeasurementTracker tracker : set) {
            if (tracker.equals(uuid, identityAddress)) {
                int reason =
                        timeout
                                ? BluetoothStatusCodes.ERROR_TIMEOUT
                                : BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST;
                invokeOnStopped(tracker.mCallback, tracker.mDevice, reason);
                tracker.cancelTimer();
                set.remove(tracker);
                break;
            }
        }

        if (set.isEmpty()) {
            logd("No CS tracker exists; stop CS");
            mCsTrackers.remove(identityAddress);
            mDistanceMeasurementNativeInterface.stopDistanceMeasurement(
                    identityAddress,
                    DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING);
        }
        return BluetoothStatusCodes.SUCCESS;
    }

    private void invokeStartFail(IDistanceMeasurementCallback callback, BluetoothDevice device,
    private void invokeStartFail(IDistanceMeasurementCallback callback, BluetoothDevice device,
            int reason) {
            int reason) {
        try {
        try {
@@ -192,26 +263,33 @@ public class DistanceMeasurementManager {
        }
        }
    }
    }


    /**
    /** Convert frequency into interval in ms */
     * Convert frequency into value in ms
    private int getIntervalValue(int frequency, int method) {
     */
    private int getFrequencyValue(int frequency, int method) {
        switch (method) {
        switch (method) {
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_AUTO:
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_AUTO:
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI:
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI:
                switch (frequency) {
                switch (frequency) {
                    case DistanceMeasurementParams.REPORT_FREQUENCY_LOW:
                    case DistanceMeasurementParams.REPORT_FREQUENCY_LOW:
                        return RSSI_FREQUENCY_LOW;
                        return RSSI_LOW_FREQUENCY_INTERVAL_MS;
                    case DistanceMeasurementParams.REPORT_FREQUENCY_MEDIUM:
                    case DistanceMeasurementParams.REPORT_FREQUENCY_MEDIUM:
                        return RSSI_FREQUENCY_MEDIUM;
                        return RSSI_MEDIUM_FREQUENCY_INTERVAL_MS;
                    case DistanceMeasurementParams.REPORT_FREQUENCY_HIGH:
                    case DistanceMeasurementParams.REPORT_FREQUENCY_HIGH:
                        return RSSI_FREQUENCY_HIGH;
                        return RSSI_HIGH_FREQUENCY_INTERVAL_MS;
                }
                }
                break;
                break;
            default:
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING:

                switch (frequency) {
                    case DistanceMeasurementParams.REPORT_FREQUENCY_LOW:
                        return CS_LOW_FREQUENCY_INTERVAL_MS;
                    case DistanceMeasurementParams.REPORT_FREQUENCY_MEDIUM:
                        return CS_MEDIUM_FREQUENCY_INTERVAL_MS;
                    case DistanceMeasurementParams.REPORT_FREQUENCY_HIGH:
                        return CS_HIGH_FREQUENCY_INTERVAL_MS;
                }
                }
                break;
            default:
                Log.w(TAG, "getFrequencyValue fail frequency:" + frequency + ", method:" + method);
                Log.w(TAG, "getFrequencyValue fail frequency:" + frequency + ", method:" + method);
        }
        return -1;
        return -1;
    }
    }


@@ -222,6 +300,9 @@ public class DistanceMeasurementManager {
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI:
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI:
                handleRssiStarted(address);
                handleRssiStarted(address);
                break;
                break;
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING:
                handleCsStarted(address);
                break;
            default:
            default:
                Log.w(TAG, "onDistanceMeasurementResult: invalid method " + method);
                Log.w(TAG, "onDistanceMeasurementResult: invalid method " + method);
        }
        }
@@ -246,6 +327,25 @@ public class DistanceMeasurementManager {
        }
        }
    }
    }


    void handleCsStarted(String address) {
        CopyOnWriteArraySet<DistanceMeasurementTracker> set = mCsTrackers.get(address);
        if (set == null) {
            Log.w(TAG, "Can't find CS tracker");
            return;
        }
        for (DistanceMeasurementTracker tracker : set) {
            try {
                if (!tracker.mStarted) {
                    tracker.mStarted = true;
                    tracker.mCallback.onStarted(tracker.mDevice);
                    tracker.startTimer(mHandlerThread.getLooper());
                }
            } catch (RemoteException e) {
                Log.e(TAG, "Exception: " + e);
            }
        }
    }

    void onDistanceMeasurementStartFail(String address, int reason, int method) {
    void onDistanceMeasurementStartFail(String address, int reason, int method) {
        logd("onDistanceMeasurementStartFail address:" + BluetoothUtils.toAnonymizedAddress(address)
        logd("onDistanceMeasurementStartFail address:" + BluetoothUtils.toAnonymizedAddress(address)
                + ", method:" + method);
                + ", method:" + method);
@@ -253,6 +353,9 @@ public class DistanceMeasurementManager {
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI:
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI:
                handleRssiStartFail(address, reason);
                handleRssiStartFail(address, reason);
                break;
                break;
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING:
                handleCsStartFail(address, reason);
                break;
            default:
            default:
                Log.w(TAG, "onDistanceMeasurementStartFail: invalid method " + method);
                Log.w(TAG, "onDistanceMeasurementStartFail: invalid method " + method);
        }
        }
@@ -272,6 +375,20 @@ public class DistanceMeasurementManager {
        set.removeIf(tracker -> !tracker.mStarted);
        set.removeIf(tracker -> !tracker.mStarted);
    }
    }


    void handleCsStartFail(String address, int reason) {
        CopyOnWriteArraySet<DistanceMeasurementTracker> set = mCsTrackers.get(address);
        if (set == null) {
            Log.w(TAG, "Can't find CS tracker");
            return;
        }
        for (DistanceMeasurementTracker tracker : set) {
            if (!tracker.mStarted) {
                invokeStartFail(tracker.mCallback, tracker.mDevice, reason);
            }
        }
        set.removeIf(tracker -> !tracker.mStarted);
    }

    void onDistanceMeasurementStopped(String address, int reason, int method) {
    void onDistanceMeasurementStopped(String address, int reason, int method) {
        logd("onDistanceMeasurementStopped address:" + BluetoothUtils.toAnonymizedAddress(address)
        logd("onDistanceMeasurementStopped address:" + BluetoothUtils.toAnonymizedAddress(address)
                + ", reason:" + reason + ", method:" + method);
                + ", reason:" + reason + ", method:" + method);
@@ -279,6 +396,9 @@ public class DistanceMeasurementManager {
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI:
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI:
                handleRssiStopped(address, reason);
                handleRssiStopped(address, reason);
                break;
                break;
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING:
                handleCsStopped(address, reason);
                break;
            default:
            default:
                Log.w(TAG, "onDistanceMeasurementStopped: invalid method " + method);
                Log.w(TAG, "onDistanceMeasurementStopped: invalid method " + method);
        }
        }
@@ -299,6 +419,21 @@ public class DistanceMeasurementManager {
        set.removeIf(tracker -> tracker.mStarted);
        set.removeIf(tracker -> tracker.mStarted);
    }
    }


    void handleCsStopped(String address, int reason) {
        CopyOnWriteArraySet<DistanceMeasurementTracker> set = mCsTrackers.get(address);
        if (set == null) {
            Log.w(TAG, "Can't find CS tracker");
            return;
        }
        for (DistanceMeasurementTracker tracker : set) {
            if (tracker.mStarted) {
                tracker.cancelTimer();
                invokeOnStopped(tracker.mCallback, tracker.mDevice, reason);
            }
        }
        set.removeIf(tracker -> tracker.mStarted);
    }

    void onDistanceMeasurementResult(String address, int centimeter, int errorCentimeter,
    void onDistanceMeasurementResult(String address, int centimeter, int errorCentimeter,
            int azimuthAngle, int errorAzimuthAngle, int altitudeAngle, int errorAltitudeAngle,
            int azimuthAngle, int errorAzimuthAngle, int altitudeAngle, int errorAltitudeAngle,
            int method) {
            int method) {
+3 −3
Original line number Original line Diff line number Diff line
@@ -82,8 +82,8 @@ public class DistanceMeasurementNativeInterface {
        cleanupNative();
        cleanupNative();
    }
    }


    void startDistanceMeasurement(String address, int frequency, int method) {
    void startDistanceMeasurement(String address, int interval, int method) {
        startDistanceMeasurementNative(address, frequency, method);
        startDistanceMeasurementNative(address, interval, method);
    }
    }


    void stopDistanceMeasurement(String address, int method) {
    void stopDistanceMeasurement(String address, int method) {
@@ -143,7 +143,7 @@ public class DistanceMeasurementNativeInterface {


    private native void cleanupNative();
    private native void cleanupNative();


    private native void startDistanceMeasurementNative(String address, int frequency, int method);
    private native void startDistanceMeasurementNative(String address, int interval, int method);


    private native void stopDistanceMeasurementNative(String address, int method);
    private native void stopDistanceMeasurementNative(String address, int method);
}
}
+8 −4
Original line number Original line Diff line number Diff line
@@ -37,21 +37,25 @@ class DistanceMeasurementTracker {
    final BluetoothDevice mDevice;
    final BluetoothDevice mDevice;
    final String mIdentityAddress;
    final String mIdentityAddress;
    final UUID mUuid;
    final UUID mUuid;
    final int mFrequency; // Report frequency in ms
    final int mInterval; // Report interval in ms
    final int mDuration; // Report duration in s
    final int mDuration; // Report duration in s
    final int mMethod;
    final int mMethod;
    final IDistanceMeasurementCallback mCallback;
    final IDistanceMeasurementCallback mCallback;
    boolean mStarted = false;
    boolean mStarted = false;
    private Handler mHandler;
    private Handler mHandler;


    DistanceMeasurementTracker(DistanceMeasurementManager manager, DistanceMeasurementParams params,
    DistanceMeasurementTracker(
            String identityAddress, UUID uuid, int frequency,
            DistanceMeasurementManager manager,
            DistanceMeasurementParams params,
            String identityAddress,
            UUID uuid,
            int interval,
            IDistanceMeasurementCallback callback) {
            IDistanceMeasurementCallback callback) {
        mManager = manager;
        mManager = manager;
        mDevice = params.getDevice();
        mDevice = params.getDevice();
        mIdentityAddress = identityAddress;
        mIdentityAddress = identityAddress;
        mUuid = uuid;
        mUuid = uuid;
        mFrequency = frequency;
        mInterval = interval;
        mDuration = params.getDurationSeconds();
        mDuration = params.getDurationSeconds();
        mMethod = params.getMethodId();
        mMethod = params.getMethodId();
        mCallback = callback;
        mCallback = callback;
+84 −32

File changed.

Preview size limit exceeded, changes collapsed.

Loading