Skip to content

Commit b3a068d

Browse files
committed
android: remove unwrap spam.
1 parent 6b76b11 commit b3a068d

File tree

3 files changed

+71
-37
lines changed

3 files changed

+71
-37
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ bluer = { version = "0.16.1", features = ["bluetoothd"] }
5555
tokio = { version = "1.20.1", features = ["rt-multi-thread"] }
5656

5757
[target.'cfg(target_os = "android")'.dependencies]
58-
jni-glue = { git = "https://github.com/akiles/jni-bindgen", rev = "1ab6c3cb29ffcca01b269fc6c23900da6668288f" }
58+
jni-glue = { git = "https://github.com/akiles/jni-bindgen", rev = "45ddf3129bbe5987ab19f9c9be091de3bf3c5c25" }
5959
futures-channel = "0.3.24"
6060

6161
[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies]

src/android/adapter.rs

+46-35
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ use futures_channel::mpsc::{Receiver, Sender};
88
use futures_core::Stream;
99
use futures_lite::{stream, StreamExt};
1010
use jni_glue::{Argument, ByteArray, Env, Global, Local, PrimitiveArray, VM};
11-
use tracing::{info, warn};
11+
use tracing::{debug, warn};
1212
use uuid::Uuid;
1313

1414
use super::bindings::android::bluetooth::le::{BluetoothLeScanner, ScanResult};
1515
use super::bindings::android::bluetooth::{BluetoothAdapter, BluetoothManager};
1616
use super::bindings::android::os::ParcelUuid;
1717
use super::bindings::com::github::alexmoon::bluest::android::BluestScanCallback;
1818
use super::device::DeviceImpl;
19-
use super::JavaIterator;
19+
use super::{JavaIterator, OptionExt};
2020
use crate::android::bindings::java::util::Map_Entry;
2121
use crate::util::defer;
2222
use crate::{
@@ -41,8 +41,8 @@ impl AdapterImpl {
4141

4242
vm.with_env(|env| {
4343
let local_manager = manager.with(env);
44-
let adapter = local_manager.getAdapter()?.unwrap();
45-
let le_scanner = adapter.getBluetoothLeScanner()?.unwrap();
44+
let adapter = local_manager.getAdapter()?.non_null()?;
45+
let le_scanner = adapter.getBluetoothLeScanner()?.non_null()?;
4646

4747
Ok(Self {
4848
inner: Arc::new(AdapterInner {
@@ -89,8 +89,10 @@ impl AdapterImpl {
8989
self.inner.manager.vm().with_env(|env| {
9090
let callback = callback_global.with(env);
9191
let scanner = self.inner.le_scanner.with(env);
92-
scanner.stopScan_ScanCallback(&**callback).unwrap();
93-
info!("stopped scan");
92+
match scanner.stopScan_ScanCallback(&**callback) {
93+
Ok(()) => debug!("stopped scan"),
94+
Err(e) => warn!("failed to stop scan: {:?}", e),
95+
};
9496
});
9597
});
9698

@@ -225,53 +227,60 @@ pub extern "system" fn Java_com_github_alexmoon_bluest_android_BluestScanCallbac
225227
callback_type: i32,
226228
scan_result: Argument<ScanResult>,
227229
) {
228-
let scan_result = unsafe { scan_result.with_unchecked(env) }.unwrap();
230+
if let Err(e) = on_scan_result(env, id, callback_type, scan_result) {
231+
warn!("on_scan_result failed: {:?}", e);
232+
}
233+
}
229234

230-
tracing::info!("got callback! {} {}", id, callback_type);
235+
fn convert_uuid(uuid: Local<'_, ParcelUuid>) -> Result<Uuid> {
236+
let uuid = uuid.getUuid()?.non_null()?;
237+
let lsb = uuid.getLeastSignificantBits()? as u64;
238+
let msb = uuid.getMostSignificantBits()? as u64;
239+
Ok(Uuid::from_u64_pair(msb, lsb))
240+
}
231241

232-
let scan_record = scan_result.getScanRecord().unwrap().unwrap();
233-
let device = scan_result.getDevice().unwrap().unwrap();
242+
#[no_mangle]
243+
fn on_scan_result(env: Env<'_>, id: i32, callback_type: i32, scan_result: Argument<ScanResult>) -> Result<()> {
244+
let scan_result = unsafe { scan_result.with_unchecked(env) }.non_null()?;
234245

235-
fn convert_uuid(uuid: Local<'_, ParcelUuid>) -> Uuid {
236-
let uuid = uuid.getUuid().unwrap().unwrap();
237-
let lsb = uuid.getLeastSignificantBits().unwrap() as u64;
238-
let msb = uuid.getMostSignificantBits().unwrap() as u64;
239-
Uuid::from_u64_pair(msb, lsb)
240-
}
246+
tracing::info!("got callback! {} {}", id, callback_type);
241247

242-
let address = device.getAddress().unwrap().unwrap().to_string_lossy();
243-
let rssi = scan_result.getRssi().unwrap();
244-
let is_connectable = scan_result.isConnectable().unwrap();
245-
let local_name = scan_record.getDeviceName().unwrap().map(|s| s.to_string_lossy());
246-
let tx_power_level = scan_record.getTxPowerLevel().unwrap();
248+
let scan_record = scan_result.getScanRecord()?.non_null()?;
249+
let device = scan_result.getDevice()?.non_null()?;
250+
251+
let address = device.getAddress()?.non_null()?.to_string_lossy();
252+
let rssi = scan_result.getRssi()?;
253+
let is_connectable = scan_result.isConnectable()?;
254+
let local_name = scan_record.getDeviceName()?.map(|s| s.to_string_lossy());
255+
let tx_power_level = scan_record.getTxPowerLevel()?;
247256

248257
// Services
249258
let mut services = Vec::new();
250-
if let Some(uuids) = scan_record.getServiceUuids().unwrap() {
251-
for uuid in JavaIterator(uuids.iterator().unwrap().unwrap()) {
252-
services.push(convert_uuid(uuid.cast().unwrap()))
259+
if let Some(uuids) = scan_record.getServiceUuids()? {
260+
for uuid in JavaIterator(uuids.iterator()?.non_null()?) {
261+
services.push(convert_uuid(uuid.cast()?)?)
253262
}
254263
}
255264

256265
// Service data
257266
let mut service_data = HashMap::new();
258-
let sd = scan_record.getServiceData().unwrap().unwrap();
259-
let sd = sd.entrySet().unwrap().unwrap();
260-
for entry in JavaIterator(sd.iterator().unwrap().unwrap()) {
261-
let entry: Local<Map_Entry> = entry.cast().unwrap();
262-
let key: Local<ParcelUuid> = entry.getKey().unwrap().unwrap().cast().unwrap();
263-
let val: Local<ByteArray> = entry.getValue().unwrap().unwrap().cast().unwrap();
264-
service_data.insert(convert_uuid(key), val.as_vec().into_iter().map(|i| i as u8).collect());
267+
let sd = scan_record.getServiceData()?.non_null()?;
268+
let sd = sd.entrySet()?.non_null()?;
269+
for entry in JavaIterator(sd.iterator()?.non_null()?) {
270+
let entry: Local<Map_Entry> = entry.cast()?;
271+
let key: Local<ParcelUuid> = entry.getKey()?.non_null()?.cast()?;
272+
let val: Local<ByteArray> = entry.getValue()?.non_null()?.cast()?;
273+
service_data.insert(convert_uuid(key)?, val.as_vec().into_iter().map(|i| i as u8).collect());
265274
}
266275

267276
// Manufacturer data
268277
let mut manufacturer_data = None;
269-
let msd = scan_record.getManufacturerSpecificData().unwrap().unwrap();
278+
let msd = scan_record.getManufacturerSpecificData()?.non_null()?;
270279
// TODO there can be multiple manufacturer data entries, but the bluest API only supports one. So grab just the first.
271-
if msd.size().unwrap() != 0 {
272-
let val: Local<'_, ByteArray> = msd.valueAt(0).unwrap().unwrap().cast().unwrap();
280+
if msd.size()? != 0 {
281+
let val: Local<'_, ByteArray> = msd.valueAt(0)?.non_null()?.cast()?;
273282
manufacturer_data = Some(ManufacturerData {
274-
company_id: msd.keyAt(0).unwrap() as _,
283+
company_id: msd.keyAt(0)? as _,
275284
data: val.as_vec().into_iter().map(|i| i as u8).collect(),
276285
});
277286
}
@@ -291,6 +300,8 @@ pub extern "system" fn Java_com_github_alexmoon_bluest_android_BluestScanCallbac
291300
rssi: Some(rssi as _),
292301
};
293302
SCAN_CALLBACKS.callback(id, d);
303+
304+
Ok(())
294305
}
295306

296307
#[no_mangle]

src/android/mod.rs

+24-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use jni_glue::Local;
1+
use jni_glue::{CastError, Local};
22

33
use self::bindings::java::lang::Throwable;
44
use crate::error::ErrorKind;
@@ -28,6 +28,12 @@ impl From<Local<'_, Throwable>> for crate::Error {
2828
}
2929
}
3030

31+
impl From<CastError> for crate::Error {
32+
fn from(e: CastError) -> Self {
33+
Self::new(ErrorKind::Internal, None, format!("{:?}", e))
34+
}
35+
}
36+
3137
struct JavaIterator<'env>(Local<'env, bindings::java::util::Iterator>);
3238

3339
impl<'env> Iterator for JavaIterator<'env> {
@@ -43,3 +49,20 @@ impl<'env> Iterator for JavaIterator<'env> {
4349
}
4450
}
4551
}
52+
53+
trait OptionExt<T> {
54+
fn non_null(self) -> Result<T, crate::Error>;
55+
}
56+
57+
impl<T> OptionExt<T> for Option<T> {
58+
#[track_caller]
59+
fn non_null(self) -> Result<T, crate::Error> {
60+
self.ok_or_else(|| {
61+
crate::Error::new(
62+
ErrorKind::Internal,
63+
None,
64+
"Java call unexpectedly returned null.".to_string(),
65+
)
66+
})
67+
}
68+
}

0 commit comments

Comments
 (0)