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 18 #pragma once 19 20 #include <bluetooth/log.h> 21 22 #include "hardware/bluetooth.h" 23 #include "hardware/hardware.h" 24 #include "jni.h" 25 #include "nativehelper/ScopedLocalRef.h" 26 27 namespace log = bluetooth::log; 28 29 namespace android { 30 31 JNIEnv* getCallbackEnv(); 32 bool isCallbackThread(); 33 34 class CallbackEnv { 35 public: CallbackEnv(const char * methodName)36 CallbackEnv(const char* methodName) : mName(methodName) { mCallbackEnv = getCallbackEnv(); } 37 ~CallbackEnv()38 ~CallbackEnv() { 39 if (mCallbackEnv && mCallbackEnv->ExceptionCheck()) { 40 log::error("An exception was thrown by callback '{}'.", mName); 41 jniLogException(mCallbackEnv, ANDROID_LOG_ERROR, LOG_TAG); 42 mCallbackEnv->ExceptionClear(); 43 } 44 } 45 valid()46 bool valid() const { 47 if (!mCallbackEnv || !isCallbackThread()) { 48 log::error("{}: Callback env fail", mName); 49 return false; 50 } 51 return true; 52 } 53 54 // stolen from art/runtime/jni/check_jni.cc isValidUtf(const char * bytes)55 bool isValidUtf(const char* bytes) const { 56 while (*bytes != '\0') { 57 const uint8_t* utf8 = reinterpret_cast<const uint8_t*>(bytes++); 58 // Switch on the high four bits. 59 switch (*utf8 >> 4) { 60 case 0x00: 61 case 0x01: 62 case 0x02: 63 case 0x03: 64 case 0x04: 65 case 0x05: 66 case 0x06: 67 case 0x07: 68 // Bit pattern 0xxx. No need for any extra bytes. 69 break; 70 case 0x08: 71 case 0x09: 72 case 0x0a: 73 case 0x0b: 74 // Bit patterns 10xx, which are illegal start bytes. 75 return false; 76 case 0x0f: 77 // Bit pattern 1111, which might be the start of a 4 byte sequence. 78 if ((*utf8 & 0x08) == 0) { 79 // Bit pattern 1111 0xxx, which is the start of a 4 byte sequence. 80 // We consume one continuation byte here, and fall through to 81 // consume two more. 82 utf8 = reinterpret_cast<const uint8_t*>(bytes++); 83 if ((*utf8 & 0xc0) != 0x80) { 84 return false; 85 } 86 } else { 87 return false; 88 } 89 // Fall through to the cases below to consume two more continuation 90 // bytes. 91 [[fallthrough]]; 92 case 0x0e: 93 // Bit pattern 1110, so there are two additional bytes. 94 utf8 = reinterpret_cast<const uint8_t*>(bytes++); 95 if ((*utf8 & 0xc0) != 0x80) { 96 return false; 97 } 98 // Fall through to consume one more continuation byte. 99 [[fallthrough]]; 100 case 0x0c: 101 case 0x0d: 102 // Bit pattern 110x, so there is one additional byte. 103 utf8 = reinterpret_cast<const uint8_t*>(bytes++); 104 if ((*utf8 & 0xc0) != 0x80) { 105 return false; 106 } 107 break; 108 } 109 } 110 return true; 111 } 112 113 JNIEnv* operator->() const { return mCallbackEnv; } 114 get()115 JNIEnv* get() const { return mCallbackEnv; } 116 117 private: 118 JNIEnv* mCallbackEnv; 119 const char* mName; 120 121 CallbackEnv(const CallbackEnv&) = delete; 122 void operator=(const CallbackEnv&) = delete; 123 }; 124 125 const bt_interface_t* getBluetoothInterface(); 126 127 int register_com_android_bluetooth_hfp(JNIEnv* env); 128 129 int register_com_android_bluetooth_hfpclient(JNIEnv* env); 130 131 int register_com_android_bluetooth_a2dp(JNIEnv* env); 132 133 int register_com_android_bluetooth_a2dp_sink(JNIEnv* env); 134 135 int register_com_android_bluetooth_avrcp(JNIEnv* env); 136 137 int register_com_android_bluetooth_avrcp_target(JNIEnv* env); 138 139 int register_com_android_bluetooth_avrcp_controller(JNIEnv* env); 140 141 int register_com_android_bluetooth_hid_host(JNIEnv* env); 142 143 int register_com_android_bluetooth_hid_device(JNIEnv* env); 144 145 int register_com_android_bluetooth_pan(JNIEnv* env); 146 147 int register_com_android_bluetooth_gatt(JNIEnv* env); 148 149 int register_com_android_bluetooth_sdp(JNIEnv* env); 150 151 int register_com_android_bluetooth_hearing_aid(JNIEnv* env); 152 153 int register_com_android_bluetooth_hap_client(JNIEnv* env); 154 155 int register_com_android_bluetooth_btservice_BluetoothKeystore(JNIEnv* env); 156 157 int register_com_android_bluetooth_le_audio(JNIEnv* env); 158 159 int register_com_android_bluetooth_vc(JNIEnv* env); 160 161 int register_com_android_bluetooth_csip_set_coordinator(JNIEnv* env); 162 163 int register_com_android_bluetooth_btservice_BluetoothQualityReport(JNIEnv* env); 164 165 int register_com_android_bluetooth_btservice_BluetoothHciVendorSpecific(JNIEnv* env); 166 167 struct JNIJavaMethod { 168 const char* name; 169 const char* signature; 170 jmethodID* id; 171 bool is_static{false}; 172 }; 173 174 void jniGetMethodsOrDie(JNIEnv* env, const char* className, const JNIJavaMethod* methods, 175 int nMethods); 176 177 #define REGISTER_NATIVE_METHODS(env, classname, methodsArray) \ 178 jniRegisterNativeMethods(env, classname, methodsArray, NELEM(methodsArray)) 179 180 #define GET_JAVA_METHODS(env, classname, methodsArray) \ 181 jniGetMethodsOrDie(env, classname, methodsArray, NELEM(methodsArray)) 182 183 } // namespace android 184