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