Skip to content

Commit d7d9959

Browse files
author
Andrei Vasiliu
committed
jni: Implemented getObject* functions and added defensive checks
Signed-off-by: Andrei Vasiliu <andrei.vasiliu@intel.com>
1 parent 636680b commit d7d9959

9 files changed

Lines changed: 189 additions & 54 deletions

java/BluetoothManager.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,19 @@ public class BluetoothManager
4141
}
4242

4343
public native BluetoothType getBluetoothType();
44-
public native BluetoothObject getObject(BluetoothType type, String name,
44+
45+
public BluetoothObject getObject(BluetoothType type, String name,
46+
String identifier, BluetoothObject parent) {
47+
return getObject(type.ordinal(), name, identifier, parent);
48+
}
49+
private native BluetoothObject getObject(int type, String name,
4550
String identifier, BluetoothObject parent);
46-
public native List<BluetoothObject> getObjects(BluetoothType type, String name,
51+
52+
public List<BluetoothObject> getObjects(BluetoothType type, String name,
53+
String identifier, BluetoothObject parent) {
54+
return getObjects(type.ordinal(), name, identifier, parent);
55+
}
56+
private native List<BluetoothObject> getObjects(int type, String name,
4757
String identifier, BluetoothObject parent);
4858

4959
/** Returns a list of BluetoothAdapters available in the system

java/jni/BluetoothAdapter.cxx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,7 @@ void Java_tinyb_BluetoothAdapter_setAlias(JNIEnv *env, jobject obj, jstring str)
9696
{
9797
BluetoothAdapter *obj_adapter = getInstance<BluetoothAdapter>(env, obj);
9898

99-
jboolean is_copy = JNI_TRUE;
100-
const char *str_chars = (char *)env->GetStringUTFChars(str, &is_copy);
101-
const std::string string_to_write = std::string(str_chars);
102-
103-
env->ReleaseStringUTFChars(str, str_chars);
99+
const std::string string_to_write = from_jstring_to_string(env, str);
104100

105101
obj_adapter->set_alias(string_to_write);
106102
}
@@ -208,6 +204,10 @@ jobjectArray Java_tinyb_BluetoothAdapter_getUuids(JNIEnv *env, jobject obj)
208204

209205
jclass string_class = search_class(env, "Ljava/lang/String;");
210206
jobjectArray result = env->NewObjectArray(uuids_size, string_class, 0);
207+
if (!result)
208+
{
209+
throw std::runtime_error("NewObjectArray cannot create instance\n");
210+
}
211211

212212
for (unsigned int i = 0; i < uuids_size; ++i)
213213
{

java/jni/BluetoothDevice.cxx

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -63,26 +63,18 @@ jboolean Java_tinyb_BluetoothDevice_connectProfile(JNIEnv *env, jobject obj, jst
6363
{
6464
BluetoothDevice *obj_device = getInstance<BluetoothDevice>(env, obj);
6565

66-
jboolean is_copy = JNI_TRUE;
67-
const char *str_chars = (char *)env->GetStringUTFChars(str, &is_copy);
68-
const std::string string_to_write = std::string(str_chars);
66+
const std::string string_to_write = from_jstring_to_string(env, str);
6967

70-
env->ReleaseStringUTFChars(str, str_chars);
71-
72-
return obj_device->connect_profile(string_to_write);
68+
return obj_device->connect_profile(string_to_write) ? JNI_TRUE : JNI_FALSE;
7369
}
7470

7571
jboolean Java_tinyb_BluetoothDevice_disconnectProfile(JNIEnv *env, jobject obj, jstring str)
7672
{
7773
BluetoothDevice *obj_device = getInstance<BluetoothDevice>(env, obj);
7874

79-
jboolean is_copy = JNI_TRUE;
80-
const char *str_chars = (char *)env->GetStringUTFChars(str, &is_copy);
81-
const std::string string_to_write = std::string(str_chars);
82-
83-
env->ReleaseStringUTFChars(str, str_chars);
75+
const std::string string_to_write = from_jstring_to_string(env, str);
8476

85-
return obj_device->disconnect_profile(string_to_write);
77+
return obj_device->disconnect_profile(string_to_write) ? JNI_TRUE : JNI_FALSE;
8678
}
8779

8880
jboolean Java_tinyb_BluetoothDevice_pair(JNIEnv *env, jobject obj)
@@ -137,11 +129,7 @@ void Java_tinyb_BluetoothDevice_setAlias(JNIEnv *env, jobject obj, jstring str)
137129
{
138130
BluetoothDevice *obj_device = getInstance<BluetoothDevice>(env, obj);
139131

140-
jboolean is_copy = JNI_TRUE;
141-
const char *str_chars = (char *)env->GetStringUTFChars(str, &is_copy);
142-
const std::string string_to_write = std::string(str_chars);
143-
144-
env->ReleaseStringUTFChars(str, str_chars);
132+
const std::string string_to_write = from_jstring_to_string(env, str);
145133

146134
obj_device->set_alias(string_to_write);
147135
}
@@ -262,7 +250,7 @@ jobject Java_tinyb_BluetoothDevice_getAdapter(JNIEnv *env, jobject obj)
262250
jmethodID b_adapter_ctor = search_method(env, b_adapter_class, "<init>",
263251
"(J)V", false);
264252
jobject result = env->NewObject(b_adapter_class, b_adapter_ctor, (jlong)obj_adapter);
265-
if (result == NULL)
253+
if (!result)
266254
{
267255
throw std::runtime_error("cannot create instance of class\n");
268256
}

java/jni/BluetoothGattCharacteristic.cxx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ jbyteArray Java_tinyb_BluetoothGattCharacteristic_readValue(JNIEnv *env, jobject
6060

6161
jboolean Java_tinyb_BluetoothGattCharacteristic_writeValue(JNIEnv *env, jobject obj, jbyteArray argValue)
6262
{
63+
if (!argValue)
64+
{
65+
throw std::invalid_argument("byte array argument is null\n");
66+
}
67+
6368
BluetoothGattCharacteristic *obj_gatt_char =
6469
getInstance<BluetoothGattCharacteristic>(env, obj);
6570

@@ -73,7 +78,7 @@ jboolean Java_tinyb_BluetoothGattCharacteristic_writeValue(JNIEnv *env, jobject
7378
array.push_back(native_array[i]);
7479
}
7580

76-
return obj_gatt_char->write_value(array);
81+
return obj_gatt_char->write_value(array) ? JNI_TRUE : JNI_FALSE;
7782
}
7883

7984
jboolean Java_tinyb_BluetoothGattCharacteristic_startNotify(JNIEnv *env, jobject obj)

java/jni/BluetoothGattDescriptor.cxx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ jbyteArray Java_tinyb_BluetoothGattDescriptor_readValue(JNIEnv *env, jobject obj
5858

5959
jboolean Java_tinyb_BluetoothGattDescriptor_writeValue(JNIEnv *env, jobject obj, jbyteArray argValue)
6060
{
61+
if (!argValue)
62+
{
63+
throw std::invalid_argument("byte array argument is null\n");
64+
}
65+
6166
BluetoothGattDescriptor *obj_gatt_desc = getInstance<BluetoothGattDescriptor>(env, obj);
6267

6368
jboolean is_copy = false;
@@ -70,7 +75,7 @@ jboolean Java_tinyb_BluetoothGattDescriptor_writeValue(JNIEnv *env, jobject obj,
7075
array.push_back(native_array[i]);
7176
}
7277

73-
return obj_gatt_desc->write_value(array);
78+
return obj_gatt_desc->write_value(array) ? JNI_TRUE : JNI_FALSE;
7479
}
7580

7681
jstring Java_tinyb_BluetoothGattDescriptor_getUuid(JNIEnv *env, jobject obj)

java/jni/BluetoothManager.cxx

Lines changed: 83 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,30 +40,91 @@ jobject Java_tinyb_BluetoothManager_getBluetoothType(JNIEnv *env, jobject obj)
4040
return get_bluetooth_type(env, "NONE");
4141
}
4242

43-
jobject Java_tinyb_BluetoothManager_getObject(JNIEnv *env, jobject obj, jobject type,
44-
jstring name, jstring identifier, jobject parent)
43+
static void getObject_setter(JNIEnv *env,
44+
jstring name, std::string **name_to_write,
45+
jstring identifier, std::string **identifier_to_write,
46+
jobject parent, BluetoothObject **b_parent)
4547
{
46-
(void)env;
47-
(void)obj;
48-
(void)type;
49-
(void)name;
50-
(void)identifier;
51-
(void)parent;
52-
53-
return nullptr;
48+
if (!parent)
49+
{
50+
*b_parent = nullptr;
51+
}
52+
else
53+
{
54+
*b_parent = getInstance<BluetoothObject>(env, parent);
55+
}
56+
57+
if (!name)
58+
{
59+
*name_to_write = nullptr;
60+
}
61+
else
62+
{
63+
**name_to_write = from_jstring_to_string(env, name);
64+
}
65+
66+
if (!identifier)
67+
{
68+
*identifier_to_write = nullptr;
69+
}
70+
else
71+
{
72+
**identifier_to_write = from_jstring_to_string(env, identifier);
73+
}
5474
}
5575

56-
jobject Java_tinyb_BluetoothManager_getObjects(JNIEnv *env, jobject obj, jobject type,
76+
jobject Java_tinyb_BluetoothManager_getObject(JNIEnv *env, jobject obj, jint type,
5777
jstring name, jstring identifier, jobject parent)
5878
{
59-
(void)env;
60-
(void)obj;
61-
(void)type;
62-
(void)name;
63-
(void)identifier;
64-
(void)parent;
79+
BluetoothManager *manager = getInstance<BluetoothManager>(env, obj);
80+
BluetoothObject *b_parent;
81+
BluetoothType b_type;
82+
std::string *name_to_write;
83+
std::string *identifier_to_write;
84+
85+
getObject_setter(env,
86+
name, &name_to_write,
87+
identifier, &identifier_to_write,
88+
parent, &b_parent);
89+
90+
b_type = from_int_to_btype((int)type);
91+
std::unique_ptr<BluetoothObject> b_object = manager->get_object(b_type, name_to_write,
92+
identifier_to_write,
93+
b_parent);
94+
95+
BluetoothObject *b_object_naked = b_object.release();
96+
if (!b_object_naked)
97+
{
98+
return nullptr;
99+
}
100+
jclass clazz = search_class(env, *b_object_naked);
101+
jmethodID clazz_ctor = search_method(env, clazz, "<init>", "(J)V", false);
102+
103+
jobject result = env->NewObject(clazz, clazz_ctor, (long)b_object_naked);
104+
return result;
105+
}
65106

66-
return nullptr;
107+
jobject Java_tinyb_BluetoothManager_getObjects(JNIEnv *env, jobject obj, jint type,
108+
jstring name, jstring identifier, jobject parent)
109+
{
110+
BluetoothManager *manager = getInstance<BluetoothManager>(env, obj);
111+
BluetoothObject *b_parent;
112+
BluetoothType b_type;
113+
std::string *name_to_write;
114+
std::string *identifier_to_write;
115+
116+
getObject_setter(env,
117+
name, &name_to_write,
118+
identifier, &identifier_to_write,
119+
parent, &b_parent);
120+
121+
b_type = from_int_to_btype((int)type);
122+
std::vector<std::unique_ptr<BluetoothObject>> array = manager->get_objects(b_type,
123+
name_to_write,
124+
identifier_to_write,
125+
b_parent);
126+
jobject result = convert_vector_to_jobject<BluetoothObject>(env, array, "(J)V");
127+
return result;
67128
}
68129

69130
jobject Java_tinyb_BluetoothManager_getAdapters(JNIEnv *env, jobject obj)
@@ -99,6 +160,10 @@ jobject Java_tinyb_BluetoothManager_getServices(JNIEnv *env, jobject obj)
99160

100161
jboolean Java_tinyb_BluetoothManager_setDefaultAdapter(JNIEnv *env, jobject obj, jobject adapter)
101162
{
163+
if (!adapter)
164+
{
165+
throw std::invalid_argument("adapter argument is null\n");
166+
}
102167
BluetoothManager *manager = getInstance<BluetoothManager>(env, obj);
103168
BluetoothAdapter *b_adapter = getInstance<BluetoothAdapter>(env, adapter);
104169

java/jni/BluetoothObject.cxx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ void Java_tinyb_BluetoothObject_delete(JNIEnv *env, jobject obj)
5151

5252
jboolean Java_tinyb_BluetoothObject_operatorEqual(JNIEnv *env, jobject obj, jobject other)
5353
{
54+
if (!other)
55+
{
56+
return JNI_FALSE;
57+
}
5458
BluetoothObject *obj_b = getInstance<BluetoothObject>(env, obj);
5559
BluetoothObject *obj_other = getInstance<BluetoothObject>(env, other);
5660

java/jni/helper.cxx

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ jclass search_class(JNIEnv *env, tinyb::BluetoothObject &object)
4444
jclass search_class(JNIEnv *env, const char *clazz_name)
4545
{
4646
jclass clazz = env->FindClass(clazz_name);
47-
if (clazz == NULL)
47+
if (!clazz)
4848
{
4949
std::string error = "no class found: "; error += clazz_name;
5050
throw std::runtime_error(error);
@@ -56,7 +56,7 @@ jmethodID search_method(JNIEnv *env, jclass clazz, const char *method_name,
5656
const char *prototype, bool is_static)
5757
{
5858
jmethodID method;
59-
if(is_static)
59+
if (is_static)
6060
{
6161
method = env->GetStaticMethodID(clazz, method_name, prototype);
6262
}
@@ -65,7 +65,7 @@ jmethodID search_method(JNIEnv *env, jclass clazz, const char *method_name,
6565
method = env->GetMethodID(clazz, method_name, prototype);
6666
}
6767

68-
if(method == NULL)
68+
if (!method)
6969
{
7070
throw std::runtime_error("no method found\n");
7171
}
@@ -77,7 +77,7 @@ jfieldID search_field(JNIEnv *env, jclass clazz, const char *field_name,
7777
const char *type, bool is_static)
7878
{
7979
jfieldID field;
80-
if(is_static)
80+
if (is_static)
8181
{
8282
field = env->GetStaticFieldID(clazz, field_name, type);
8383
}
@@ -86,7 +86,7 @@ jfieldID search_field(JNIEnv *env, jclass clazz, const char *field_name,
8686
field = env->GetFieldID(clazz, field_name, type);
8787
}
8888

89-
if(field == NULL)
89+
if (!field)
9090
{
9191
throw std::runtime_error("no method found\n");
9292
}
@@ -117,6 +117,60 @@ bool from_jboolean_to_bool(jboolean val)
117117
return result;
118118
}
119119

120+
std::string from_jstring_to_string(JNIEnv *env, jstring str)
121+
{
122+
jboolean is_copy = JNI_TRUE;
123+
const char *str_chars = (char *)env->GetStringUTFChars(str, &is_copy);
124+
if (!str_chars)
125+
{
126+
throw std::runtime_error("GetStringUTFChars returned NULL\n");
127+
}
128+
const std::string string_to_write = std::string(str_chars);
129+
130+
env->ReleaseStringUTFChars(str, str_chars);
131+
132+
return string_to_write;
133+
}
134+
135+
tinyb::BluetoothType from_int_to_btype(int type)
136+
{
137+
tinyb::BluetoothType result = tinyb::BluetoothType::NONE;
138+
139+
switch (type)
140+
{
141+
case 0:
142+
result = tinyb::BluetoothType::NONE;
143+
break;
144+
145+
case 1:
146+
result = tinyb::BluetoothType::ADAPTER;
147+
break;
148+
149+
case 2:
150+
result = tinyb::BluetoothType::DEVICE;
151+
break;
152+
153+
case 3:
154+
result = tinyb::BluetoothType::GATT_SERVICE;
155+
break;
156+
157+
case 4:
158+
result = tinyb::BluetoothType::GATT_CHARACTERISTIC;
159+
break;
160+
161+
case 5:
162+
result = tinyb::BluetoothType::GATT_CHARACTERISTIC;
163+
break;
164+
165+
default:
166+
result = tinyb::BluetoothType::NONE;
167+
break;
168+
}
169+
170+
return result;
171+
}
172+
173+
120174
jobject get_bluetooth_type(JNIEnv *env, const char *field_name)
121175
{
122176
jclass b_type_enum = search_class(env, JAVA_PACKAGE "/BluetoothType");
@@ -127,14 +181,13 @@ jobject get_bluetooth_type(JNIEnv *env, const char *field_name)
127181
return result;
128182
}
129183

130-
131184
jobject get_new_arraylist(JNIEnv *env, unsigned int size, jmethodID *add)
132185
{
133186
jclass arraylist_class = search_class(env, "Ljava/util/ArrayList;");
134187
jmethodID arraylist_ctor = search_method(env, arraylist_class, "<init>", "(I)V", false);
135188

136189
jobject result = env->NewObject(arraylist_class, arraylist_ctor, size);
137-
if (result == NULL)
190+
if (!result)
138191
{
139192
throw std::runtime_error("cannot create instance of class\n");
140193
}

0 commit comments

Comments
 (0)