Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2014 The Android Open Source Project |
| 3 | * Copyright (C) 2012 The Android Open Source Project |
| 4 | * |
| 5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | * you may not use this file except in compliance with the License. |
| 7 | * You may obtain a copy of the License at |
| 8 | * |
| 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | * |
| 11 | * Unless required by applicable law or agreed to in writing, software |
| 12 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | * See the License for the specific language governing permissions and |
| 15 | * limitations under the License. |
| 16 | */ |
| 17 | |
Mike Lockwood | 8d536f3 | 2014-06-12 12:07:01 -0700 | [diff] [blame] | 18 | #define LOG_TAG "BluetoothHeadsetClientServiceJni" |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 19 | #define LOG_NDEBUG 0 |
| 20 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 21 | #include "android_runtime/AndroidRuntime.h" |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 22 | #include "com_android_bluetooth.h" |
| 23 | #include "hardware/bt_hf_client.h" |
| 24 | #include "utils/Log.h" |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 25 | |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 26 | namespace android { |
| 27 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 28 | static bthf_client_interface_t* sBluetoothHfpClientInterface = NULL; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 29 | static jobject mCallbacksObj = NULL; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 30 | |
| 31 | static jmethodID method_onConnectionStateChanged; |
| 32 | static jmethodID method_onAudioStateChanged; |
| 33 | static jmethodID method_onVrStateChanged; |
| 34 | static jmethodID method_onNetworkState; |
| 35 | static jmethodID method_onNetworkRoaming; |
| 36 | static jmethodID method_onNetworkSignal; |
| 37 | static jmethodID method_onBatteryLevel; |
| 38 | static jmethodID method_onCurrentOperator; |
| 39 | static jmethodID method_onCall; |
| 40 | static jmethodID method_onCallSetup; |
| 41 | static jmethodID method_onCallHeld; |
| 42 | static jmethodID method_onRespAndHold; |
| 43 | static jmethodID method_onClip; |
| 44 | static jmethodID method_onCallWaiting; |
| 45 | static jmethodID method_onCurrentCalls; |
| 46 | static jmethodID method_onVolumeChange; |
| 47 | static jmethodID method_onCmdResult; |
| 48 | static jmethodID method_onSubscriberInfo; |
| 49 | static jmethodID method_onInBandRing; |
| 50 | static jmethodID method_onLastVoiceTagNumber; |
| 51 | static jmethodID method_onRingIndication; |
| 52 | |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 53 | static jbyteArray marshall_bda(const RawAddress* bd_addr) { |
Andre Eisenbach | 2116dbf | 2017-03-17 04:47:41 +0000 | [diff] [blame] | 54 | CallbackEnv sCallbackEnv(__func__); |
| 55 | if (!sCallbackEnv.valid()) return NULL; |
| 56 | |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 57 | jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(RawAddress)); |
Andre Eisenbach | 2116dbf | 2017-03-17 04:47:41 +0000 | [diff] [blame] | 58 | if (!addr) { |
| 59 | ALOGE("Fail to new jbyteArray bd addr"); |
| 60 | return NULL; |
| 61 | } |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 62 | sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(RawAddress), |
Andre Eisenbach | 2116dbf | 2017-03-17 04:47:41 +0000 | [diff] [blame] | 63 | (jbyte*)bd_addr); |
| 64 | return addr; |
| 65 | } |
| 66 | |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 67 | static void connection_state_cb(const RawAddress* bd_addr, |
Sanket Agarwal | ef3a3b5 | 2016-11-28 15:53:06 -0800 | [diff] [blame] | 68 | bthf_client_connection_state_t state, |
| 69 | unsigned int peer_feat, |
| 70 | unsigned int chld_feat) { |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 71 | CallbackEnv sCallbackEnv(__func__); |
| 72 | if (!sCallbackEnv.valid()) return; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 73 | |
Andre Eisenbach | 2116dbf | 2017-03-17 04:47:41 +0000 | [diff] [blame] | 74 | ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 75 | if (!addr.get()) return; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 76 | |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 77 | ALOGD("%s: state %d peer_feat %d chld_feat %d", __func__, state, peer_feat, chld_feat); |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 78 | sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectionStateChanged, |
| 79 | (jint)state, (jint)peer_feat, (jint)chld_feat, |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 80 | addr.get()); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 81 | } |
| 82 | |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 83 | static void audio_state_cb(const RawAddress* bd_addr, |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 84 | bthf_client_audio_state_t state) { |
| 85 | CallbackEnv sCallbackEnv(__func__); |
| 86 | if (!sCallbackEnv.valid()) return; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 87 | |
Andre Eisenbach | 2116dbf | 2017-03-17 04:47:41 +0000 | [diff] [blame] | 88 | ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 89 | if (!addr.get()) return; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 90 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 91 | sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAudioStateChanged, |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 92 | (jint)state, addr.get()); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 93 | } |
| 94 | |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 95 | static void vr_cmd_cb(const RawAddress* bd_addr, bthf_client_vr_state_t state) { |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 96 | CallbackEnv sCallbackEnv(__func__); |
| 97 | if (!sCallbackEnv.valid()) return; |
Joseph Pirozzo | a4cca00 | 2017-10-06 14:04:22 -0700 | [diff] [blame^] | 98 | |
| 99 | ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); |
| 100 | if (!addr.get()) return; |
| 101 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 102 | sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVrStateChanged, |
Joseph Pirozzo | a4cca00 | 2017-10-06 14:04:22 -0700 | [diff] [blame^] | 103 | (jint)state, addr.get()); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 104 | } |
| 105 | |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 106 | static void network_state_cb(const RawAddress* bd_addr, |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 107 | bthf_client_network_state_t state) { |
| 108 | CallbackEnv sCallbackEnv(__func__); |
| 109 | if (!sCallbackEnv.valid()) return; |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 110 | |
Andre Eisenbach | 2116dbf | 2017-03-17 04:47:41 +0000 | [diff] [blame] | 111 | ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 112 | if (!addr.get()) return; |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 113 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 114 | sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNetworkState, |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 115 | (jint)state, addr.get()); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 116 | } |
| 117 | |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 118 | static void network_roaming_cb(const RawAddress* bd_addr, |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 119 | bthf_client_service_type_t type) { |
| 120 | CallbackEnv sCallbackEnv(__func__); |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 121 | |
Andre Eisenbach | 2116dbf | 2017-03-17 04:47:41 +0000 | [diff] [blame] | 122 | ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 123 | if (!addr.get()) return; |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 124 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 125 | sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNetworkRoaming, |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 126 | (jint)type, addr.get()); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 127 | } |
| 128 | |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 129 | static void network_signal_cb(const RawAddress* bd_addr, int signal) { |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 130 | CallbackEnv sCallbackEnv(__func__); |
| 131 | if (!sCallbackEnv.valid()) return; |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 132 | |
Andre Eisenbach | 2116dbf | 2017-03-17 04:47:41 +0000 | [diff] [blame] | 133 | ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 134 | if (!addr.get()) return; |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 135 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 136 | sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNetworkSignal, |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 137 | (jint)signal, addr.get()); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 138 | } |
| 139 | |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 140 | static void battery_level_cb(const RawAddress* bd_addr, int level) { |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 141 | CallbackEnv sCallbackEnv(__func__); |
| 142 | if (!sCallbackEnv.valid()) return; |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 143 | |
Andre Eisenbach | 2116dbf | 2017-03-17 04:47:41 +0000 | [diff] [blame] | 144 | ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 145 | if (!addr.get()) return; |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 146 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 147 | sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatteryLevel, |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 148 | (jint)level, addr.get()); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 149 | } |
| 150 | |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 151 | static void current_operator_cb(const RawAddress* bd_addr, const char* name) { |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 152 | CallbackEnv sCallbackEnv(__func__); |
| 153 | if (!sCallbackEnv.valid()) return; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 154 | |
Andre Eisenbach | 2116dbf | 2017-03-17 04:47:41 +0000 | [diff] [blame] | 155 | ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 156 | if (!addr.get()) return; |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 157 | |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 158 | ScopedLocalRef<jstring> js_name(sCallbackEnv.get(), |
| 159 | sCallbackEnv->NewStringUTF(name)); |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 160 | sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCurrentOperator, |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 161 | js_name.get(), addr.get()); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 162 | } |
| 163 | |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 164 | static void call_cb(const RawAddress* bd_addr, bthf_client_call_t call) { |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 165 | CallbackEnv sCallbackEnv(__func__); |
| 166 | if (!sCallbackEnv.valid()) return; |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 167 | |
Andre Eisenbach | 2116dbf | 2017-03-17 04:47:41 +0000 | [diff] [blame] | 168 | ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 169 | if (!addr.get()) return; |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 170 | |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 171 | sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCall, (jint)call, |
| 172 | addr.get()); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 173 | } |
| 174 | |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 175 | static void callsetup_cb(const RawAddress* bd_addr, |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 176 | bthf_client_callsetup_t callsetup) { |
| 177 | CallbackEnv sCallbackEnv(__func__); |
| 178 | if (!sCallbackEnv.valid()) return; |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 179 | |
Andre Eisenbach | 2116dbf | 2017-03-17 04:47:41 +0000 | [diff] [blame] | 180 | ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 181 | if (!addr.get()) return; |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 182 | |
Marie Janssen | 19ec783 | 2017-02-22 07:26:34 -0800 | [diff] [blame] | 183 | ALOGD("callsetup_cb bdaddr %02x:%02x:%02x:%02x:%02x:%02x", |
| 184 | bd_addr->address[0], bd_addr->address[1], bd_addr->address[2], |
| 185 | bd_addr->address[3], bd_addr->address[4], bd_addr->address[5]); |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 186 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 187 | sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCallSetup, |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 188 | (jint)callsetup, addr.get()); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 189 | } |
| 190 | |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 191 | static void callheld_cb(const RawAddress* bd_addr, |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 192 | bthf_client_callheld_t callheld) { |
| 193 | CallbackEnv sCallbackEnv(__func__); |
| 194 | if (!sCallbackEnv.valid()) return; |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 195 | |
Andre Eisenbach | 2116dbf | 2017-03-17 04:47:41 +0000 | [diff] [blame] | 196 | ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 197 | if (!addr.get()) return; |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 198 | |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 199 | sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCallHeld, (jint)callheld, |
| 200 | addr.get()); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 201 | } |
| 202 | |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 203 | static void resp_and_hold_cb(const RawAddress* bd_addr, |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 204 | bthf_client_resp_and_hold_t resp_and_hold) { |
| 205 | CallbackEnv sCallbackEnv(__func__); |
| 206 | if (!sCallbackEnv.valid()) return; |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 207 | |
Andre Eisenbach | 2116dbf | 2017-03-17 04:47:41 +0000 | [diff] [blame] | 208 | ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 209 | if (!addr.get()) return; |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 210 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 211 | sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onRespAndHold, |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 212 | (jint)resp_and_hold, addr.get()); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 213 | } |
| 214 | |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 215 | static void clip_cb(const RawAddress* bd_addr, const char* number) { |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 216 | CallbackEnv sCallbackEnv(__func__); |
| 217 | if (!sCallbackEnv.valid()) return; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 218 | |
Andre Eisenbach | 2116dbf | 2017-03-17 04:47:41 +0000 | [diff] [blame] | 219 | ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 220 | if (!addr.get()) return; |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 221 | |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 222 | ScopedLocalRef<jstring> js_number(sCallbackEnv.get(), |
| 223 | sCallbackEnv->NewStringUTF(number)); |
| 224 | sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClip, js_number.get(), |
| 225 | addr.get()); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 226 | } |
| 227 | |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 228 | static void call_waiting_cb(const RawAddress* bd_addr, const char* number) { |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 229 | CallbackEnv sCallbackEnv(__func__); |
| 230 | if (!sCallbackEnv.valid()) return; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 231 | |
Andre Eisenbach | 2116dbf | 2017-03-17 04:47:41 +0000 | [diff] [blame] | 232 | ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 233 | if (!addr.get()) return; |
| 234 | ScopedLocalRef<jstring> js_number(sCallbackEnv.get(), |
| 235 | sCallbackEnv->NewStringUTF(number)); |
| 236 | sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCallWaiting, |
| 237 | js_number.get(), addr.get()); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 238 | } |
| 239 | |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 240 | static void current_calls_cb(const RawAddress* bd_addr, int index, |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 241 | bthf_client_call_direction_t dir, |
| 242 | bthf_client_call_state_t state, |
| 243 | bthf_client_call_mpty_type_t mpty, |
| 244 | const char* number) { |
| 245 | CallbackEnv sCallbackEnv(__func__); |
| 246 | if (!sCallbackEnv.valid()) return; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 247 | |
Andre Eisenbach | 2116dbf | 2017-03-17 04:47:41 +0000 | [diff] [blame] | 248 | ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 249 | if (!addr.get()) return; |
| 250 | ScopedLocalRef<jstring> js_number(sCallbackEnv.get(), |
| 251 | sCallbackEnv->NewStringUTF(number)); |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 252 | sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCurrentCalls, index, dir, |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 253 | state, mpty, js_number.get(), addr.get()); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 254 | } |
| 255 | |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 256 | static void volume_change_cb(const RawAddress* bd_addr, |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 257 | bthf_client_volume_type_t type, int volume) { |
| 258 | CallbackEnv sCallbackEnv(__func__); |
| 259 | if (!sCallbackEnv.valid()) return; |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 260 | |
Andre Eisenbach | 2116dbf | 2017-03-17 04:47:41 +0000 | [diff] [blame] | 261 | ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 262 | if (!addr.get()) return; |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 263 | sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVolumeChange, (jint)type, |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 264 | (jint)volume, addr.get()); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 265 | } |
| 266 | |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 267 | static void cmd_complete_cb(const RawAddress* bd_addr, |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 268 | bthf_client_cmd_complete_t type, int cme) { |
| 269 | CallbackEnv sCallbackEnv(__func__); |
| 270 | if (!sCallbackEnv.valid()) return; |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 271 | |
Andre Eisenbach | 2116dbf | 2017-03-17 04:47:41 +0000 | [diff] [blame] | 272 | ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 273 | if (!addr.get()) return; |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 274 | sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCmdResult, (jint)type, |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 275 | (jint)cme, addr.get()); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 276 | } |
| 277 | |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 278 | static void subscriber_info_cb(const RawAddress* bd_addr, const char* name, |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 279 | bthf_client_subscriber_service_type_t type) { |
| 280 | CallbackEnv sCallbackEnv(__func__); |
| 281 | if (!sCallbackEnv.valid()) return; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 282 | |
Andre Eisenbach | 2116dbf | 2017-03-17 04:47:41 +0000 | [diff] [blame] | 283 | ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 284 | if (!addr.get()) return; |
| 285 | ScopedLocalRef<jstring> js_name(sCallbackEnv.get(), |
| 286 | sCallbackEnv->NewStringUTF(name)); |
| 287 | sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSubscriberInfo, |
| 288 | js_name.get(), (jint)type, addr.get()); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 289 | } |
| 290 | |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 291 | static void in_band_ring_cb(const RawAddress* bd_addr, |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 292 | bthf_client_in_band_ring_state_t in_band) { |
| 293 | CallbackEnv sCallbackEnv(__func__); |
| 294 | if (!sCallbackEnv.valid()) return; |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 295 | |
Andre Eisenbach | 2116dbf | 2017-03-17 04:47:41 +0000 | [diff] [blame] | 296 | ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 297 | if (!addr.get()) return; |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 298 | sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onInBandRing, |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 299 | (jint)in_band, addr.get()); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 300 | } |
| 301 | |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 302 | static void last_voice_tag_number_cb(const RawAddress* bd_addr, |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 303 | const char* number) { |
| 304 | CallbackEnv sCallbackEnv(__func__); |
| 305 | if (!sCallbackEnv.valid()) return; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 306 | |
Andre Eisenbach | 2116dbf | 2017-03-17 04:47:41 +0000 | [diff] [blame] | 307 | ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 308 | if (!addr.get()) return; |
| 309 | ScopedLocalRef<jstring> js_number(sCallbackEnv.get(), |
| 310 | sCallbackEnv->NewStringUTF(number)); |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 311 | sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onLastVoiceTagNumber, |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 312 | js_number.get(), addr.get()); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 313 | } |
| 314 | |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 315 | static void ring_indication_cb(const RawAddress* bd_addr) { |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 316 | CallbackEnv sCallbackEnv(__func__); |
| 317 | if (!sCallbackEnv.valid()) return; |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 318 | |
Andre Eisenbach | 2116dbf | 2017-03-17 04:47:41 +0000 | [diff] [blame] | 319 | ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); |
Marie Janssen | 479b348 | 2016-10-11 13:54:41 -0700 | [diff] [blame] | 320 | if (!addr.get()) return; |
| 321 | sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onRingIndication, |
| 322 | addr.get()); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 323 | } |
| 324 | |
| 325 | static bthf_client_callbacks_t sBluetoothHfpClientCallbacks = { |
| 326 | sizeof(sBluetoothHfpClientCallbacks), |
| 327 | connection_state_cb, |
| 328 | audio_state_cb, |
| 329 | vr_cmd_cb, |
| 330 | network_state_cb, |
| 331 | network_roaming_cb, |
| 332 | network_signal_cb, |
| 333 | battery_level_cb, |
| 334 | current_operator_cb, |
| 335 | call_cb, |
| 336 | callsetup_cb, |
| 337 | callheld_cb, |
| 338 | resp_and_hold_cb, |
| 339 | clip_cb, |
| 340 | call_waiting_cb, |
| 341 | current_calls_cb, |
| 342 | volume_change_cb, |
| 343 | cmd_complete_cb, |
| 344 | subscriber_info_cb, |
| 345 | in_band_ring_cb, |
| 346 | last_voice_tag_number_cb, |
| 347 | ring_indication_cb, |
| 348 | }; |
| 349 | |
| 350 | static void classInitNative(JNIEnv* env, jclass clazz) { |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 351 | method_onConnectionStateChanged = |
| 352 | env->GetMethodID(clazz, "onConnectionStateChanged", "(III[B)V"); |
| 353 | method_onAudioStateChanged = |
| 354 | env->GetMethodID(clazz, "onAudioStateChanged", "(I[B)V"); |
Joseph Pirozzo | a4cca00 | 2017-10-06 14:04:22 -0700 | [diff] [blame^] | 355 | method_onVrStateChanged = |
| 356 | env->GetMethodID(clazz, "onVrStateChanged", "(I[B)V"); |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 357 | method_onNetworkState = env->GetMethodID(clazz, "onNetworkState", "(I[B)V"); |
| 358 | method_onNetworkRoaming = env->GetMethodID(clazz, "onNetworkRoaming", "(I[B)V"); |
| 359 | method_onNetworkSignal = env->GetMethodID(clazz, "onNetworkSignal", "(I[B)V"); |
| 360 | method_onBatteryLevel = env->GetMethodID(clazz, "onBatteryLevel", "(I[B)V"); |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 361 | method_onCurrentOperator = |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 362 | env->GetMethodID(clazz, "onCurrentOperator", "(Ljava/lang/String;[B)V"); |
| 363 | method_onCall = env->GetMethodID(clazz, "onCall", "(I[B)V"); |
| 364 | method_onCallSetup = env->GetMethodID(clazz, "onCallSetup", "(I[B)V"); |
| 365 | method_onCallHeld = env->GetMethodID(clazz, "onCallHeld", "(I[B)V"); |
| 366 | method_onRespAndHold = env->GetMethodID(clazz, "onRespAndHold", "(I[B)V"); |
| 367 | method_onClip = env->GetMethodID(clazz, "onClip", "(Ljava/lang/String;[B)V"); |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 368 | method_onCallWaiting = |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 369 | env->GetMethodID(clazz, "onCallWaiting", "(Ljava/lang/String;[B)V"); |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 370 | method_onCurrentCalls = |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 371 | env->GetMethodID(clazz, "onCurrentCalls", "(IIIILjava/lang/String;[B)V"); |
| 372 | method_onVolumeChange = env->GetMethodID(clazz, "onVolumeChange", "(II[B)V"); |
| 373 | method_onCmdResult = env->GetMethodID(clazz, "onCmdResult", "(II[B)V"); |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 374 | method_onSubscriberInfo = |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 375 | env->GetMethodID(clazz, "onSubscriberInfo", "(Ljava/lang/String;I[B)V"); |
| 376 | method_onInBandRing = env->GetMethodID(clazz, "onInBandRing", "(I[B)V"); |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 377 | method_onLastVoiceTagNumber = |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 378 | env->GetMethodID(clazz, "onLastVoiceTagNumber", "(Ljava/lang/String;[B)V"); |
| 379 | method_onRingIndication = env->GetMethodID(clazz, "onRingIndication", "([B)V"); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 380 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 381 | ALOGI("%s succeeds", __func__); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 382 | } |
| 383 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 384 | static void initializeNative(JNIEnv* env, jobject object) { |
Sanket Agarwal | 727dc79 | 2017-01-24 14:59:31 -0800 | [diff] [blame] | 385 | ALOGD("%s: HfpClient", __func__); |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 386 | const bt_interface_t* btInf = getBluetoothInterface(); |
| 387 | if (btInf == NULL) { |
| 388 | ALOGE("Bluetooth module is not loaded"); |
| 389 | return; |
| 390 | } |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 391 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 392 | if (sBluetoothHfpClientInterface != NULL) { |
| 393 | ALOGW("Cleaning up Bluetooth HFP Client Interface before initializing"); |
| 394 | sBluetoothHfpClientInterface->cleanup(); |
| 395 | sBluetoothHfpClientInterface = NULL; |
| 396 | } |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 397 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 398 | if (mCallbacksObj != NULL) { |
| 399 | ALOGW("Cleaning up Bluetooth HFP Client callback object"); |
| 400 | env->DeleteGlobalRef(mCallbacksObj); |
| 401 | mCallbacksObj = NULL; |
| 402 | } |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 403 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 404 | sBluetoothHfpClientInterface = |
| 405 | (bthf_client_interface_t*)btInf->get_profile_interface( |
| 406 | BT_PROFILE_HANDSFREE_CLIENT_ID); |
| 407 | if (sBluetoothHfpClientInterface == NULL) { |
| 408 | ALOGE("Failed to get Bluetooth HFP Client Interface"); |
| 409 | return; |
| 410 | } |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 411 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 412 | bt_status_t status = |
| 413 | sBluetoothHfpClientInterface->init(&sBluetoothHfpClientCallbacks); |
| 414 | if (status != BT_STATUS_SUCCESS) { |
| 415 | ALOGE("Failed to initialize Bluetooth HFP Client, status: %d", status); |
| 416 | sBluetoothHfpClientInterface = NULL; |
| 417 | return; |
| 418 | } |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 419 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 420 | mCallbacksObj = env->NewGlobalRef(object); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 421 | } |
| 422 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 423 | static void cleanupNative(JNIEnv* env, jobject object) { |
| 424 | const bt_interface_t* btInf = getBluetoothInterface(); |
| 425 | if (btInf == NULL) { |
| 426 | ALOGE("Bluetooth module is not loaded"); |
| 427 | return; |
| 428 | } |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 429 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 430 | if (sBluetoothHfpClientInterface != NULL) { |
| 431 | ALOGW("Cleaning up Bluetooth HFP Client Interface..."); |
| 432 | sBluetoothHfpClientInterface->cleanup(); |
| 433 | sBluetoothHfpClientInterface = NULL; |
| 434 | } |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 435 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 436 | if (mCallbacksObj != NULL) { |
| 437 | ALOGW("Cleaning up Bluetooth HFP Client callback object"); |
| 438 | env->DeleteGlobalRef(mCallbacksObj); |
| 439 | mCallbacksObj = NULL; |
| 440 | } |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 441 | } |
| 442 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 443 | static jboolean connectNative(JNIEnv* env, jobject object, jbyteArray address) { |
| 444 | if (!sBluetoothHfpClientInterface) return JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 445 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 446 | jbyte* addr = env->GetByteArrayElements(address, NULL); |
| 447 | if (!addr) { |
| 448 | jniThrowIOException(env, EINVAL); |
| 449 | return JNI_FALSE; |
| 450 | } |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 451 | |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 452 | bt_status_t status = sBluetoothHfpClientInterface->connect((RawAddress*)addr); |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 453 | if (status != BT_STATUS_SUCCESS) { |
| 454 | ALOGE("Failed AG connection, status: %d", status); |
| 455 | } |
| 456 | env->ReleaseByteArrayElements(address, addr, 0); |
| 457 | return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 458 | } |
| 459 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 460 | static jboolean disconnectNative(JNIEnv* env, jobject object, |
| 461 | jbyteArray address) { |
| 462 | if (!sBluetoothHfpClientInterface) return JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 463 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 464 | jbyte* addr = env->GetByteArrayElements(address, NULL); |
| 465 | if (!addr) { |
| 466 | jniThrowIOException(env, EINVAL); |
| 467 | return JNI_FALSE; |
| 468 | } |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 469 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 470 | bt_status_t status = |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 471 | sBluetoothHfpClientInterface->disconnect((const RawAddress*)addr); |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 472 | if (status != BT_STATUS_SUCCESS) { |
| 473 | ALOGE("Failed AG disconnection, status: %d", status); |
| 474 | } |
| 475 | env->ReleaseByteArrayElements(address, addr, 0); |
| 476 | return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 477 | } |
| 478 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 479 | static jboolean connectAudioNative(JNIEnv* env, jobject object, |
| 480 | jbyteArray address) { |
| 481 | if (!sBluetoothHfpClientInterface) return JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 482 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 483 | jbyte* addr = env->GetByteArrayElements(address, NULL); |
| 484 | if (!addr) { |
| 485 | jniThrowIOException(env, EINVAL); |
| 486 | return JNI_FALSE; |
| 487 | } |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 488 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 489 | bt_status_t status = |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 490 | sBluetoothHfpClientInterface->connect_audio((const RawAddress*)addr); |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 491 | if (status != BT_STATUS_SUCCESS) { |
| 492 | ALOGE("Failed AG audio connection, status: %d", status); |
| 493 | } |
| 494 | env->ReleaseByteArrayElements(address, addr, 0); |
| 495 | return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 496 | } |
| 497 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 498 | static jboolean disconnectAudioNative(JNIEnv* env, jobject object, |
| 499 | jbyteArray address) { |
| 500 | if (!sBluetoothHfpClientInterface) return JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 501 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 502 | jbyte* addr = env->GetByteArrayElements(address, NULL); |
| 503 | if (!addr) { |
| 504 | jniThrowIOException(env, EINVAL); |
| 505 | return JNI_FALSE; |
| 506 | } |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 507 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 508 | bt_status_t status = |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 509 | sBluetoothHfpClientInterface->disconnect_audio((const RawAddress*)addr); |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 510 | if (status != BT_STATUS_SUCCESS) { |
| 511 | ALOGE("Failed AG audio disconnection, status: %d", status); |
| 512 | } |
| 513 | env->ReleaseByteArrayElements(address, addr, 0); |
| 514 | return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 515 | } |
| 516 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 517 | static jboolean startVoiceRecognitionNative(JNIEnv* env, jobject object, |
| 518 | jbyteArray address) { |
| 519 | if (!sBluetoothHfpClientInterface) return JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 520 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 521 | jbyte* addr = env->GetByteArrayElements(address, NULL); |
| 522 | if (!addr) { |
| 523 | jniThrowIOException(env, EINVAL); |
| 524 | return JNI_FALSE; |
| 525 | } |
Sanket Agarwal | ef3a3b5 | 2016-11-28 15:53:06 -0800 | [diff] [blame] | 526 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 527 | bt_status_t status = sBluetoothHfpClientInterface->start_voice_recognition( |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 528 | (const RawAddress*)addr); |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 529 | if (status != BT_STATUS_SUCCESS) { |
| 530 | ALOGE("Failed to start voice recognition, status: %d", status); |
| 531 | } |
| 532 | env->ReleaseByteArrayElements(address, addr, 0); |
| 533 | return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 534 | } |
| 535 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 536 | static jboolean stopVoiceRecognitionNative(JNIEnv* env, jobject object, |
| 537 | jbyteArray address) { |
| 538 | if (!sBluetoothHfpClientInterface) return JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 539 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 540 | jbyte* addr = env->GetByteArrayElements(address, NULL); |
| 541 | if (!addr) { |
| 542 | jniThrowIOException(env, EINVAL); |
| 543 | return JNI_FALSE; |
| 544 | } |
Sanket Agarwal | ef3a3b5 | 2016-11-28 15:53:06 -0800 | [diff] [blame] | 545 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 546 | bt_status_t status = sBluetoothHfpClientInterface->stop_voice_recognition( |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 547 | (const RawAddress*)addr); |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 548 | if (status != BT_STATUS_SUCCESS) { |
| 549 | ALOGE("Failed to stop voice recognition, status: %d", status); |
| 550 | } |
| 551 | env->ReleaseByteArrayElements(address, addr, 0); |
| 552 | return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 553 | } |
| 554 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 555 | static jboolean setVolumeNative(JNIEnv* env, jobject object, jbyteArray address, |
| 556 | jint volume_type, jint volume) { |
| 557 | if (!sBluetoothHfpClientInterface) return JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 558 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 559 | jbyte* addr = env->GetByteArrayElements(address, NULL); |
| 560 | if (!addr) { |
| 561 | jniThrowIOException(env, EINVAL); |
| 562 | return JNI_FALSE; |
| 563 | } |
Sanket Agarwal | ef3a3b5 | 2016-11-28 15:53:06 -0800 | [diff] [blame] | 564 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 565 | bt_status_t status = sBluetoothHfpClientInterface->volume_control( |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 566 | (const RawAddress*)addr, (bthf_client_volume_type_t)volume_type, volume); |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 567 | if (status != BT_STATUS_SUCCESS) { |
| 568 | ALOGE("FAILED to control volume, status: %d", status); |
| 569 | } |
| 570 | env->ReleaseByteArrayElements(address, addr, 0); |
| 571 | return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 572 | } |
| 573 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 574 | static jboolean dialNative(JNIEnv* env, jobject object, jbyteArray address, |
| 575 | jstring number_str) { |
| 576 | if (!sBluetoothHfpClientInterface) return JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 577 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 578 | jbyte* addr = env->GetByteArrayElements(address, NULL); |
| 579 | if (!addr) { |
| 580 | jniThrowIOException(env, EINVAL); |
| 581 | return JNI_FALSE; |
| 582 | } |
Sanket Agarwal | ef3a3b5 | 2016-11-28 15:53:06 -0800 | [diff] [blame] | 583 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 584 | const char* number = NULL; |
| 585 | if (number_str != NULL) { |
| 586 | number = env->GetStringUTFChars(number_str, NULL); |
| 587 | } |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 588 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 589 | bt_status_t status = |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 590 | sBluetoothHfpClientInterface->dial((const RawAddress*)addr, number); |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 591 | if (status != BT_STATUS_SUCCESS) { |
| 592 | ALOGE("Failed to dial, status: %d", status); |
| 593 | } |
| 594 | if (number != NULL) { |
| 595 | env->ReleaseStringUTFChars(number_str, number); |
| 596 | } |
| 597 | env->ReleaseByteArrayElements(address, addr, 0); |
| 598 | return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 599 | } |
| 600 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 601 | static jboolean dialMemoryNative(JNIEnv* env, jobject object, |
| 602 | jbyteArray address, jint location) { |
| 603 | if (!sBluetoothHfpClientInterface) return JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 604 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 605 | jbyte* addr = env->GetByteArrayElements(address, NULL); |
| 606 | if (!addr) { |
| 607 | jniThrowIOException(env, EINVAL); |
| 608 | return JNI_FALSE; |
| 609 | } |
Sanket Agarwal | ef3a3b5 | 2016-11-28 15:53:06 -0800 | [diff] [blame] | 610 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 611 | bt_status_t status = sBluetoothHfpClientInterface->dial_memory( |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 612 | (const RawAddress*)addr, (int)location); |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 613 | if (status != BT_STATUS_SUCCESS) { |
| 614 | ALOGE("Failed to dial from memory, status: %d", status); |
| 615 | } |
Sanket Agarwal | ef3a3b5 | 2016-11-28 15:53:06 -0800 | [diff] [blame] | 616 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 617 | env->ReleaseByteArrayElements(address, addr, 0); |
| 618 | return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 619 | } |
| 620 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 621 | static jboolean handleCallActionNative(JNIEnv* env, jobject object, |
| 622 | jbyteArray address, jint action, |
| 623 | jint index) { |
| 624 | if (!sBluetoothHfpClientInterface) return JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 625 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 626 | jbyte* addr = env->GetByteArrayElements(address, NULL); |
| 627 | if (!addr) { |
| 628 | jniThrowIOException(env, EINVAL); |
| 629 | return JNI_FALSE; |
| 630 | } |
Sanket Agarwal | ef3a3b5 | 2016-11-28 15:53:06 -0800 | [diff] [blame] | 631 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 632 | bt_status_t status = sBluetoothHfpClientInterface->handle_call_action( |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 633 | (const RawAddress*)addr, (bthf_client_call_action_t)action, (int)index); |
Sanket Agarwal | ef3a3b5 | 2016-11-28 15:53:06 -0800 | [diff] [blame] | 634 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 635 | if (status != BT_STATUS_SUCCESS) { |
| 636 | ALOGE("Failed to enter private mode, status: %d", status); |
| 637 | } |
| 638 | env->ReleaseByteArrayElements(address, addr, 0); |
| 639 | return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 640 | } |
| 641 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 642 | static jboolean queryCurrentCallsNative(JNIEnv* env, jobject object, |
| 643 | jbyteArray address) { |
| 644 | if (!sBluetoothHfpClientInterface) return JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 645 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 646 | jbyte* addr = env->GetByteArrayElements(address, NULL); |
| 647 | if (!addr) { |
| 648 | jniThrowIOException(env, EINVAL); |
| 649 | return JNI_FALSE; |
| 650 | } |
Sanket Agarwal | ef3a3b5 | 2016-11-28 15:53:06 -0800 | [diff] [blame] | 651 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 652 | bt_status_t status = sBluetoothHfpClientInterface->query_current_calls( |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 653 | (const RawAddress*)addr); |
Sanket Agarwal | ef3a3b5 | 2016-11-28 15:53:06 -0800 | [diff] [blame] | 654 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 655 | if (status != BT_STATUS_SUCCESS) { |
| 656 | ALOGE("Failed to query current calls, status: %d", status); |
| 657 | } |
| 658 | env->ReleaseByteArrayElements(address, addr, 0); |
| 659 | return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 660 | } |
| 661 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 662 | static jboolean queryCurrentOperatorNameNative(JNIEnv* env, jobject object, |
| 663 | jbyteArray address) { |
| 664 | if (!sBluetoothHfpClientInterface) return JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 665 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 666 | jbyte* addr = env->GetByteArrayElements(address, NULL); |
| 667 | if (!addr) { |
| 668 | jniThrowIOException(env, EINVAL); |
| 669 | return JNI_FALSE; |
| 670 | } |
Sanket Agarwal | ef3a3b5 | 2016-11-28 15:53:06 -0800 | [diff] [blame] | 671 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 672 | bt_status_t status = |
| 673 | sBluetoothHfpClientInterface->query_current_operator_name( |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 674 | (const RawAddress*)addr); |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 675 | if (status != BT_STATUS_SUCCESS) { |
| 676 | ALOGE("Failed to query current operator name, status: %d", status); |
| 677 | } |
Sanket Agarwal | ef3a3b5 | 2016-11-28 15:53:06 -0800 | [diff] [blame] | 678 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 679 | env->ReleaseByteArrayElements(address, addr, 0); |
| 680 | return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 681 | } |
| 682 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 683 | static jboolean retrieveSubscriberInfoNative(JNIEnv* env, jobject object, |
| 684 | jbyteArray address) { |
| 685 | if (!sBluetoothHfpClientInterface) return JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 686 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 687 | jbyte* addr = env->GetByteArrayElements(address, NULL); |
| 688 | if (!addr) { |
| 689 | jniThrowIOException(env, EINVAL); |
| 690 | return JNI_FALSE; |
| 691 | } |
Sanket Agarwal | ef3a3b5 | 2016-11-28 15:53:06 -0800 | [diff] [blame] | 692 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 693 | bt_status_t status = sBluetoothHfpClientInterface->retrieve_subscriber_info( |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 694 | (const RawAddress*)addr); |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 695 | if (status != BT_STATUS_SUCCESS) { |
| 696 | ALOGE("Failed to retrieve subscriber info, status: %d", status); |
| 697 | } |
Sanket Agarwal | ef3a3b5 | 2016-11-28 15:53:06 -0800 | [diff] [blame] | 698 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 699 | env->ReleaseByteArrayElements(address, addr, 0); |
| 700 | return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 701 | } |
| 702 | |
Joseph Pirozzo | 39a5890 | 2017-04-20 11:30:38 -0700 | [diff] [blame] | 703 | static jboolean sendDtmfNative(JNIEnv* env, jobject object, jbyteArray address, |
| 704 | jbyte code) { |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 705 | if (!sBluetoothHfpClientInterface) return JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 706 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 707 | jbyte* addr = env->GetByteArrayElements(address, NULL); |
| 708 | if (!addr) { |
| 709 | jniThrowIOException(env, EINVAL); |
| 710 | return JNI_FALSE; |
| 711 | } |
Sanket Agarwal | ef3a3b5 | 2016-11-28 15:53:06 -0800 | [diff] [blame] | 712 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 713 | bt_status_t status = sBluetoothHfpClientInterface->send_dtmf( |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 714 | (const RawAddress*)addr, (char)code); |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 715 | if (status != BT_STATUS_SUCCESS) { |
| 716 | ALOGE("Failed to send DTMF, status: %d", status); |
| 717 | } |
Sanket Agarwal | ef3a3b5 | 2016-11-28 15:53:06 -0800 | [diff] [blame] | 718 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 719 | env->ReleaseByteArrayElements(address, addr, 0); |
| 720 | return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 721 | } |
| 722 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 723 | static jboolean requestLastVoiceTagNumberNative(JNIEnv* env, jobject object, |
| 724 | jbyteArray address) { |
| 725 | if (!sBluetoothHfpClientInterface) return JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 726 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 727 | jbyte* addr = env->GetByteArrayElements(address, NULL); |
| 728 | if (!addr) { |
| 729 | jniThrowIOException(env, EINVAL); |
| 730 | return JNI_FALSE; |
| 731 | } |
Sanket Agarwal | ef3a3b5 | 2016-11-28 15:53:06 -0800 | [diff] [blame] | 732 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 733 | bt_status_t status = |
| 734 | sBluetoothHfpClientInterface->request_last_voice_tag_number( |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 735 | (const RawAddress*)addr); |
Sanket Agarwal | ef3a3b5 | 2016-11-28 15:53:06 -0800 | [diff] [blame] | 736 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 737 | if (status != BT_STATUS_SUCCESS) { |
| 738 | ALOGE("Failed to request last Voice Tag number, status: %d", status); |
| 739 | } |
Sanket Agarwal | ef3a3b5 | 2016-11-28 15:53:06 -0800 | [diff] [blame] | 740 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 741 | env->ReleaseByteArrayElements(address, addr, 0); |
| 742 | return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 743 | } |
| 744 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 745 | static jboolean sendATCmdNative(JNIEnv* env, jobject object, jbyteArray address, |
| 746 | jint cmd, jint val1, jint val2, |
| 747 | jstring arg_str) { |
| 748 | if (!sBluetoothHfpClientInterface) return JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 749 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 750 | jbyte* addr = env->GetByteArrayElements(address, NULL); |
| 751 | if (!addr) { |
| 752 | jniThrowIOException(env, EINVAL); |
| 753 | return JNI_FALSE; |
| 754 | } |
Sanket Agarwal | ef3a3b5 | 2016-11-28 15:53:06 -0800 | [diff] [blame] | 755 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 756 | const char* arg = NULL; |
| 757 | if (arg_str != NULL) { |
| 758 | arg = env->GetStringUTFChars(arg_str, NULL); |
| 759 | } |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 760 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 761 | bt_status_t status = sBluetoothHfpClientInterface->send_at_cmd( |
Jakub Pawlowski | cb39925 | 2017-06-24 17:27:01 -0700 | [diff] [blame] | 762 | (const RawAddress*)addr, cmd, val1, val2, arg); |
Sanket Agarwal | ef3a3b5 | 2016-11-28 15:53:06 -0800 | [diff] [blame] | 763 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 764 | if (status != BT_STATUS_SUCCESS) { |
| 765 | ALOGE("Failed to send cmd, status: %d", status); |
| 766 | } |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 767 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 768 | if (arg != NULL) { |
| 769 | env->ReleaseStringUTFChars(arg_str, arg); |
| 770 | } |
Sanket Agarwal | ef3a3b5 | 2016-11-28 15:53:06 -0800 | [diff] [blame] | 771 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 772 | env->ReleaseByteArrayElements(address, addr, 0); |
| 773 | return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 774 | } |
| 775 | |
| 776 | static JNINativeMethod sMethods[] = { |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 777 | {"classInitNative", "()V", (void*)classInitNative}, |
| 778 | {"initializeNative", "()V", (void*)initializeNative}, |
| 779 | {"cleanupNative", "()V", (void*)cleanupNative}, |
| 780 | {"connectNative", "([B)Z", (void*)connectNative}, |
| 781 | {"disconnectNative", "([B)Z", (void*)disconnectNative}, |
| 782 | {"connectAudioNative", "([B)Z", (void*)connectAudioNative}, |
| 783 | {"disconnectAudioNative", "([B)Z", (void*)disconnectAudioNative}, |
| 784 | {"startVoiceRecognitionNative", "([B)Z", |
| 785 | (void*)startVoiceRecognitionNative}, |
| 786 | {"stopVoiceRecognitionNative", "([B)Z", (void*)stopVoiceRecognitionNative}, |
| 787 | {"setVolumeNative", "([BII)Z", (void*)setVolumeNative}, |
| 788 | {"dialNative", "([BLjava/lang/String;)Z", (void*)dialNative}, |
| 789 | {"dialMemoryNative", "([BI)Z", (void*)dialMemoryNative}, |
| 790 | {"handleCallActionNative", "([BII)Z", (void*)handleCallActionNative}, |
| 791 | {"queryCurrentCallsNative", "([B)Z", (void*)queryCurrentCallsNative}, |
| 792 | {"queryCurrentOperatorNameNative", "([B)Z", |
| 793 | (void*)queryCurrentOperatorNameNative}, |
| 794 | {"retrieveSubscriberInfoNative", "([B)Z", |
| 795 | (void*)retrieveSubscriberInfoNative}, |
| 796 | {"sendDtmfNative", "([BB)Z", (void*)sendDtmfNative}, |
Sanket Agarwal | ef3a3b5 | 2016-11-28 15:53:06 -0800 | [diff] [blame] | 797 | {"requestLastVoiceTagNumberNative", "([B)Z", |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 798 | (void*)requestLastVoiceTagNumberNative}, |
| 799 | {"sendATCmdNative", "([BIIILjava/lang/String;)Z", (void*)sendATCmdNative}, |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 800 | }; |
| 801 | |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 802 | int register_com_android_bluetooth_hfpclient(JNIEnv* env) { |
| 803 | return jniRegisterNativeMethods( |
Sanket Agarwal | 84f977c | 2016-12-14 14:09:38 -0800 | [diff] [blame] | 804 | env, "com/android/bluetooth/hfpclient/NativeInterface", |
Marie Janssen | dbd48b5 | 2016-12-06 09:57:09 -0800 | [diff] [blame] | 805 | sMethods, NELEM(sMethods)); |
Hemant Gupta | aebc726 | 2013-08-19 18:54:29 +0530 | [diff] [blame] | 806 | } |
| 807 | |
| 808 | } /* namespace android */ |