1 /* 2 * Copyright 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.bluetooth.gatt; 18 19 import android.bluetooth.BluetoothStatusCodes; 20 21 import com.android.internal.annotations.VisibleForTesting; 22 23 /** 24 * Distance Measurement Native Interface to/from JNI. 25 * 26 * @hide 27 */ 28 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 29 public class DistanceMeasurementNativeInterface { 30 private static DistanceMeasurementNativeInterface sInterface; 31 private static final Object INSTANCE_LOCK = new Object(); 32 private DistanceMeasurementManager mDistanceMeasurementManager; 33 34 /** 35 * Do not modify without updating distance_measurement_manager.h 36 * match up with DistanceMeasurementErrorCode enum of distance_measurement_manager.h 37 */ 38 private static final int REASON_FEATURE_NOT_SUPPORTED_LOCAL = 0; 39 private static final int REASON_FEATURE_NOT_SUPPORTED_REMOTE = 1; 40 private static final int REASON_LOCAL_REQUEST = 2; 41 private static final int REASON_REMOTE_REQUEST = 3; 42 private static final int REASON_DURATION_TIMEOUT = 4; 43 private static final int REASON_NO_LE_CONNECTION = 5; 44 private static final int REASON_INVALID_PARAMETERS = 6; 45 private static final int REASON_INTERNAL_ERROR = 7; 46 47 DistanceMeasurementNativeInterface()48 private DistanceMeasurementNativeInterface() {} 49 50 /** 51 * This class is a singleton because native library should only be loaded once 52 * 53 * @return default instance 54 */ getInstance()55 public static DistanceMeasurementNativeInterface getInstance() { 56 synchronized (INSTANCE_LOCK) { 57 if (sInterface == null) { 58 sInterface = new DistanceMeasurementNativeInterface(); 59 } 60 } 61 return sInterface; 62 } 63 init(DistanceMeasurementManager manager)64 void init(DistanceMeasurementManager manager) { 65 mDistanceMeasurementManager = manager; 66 initializeNative(); 67 } 68 cleanup()69 void cleanup() { 70 cleanupNative(); 71 } 72 startDistanceMeasurement(String address, int frequency, int method)73 void startDistanceMeasurement(String address, int frequency, int method) { 74 startDistanceMeasurementNative(address, frequency, method); 75 } 76 stopDistanceMeasurement(String address, int method)77 void stopDistanceMeasurement(String address, int method) { 78 stopDistanceMeasurementNative(address, method); 79 } 80 onDistanceMeasurementStarted(String address, int method)81 void onDistanceMeasurementStarted(String address, int method) { 82 mDistanceMeasurementManager.onDistanceMeasurementStarted(address, method); 83 } 84 onDistanceMeasurementStartFail(String address, int reason, int method)85 void onDistanceMeasurementStartFail(String address, int reason, int method) { 86 mDistanceMeasurementManager.onDistanceMeasurementStartFail(address, 87 convertErrorCode(reason), method); 88 } 89 onDistanceMeasurementStopped(String address, int reason, int method)90 void onDistanceMeasurementStopped(String address, int reason, int method) { 91 mDistanceMeasurementManager.onDistanceMeasurementStopped(address, 92 convertErrorCode(reason), method); 93 } 94 onDistanceMeasurementResult(String address, int centimeter, int errorCentimeter, int azimuthAngle, int errorAzimuthAngle, int altitudeAngle, int errorAltitudeAngle, int method)95 void onDistanceMeasurementResult(String address, int centimeter, int errorCentimeter, 96 int azimuthAngle, int errorAzimuthAngle, int altitudeAngle, int errorAltitudeAngle, 97 int method) { 98 mDistanceMeasurementManager.onDistanceMeasurementResult(address, centimeter, 99 errorCentimeter, azimuthAngle, errorAzimuthAngle, altitudeAngle, errorAltitudeAngle, 100 method); 101 } 102 convertErrorCode(int errorCode)103 private int convertErrorCode(int errorCode) { 104 switch (errorCode) { 105 case REASON_FEATURE_NOT_SUPPORTED_LOCAL: 106 return BluetoothStatusCodes.FEATURE_NOT_SUPPORTED; 107 case REASON_FEATURE_NOT_SUPPORTED_REMOTE: 108 return BluetoothStatusCodes.ERROR_REMOTE_OPERATION_NOT_SUPPORTED; 109 case REASON_LOCAL_REQUEST: 110 return BluetoothStatusCodes.REASON_LOCAL_STACK_REQUEST; 111 case REASON_REMOTE_REQUEST: 112 return BluetoothStatusCodes.REASON_REMOTE_REQUEST; 113 case REASON_DURATION_TIMEOUT: 114 return BluetoothStatusCodes.ERROR_TIMEOUT; 115 case REASON_NO_LE_CONNECTION: 116 return BluetoothStatusCodes.ERROR_NO_LE_CONNECTION; 117 case REASON_INVALID_PARAMETERS: 118 return BluetoothStatusCodes.ERROR_BAD_PARAMETERS; 119 case REASON_INTERNAL_ERROR: 120 return BluetoothStatusCodes.ERROR_DISTANCE_MEASUREMENT_INTERNAL; 121 default: 122 return BluetoothStatusCodes.ERROR_UNKNOWN; 123 } 124 } 125 126 static { classInitNative()127 classInitNative(); 128 } 129 classInitNative()130 private static native void classInitNative(); 131 initializeNative()132 private native void initializeNative(); 133 cleanupNative()134 private native void cleanupNative(); 135 startDistanceMeasurementNative(String address, int frequency, int method)136 private native void startDistanceMeasurementNative(String address, int frequency, int method); 137 stopDistanceMeasurementNative(String address, int method)138 private native void stopDistanceMeasurementNative(String address, int method); 139 } 140