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