Skip to content

Commit

Permalink
🤡 Implement the testing hack as a mock method in the data collection …
Browse files Browse the repository at this point in the history
…plugin

We created a testing hack to test the previous read/write native changes.
e-mission/e-mission-phone#1144 (comment)

We now move that hack to the plugin interface and make it accessible externally.
That makes it easier to call from the UI for better mocking.
Concretely, we can modify
e-mission/e-mission-phone@7cb3882
to call the interface, which will write sensor data using native code.
This allows us to simulate the actual working of the system (writing native
code) through the UI

Summary of changes:
- Create a new `mockBLEObjects` method in the interface
- Implement it on both android and iOS
- Change the fake object implementaton in the BluetoothBLE wrapper to take more
  arguments to that they can be passed in from the UI

Testing done:
e-mission/e-mission-phone@463c2a5
  • Loading branch information
shankari committed Apr 13, 2024
1 parent 4220302 commit 0846678
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 19 deletions.
30 changes: 30 additions & 0 deletions src/android/DataCollectionPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@
import edu.berkeley.eecs.emission.cordova.tracker.wrapper.ConsentConfig;
import edu.berkeley.eecs.emission.cordova.tracker.wrapper.LocationTrackingConfig;
import edu.berkeley.eecs.emission.cordova.tracker.wrapper.StatsEvent;
import edu.berkeley.eecs.emission.cordova.tracker.wrapper.BluetoothBLE;
import edu.berkeley.eecs.emission.cordova.tracker.verification.SensorControlForegroundDelegate;
import edu.berkeley.eecs.emission.cordova.unifiedlogger.Log;
import edu.berkeley.eecs.emission.cordova.usercache.BuiltinUserCache;
import edu.berkeley.eecs.emission.cordova.usercache.UserCacheFactory;

public class DataCollectionPlugin extends CordovaPlugin {
public static final String TAG = "DataCollectionPlugin";
Expand Down Expand Up @@ -193,6 +195,34 @@ public void run() {
}
});
return true;
} else if (action.equals("mockBLEObjects")) {
// we want to run this in a background thread because it might sometimes wait to get
// the current location
final String eventType = data.getString(0);
final String uuid = data.getString(1);
final int major = data.getInt(2);
final int minor = data.getInt(3);
final int nObjects = data.getInt(4);
cordova.getThreadPool().execute(new Runnable() {
@Override
public void run() {
Context ctxt = cordova.getActivity();
for (int i = 0; i < nObjects; i++) {
BluetoothBLE currWrapper = BluetoothBLE.initFake(eventType, uuid, major, minor);
UserCacheFactory.getUserCache(ctxt).putSensorData(R.string.key_usercache_bluetooth_ble,
currWrapper);
}
BluetoothBLE[] justAddedEntries = UserCacheFactory.getUserCache(ctxt).getLastSensorData(
R.string.key_usercache_bluetooth_ble, nObjects, BluetoothBLE.class);
for(BluetoothBLE currEntry : justAddedEntries) {
if (!currEntry.getEventType().equals(eventType)) {
callbackContext.error(currEntry.getEventType()+ " found in last "+nObjects+" objects, expected all "+eventType);
}
callbackContext.success(eventType);
}
}
});
return true;
} else if (action.equals("handleSilentPush")) {
throw new UnsupportedOperationException("silent push handling not supported for android");
} else if (action.equals("getAccuracyOptions")) {
Expand Down
23 changes: 13 additions & 10 deletions src/android/wrapper/BluetoothBLE.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package edu.berkeley.eecs.emission.cordova.tracker.wrapper;

import java.util.UUID;

/**
* Created by shankari on 3/30/24.
*/
Expand Down Expand Up @@ -78,17 +76,22 @@ public static BluetoothBLE initRangeUpdate(String uuid, double ts,
return rangeEvent;
}

public static BluetoothBLE initFakeWithEventType(String eventType) {
public static BluetoothBLE initFake(String eventType, String uuid, int major, int minor) {
BluetoothBLE fakeEvent = new BluetoothBLE();
fakeEvent.uuid = UUID.randomUUID().toString();
fakeEvent.major = 4538;
fakeEvent.minor = 1256;
fakeEvent.proximity = "ProximityNear";
fakeEvent.accuracy = 100;
fakeEvent.rssi = 10;

fakeEvent.uuid = uuid;
fakeEvent.eventType = eventType;
fakeEvent.ts = System.currentTimeMillis() / 1000; // time is in seconds for us

// we assume that we don't have major and minor entries for the
// "monitor" responses
if (eventType == "RANGE_UPDATE") {
fakeEvent.major = major;
fakeEvent.minor = minor;
fakeEvent.proximity = "ProximityNear";
fakeEvent.accuracy = (int)(Math.random() * 100);
fakeEvent.rssi = (int)(Math.random() * 10);
}

return fakeEvent;
}
}
1 change: 1 addition & 0 deletions src/ios/BEMDataCollection.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
- (void) setConfig:(CDVInvokedUrlCommand*)command;
- (void) getState:(CDVInvokedUrlCommand*)command;
- (void) forceTransition:(CDVInvokedUrlCommand *)command;
- (void) mockBLEObjects:(CDVInvokedUrlCommand *)command;
- (void) handleSilentPush:(CDVInvokedUrlCommand *)command;
- (void)getAccuracyOptions:(CDVInvokedUrlCommand *)command;

Expand Down
49 changes: 49 additions & 0 deletions src/ios/BEMDataCollection.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#import "BEMDataCollection.h"
#import "LocalNotificationManager.h"
#import "Wrapper/LocationTrackingConfig.h"
#import "Wrapper/BluetoothBLE.h"
#import "BEMAppDelegate.h"
#import "ConfigManager.h"
#import "DataUtils.h"
Expand Down Expand Up @@ -301,6 +302,54 @@ - (void)forceTransition:(CDVInvokedUrlCommand *)command
messageAsString:msg];
[self.commandDelegate sendPluginResult:result callbackId:callbackId];
}
@catch (NSException *exception) {
NSString* msg = [NSString stringWithFormat: @"While getting settings, error %@", exception];
CDVPluginResult* result = [CDVPluginResult
resultWithStatus:CDVCommandStatus_ERROR
messageAsString:msg];
[self.commandDelegate sendPluginResult:result callbackId:callbackId];
}
}

- (void)mockBLEObjects:(CDVInvokedUrlCommand *)command
{
NSString* callbackId = [command callbackId];

@try {
NSString* eventType = [[command arguments] objectAtIndex:0];
NSString* uuid = [[command arguments] objectAtIndex:1];
int major = [[[command arguments] objectAtIndex:2] intValue];
int minor = [[[command arguments] objectAtIndex:3] intValue];
int nObjects = [[[command arguments] objectAtIndex:4] intValue];
for (int i = 0; i < nObjects; i++) {
BluetoothBLE* currWrapper = [[BluetoothBLE new] initFake:@"RANGE_UPDATE" anduuid: uuid andmajor: major andminor: minor];
[[BuiltinUserCache database] putSensorData:@"key.usercache.bluetooth_ble" value:currWrapper];
}
NSArray* justAddedEntries = [[BuiltinUserCache database] getLastSensorData:@"key.usercache.bluetooth_ble"
nEntries:nObjects
wrapperClass:BluetoothBLE.class];
for (int i = 0; i < justAddedEntries.count; i++) {
BluetoothBLE* currEntry = [justAddedEntries objectAtIndex:i];
if (![currEntry.eventType isEqualToString:eventType]) {
NSString* msg = [NSString stringWithFormat: @"%@ found in last %d objects, expected all %@", currEntry.eventType, nObjects, eventType];
CDVPluginResult* result = [CDVPluginResult
resultWithStatus:CDVCommandStatus_ERROR
messageAsString:msg];
[self.commandDelegate sendPluginResult:result callbackId:callbackId];
}
}
CDVPluginResult* result = [CDVPluginResult
resultWithStatus:CDVCommandStatus_OK
messageAsString:eventType];
[self.commandDelegate sendPluginResult:result callbackId:callbackId];
}
@catch (NSException *exception) {
NSString* msg = [NSString stringWithFormat: @"While getting settings, error %@", exception];
CDVPluginResult* result = [CDVPluginResult
resultWithStatus:CDVCommandStatus_ERROR
messageAsString:msg];
[self.commandDelegate sendPluginResult:result callbackId:callbackId];
}
}

- (void)handleSilentPush:(CDVInvokedUrlCommand *)command
Expand Down
2 changes: 1 addition & 1 deletion src/ios/Wrapper/BluetoothBLE.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
@interface BluetoothBLE : NSObject

- (instancetype)initWithCLBeacon:(CLBeacon *)beacon andEventType:(NSString *) eventType;
- (instancetype)initFakeWithEventType:(NSString *)eventType;
- (instancetype)initFake:(NSString *)eventType anduuid:(NSString*) uuid andmajor:(int) major andminor:(int) minor;

// fields from CLBeacon, modified to be easy to serialize and restore
@property NSString* uuid;
Expand Down
20 changes: 12 additions & 8 deletions src/ios/Wrapper/BluetoothBLE.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#import "BluetoothBLE.h"
#import "DataUtils.h"
#import <stdlib.h>

@implementation BluetoothBLE

Expand All @@ -25,17 +26,20 @@ -(id) initWithCLBeacon:(CLBeacon*) beacon andEventType:(NSString*) eventType {
return self;
}

-(id) initFakeWithEventType:(NSString*) eventType {
-(id) initFake:(NSString*) eventType anduuid:(NSString*) uuid andmajor:(int) major andminor:(int)minor {
self = [super init];
self.uuid = [NSUUID UUID].UUIDString;
self.major = 4538;
self.minor = 1256;
self.proximity = [BluetoothBLE proximityToString:CLProximityNear];
self.accuracy = 100;
self.rssi = 10;

self.uuid = uuid;
self.eventType = eventType;
self.ts = [DataUtils dateToTs:[NSDate now]];

if ([eventType isEqualToString:@"RANGE_UPDATE"]) {
self.major = major;
self.minor = minor;
self.proximity = [BluetoothBLE proximityToString:CLProximityNear];
self.accuracy = arc4random_uniform(100);
self.rssi = arc4random_uniform(10);
}

return self;
}

Expand Down
9 changes: 9 additions & 0 deletions www/datacollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,15 @@ var DataCollection = {
exec(resolve, reject, "DataCollection", "forceTransition", [generalTransitionName]);
});
},
mockBLEObjects: function (eventType, uuid, major, minor, nObjects) {
// major and minor are optional, so we check if they are defined and
// put in a default value if they don't this allows us to have a nice
// external interface without running into null pointers internally
return new Promise(function(resolve, reject) {
exec(resolve, reject, "DataCollection", "mockBLEObjects", [eventType, uuid,
major? major : -1, minor? minor: -1, nObjects]);
});
},
handleSilentPush: function() {
return new Promise(function(resolve, reject) {
exec(resolve, reject, "DataCollection", "handleSilentPush",
Expand Down

0 comments on commit 0846678

Please sign in to comment.