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

Commit ebe3489f authored by Chienyuan Huang's avatar Chienyuan Huang Committed by Gerrit Code Review
Browse files

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

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

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

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

    private static final int RSSI_FREQUENCY_LOW = 3000;
    private static final int RSSI_FREQUENCY_MEDIUM = 1000;
    private static final int RSSI_FREQUENCY_HIGH = 500;
    private static final int RSSI_LOW_FREQUENCY_INTERVAL_MS = 3000;
    private static final int RSSI_MEDIUM_FREQUENCY_INTERVAL_MS = 1000;
    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 HandlerThread mHandlerThread;
    DistanceMeasurementNativeInterface mDistanceMeasurementNativeInterface;
    private final ConcurrentHashMap<String, CopyOnWriteArraySet<DistanceMeasurementTracker>>
            mRssiTrackers = new ConcurrentHashMap<>();
    private final ConcurrentHashMap<String, CopyOnWriteArraySet<DistanceMeasurementTracker>>
            mCsTrackers = new ConcurrentHashMap<>();

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

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

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

        switch (params.getMethodId()) {
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_AUTO:
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI:
                startRssiTracker(tracker);
                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:
                invokeStartFail(callback, params.getDevice(),
                        BluetoothStatusCodes.ERROR_BAD_PARAMETERS);
@@ -116,8 +136,24 @@ public class DistanceMeasurementManager {
            Log.w(TAG, "Already registered");
            return;
        }
        mDistanceMeasurementNativeInterface.startDistanceMeasurement(tracker.mIdentityAddress,
                tracker.mFrequency, DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI);
        mDistanceMeasurementNativeInterface.startDistanceMeasurement(
                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,
@@ -125,6 +161,9 @@ public class DistanceMeasurementManager {
        Log.i(TAG, "stopDistanceMeasurement device:" + device.getAnonymizedAddress()
                + ", method: " + method + " timeout " + timeout);
        String identityAddress = mAdapterService.getIdentityAddress(device.getAddress());
        if (identityAddress == null) {
            identityAddress = device.getAddress();
        }
        logd("Get identityAddress: " + device.getAnonymizedAddress() + " => "
                + BluetoothUtils.toAnonymizedAddress(identityAddress));

@@ -132,6 +171,8 @@ public class DistanceMeasurementManager {
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_AUTO:
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI:
                return stopRssiTracker(uuid, identityAddress, timeout);
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING:
                return stopCsTracker(uuid, identityAddress, timeout);
            default:
                Log.w(TAG, "stopDistanceMeasurement with invalid method:" + method);
                return BluetoothStatusCodes.ERROR_DISTANCE_MEASUREMENT_INTERNAL;
@@ -174,6 +215,36 @@ public class DistanceMeasurementManager {
        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,
            int reason) {
        try {
@@ -192,26 +263,33 @@ public class DistanceMeasurementManager {
        }
    }

    /**
     * Convert frequency into value in ms
     */
    private int getFrequencyValue(int frequency, int method) {
    /** Convert frequency into interval in ms */
    private int getIntervalValue(int frequency, int method) {
        switch (method) {
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_AUTO:
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI:
                switch (frequency) {
                    case DistanceMeasurementParams.REPORT_FREQUENCY_LOW:
                        return RSSI_FREQUENCY_LOW;
                        return RSSI_LOW_FREQUENCY_INTERVAL_MS;
                    case DistanceMeasurementParams.REPORT_FREQUENCY_MEDIUM:
                        return RSSI_FREQUENCY_MEDIUM;
                        return RSSI_MEDIUM_FREQUENCY_INTERVAL_MS;
                    case DistanceMeasurementParams.REPORT_FREQUENCY_HIGH:
                        return RSSI_FREQUENCY_HIGH;
                        return RSSI_HIGH_FREQUENCY_INTERVAL_MS;
                }
                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);
        }
        return -1;
    }

@@ -222,6 +300,9 @@ public class DistanceMeasurementManager {
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI:
                handleRssiStarted(address);
                break;
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING:
                handleCsStarted(address);
                break;
            default:
                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) {
        logd("onDistanceMeasurementStartFail address:" + BluetoothUtils.toAnonymizedAddress(address)
                + ", method:" + method);
@@ -253,6 +353,9 @@ public class DistanceMeasurementManager {
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI:
                handleRssiStartFail(address, reason);
                break;
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING:
                handleCsStartFail(address, reason);
                break;
            default:
                Log.w(TAG, "onDistanceMeasurementStartFail: invalid method " + method);
        }
@@ -272,6 +375,20 @@ public class DistanceMeasurementManager {
        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) {
        logd("onDistanceMeasurementStopped address:" + BluetoothUtils.toAnonymizedAddress(address)
                + ", reason:" + reason + ", method:" + method);
@@ -279,6 +396,9 @@ public class DistanceMeasurementManager {
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI:
                handleRssiStopped(address, reason);
                break;
            case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING:
                handleCsStopped(address, reason);
                break;
            default:
                Log.w(TAG, "onDistanceMeasurementStopped: invalid method " + method);
        }
@@ -299,6 +419,21 @@ public class DistanceMeasurementManager {
        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,
            int azimuthAngle, int errorAzimuthAngle, int altitudeAngle, int errorAltitudeAngle,
            int method) {
+3 −3
Original line number Diff line number Diff line
@@ -82,8 +82,8 @@ public class DistanceMeasurementNativeInterface {
        cleanupNative();
    }

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

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

    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);
}
+8 −4
Original line number Diff line number Diff line
@@ -37,21 +37,25 @@ class DistanceMeasurementTracker {
    final BluetoothDevice mDevice;
    final String mIdentityAddress;
    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 mMethod;
    final IDistanceMeasurementCallback mCallback;
    boolean mStarted = false;
    private Handler mHandler;

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

File changed.

Preview size limit exceeded, changes collapsed.

Loading