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