Skip to content

Commit

Permalink
Merge branch 'master' into fix_foreground_service
Browse files Browse the repository at this point in the history
  • Loading branch information
shankari committed Oct 7, 2024
2 parents 9bd16b4 + dcc4853 commit b0850bf
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 49 deletions.
2 changes: 1 addition & 1 deletion plugin.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
id="cordova-plugin-em-datacollection"
version="1.8.9">
version="1.9.1">

<name>DataCollection</name>
<description>Background data collection FTW! This is the part that I really
Expand Down
3 changes: 2 additions & 1 deletion src/android/location/TripDiaryStateMachineService.java
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,8 @@ public void handleTripStart(Context ctxt, final String actionString) {
if (isFleet) {
Log.d(this, TAG, "Found beacon in fleet mode, starting location tracking");
} else {
Log.e(this, TAG, "Found beacon in non-fleet mode, not sure why this happened, starting location tracking anyway");
Log.e(this, TAG, "ERROR: Found beacon in non-fleet mode, not starting location tracking");
return;
}
}

Expand Down
41 changes: 35 additions & 6 deletions src/android/location/TripDiaryStateMachineServiceOngoing.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
import java.util.LinkedList;
import java.util.List;

import org.json.JSONException;
import org.json.JSONObject;

import edu.berkeley.eecs.emission.cordova.tracker.ConfigManager;
import edu.berkeley.eecs.emission.cordova.unifiedlogger.NotificationHelper;
import edu.berkeley.eecs.emission.R;
Expand Down Expand Up @@ -48,6 +51,8 @@ public class TripDiaryStateMachineServiceOngoing extends Service {
private String mTransition = null;
private SharedPreferences mPrefs = null;
private ForegroundServiceComm mComm = null;
private JSONObject config;
private boolean isFleet = false;

public TripDiaryStateMachineServiceOngoing() {
super();
Expand All @@ -57,6 +62,16 @@ public TripDiaryStateMachineServiceOngoing() {
public void onCreate() {
Log.i(this, TAG, "Service created. Initializing one-time variables!");
mComm = new ForegroundServiceComm(this);

try {
JSONObject c = (JSONObject) UserCacheFactory.getUserCache(this).getDocument("config/app_ui_config", false);
config = c;
isFleet = (config != null && config.has("tracking") && config.getJSONObject("tracking").getBoolean("bluetooth_only"));
} catch (JSONException e) {
Log.d(this, TAG, "Error reading config! " + e);
// TODO: Need to figure out what to do about the fleet flag when the config is invalid
// Original implementation by @louisg1337 had isFleet = true in that case (location tracking would not stop)
}
}

@Override
Expand Down Expand Up @@ -158,9 +173,17 @@ private void handleStart(Context ctxt, String actionString) {
Log.d(this, TAG, "TripDiaryStateMachineReceiver handleStarted(" + actionString + ") called");
// Get current location
if (actionString.equals(ctxt.getString(R.string.transition_initialize)) &&
!mCurrState.equals(ctxt.getString(R.string.state_tracking_stopped))) {
startEverything(ctxt, actionString);
}
!mCurrState.equals(ctxt.getString(R.string.state_tracking_stopped))) {
if (isFleet) {
// Start up the bluetooth service to check for beacons
Intent foregroundStartBluetooth = new Intent(ctxt, TripDiaryStateMachineForegroundService.class);
foregroundStartBluetooth.setAction("foreground_start_bluetooth");
ctxt.startService(foregroundStartBluetooth);
setNewState(ctxt.getString(R.string.state_waiting_for_trip_start));
} else {
startEverything(ctxt, actionString);
}
}
if (actionString.equals(ctxt.getString(R.string.transition_stop_tracking))) {
// Haven't started anything yet (that's why we are in the start state).
// just move to the stop tracking state
Expand All @@ -185,9 +208,11 @@ private void handleStart(Context ctxt, String actionString) {
// If we stop tracking, we stop everything
// For everything else, go to the ongoing state :)
private void handleWaitingForTripStart(final Context ctxt, final String actionString) {
if (actionString.equals(getString(R.string.transition_exited_geofence))) {
if (actionString.equals(getString(R.string.transition_exited_geofence)) && !isFleet) {
startEverything(ctxt, actionString);
} else if (actionString.equals(getString(R.string.transition_start_tracking))) {
} else if (actionString.equals(ctxt.getString(R.string.transition_ble_beacon_found)) && isFleet) {
startEverything(ctxt, actionString);
} else if (actionString.equals(getString(R.string.transition_start_tracking)) && !isFleet) {
startEverything(ctxt, actionString);
} else if (actionString.equals(ctxt.getString(R.string.transition_stop_tracking))) {
// Haven't started anything yet (that's why we are in the start state).
Expand Down Expand Up @@ -220,7 +245,11 @@ private void handleOngoing(Context ctxt, String actionString) {
private void handleTrackingStopped(final Context ctxt, String actionString) {
Log.d(this, TAG, "TripDiaryStateMachineReceiver handleTrackingStopped(" + actionString + ") called");
if (actionString.equals(ctxt.getString(R.string.transition_start_tracking))) {
startEverything(ctxt, actionString);
if (isFleet) {
setNewState(ctxt.getString(R.string.state_waiting_for_trip_start));
} else {
startEverything(ctxt, actionString);
}
}
if (actionString.equals(ctxt.getString(R.string.transition_tracking_error))) {
Log.i(this, TAG, "Tracking manually turned off, no need to prompt for location");
Expand Down
99 changes: 58 additions & 41 deletions src/ios/Location/TripDiaryStateMachine.m
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ - (id) init {
// currently only in `BEMDataCollection initWithConsent`
// https://github.com/e-mission/e-mission-docs/issues/735#issuecomment-1179774103

if (![ConfigManager instance].is_duty_cycling && self.currState != kTrackingStoppedState) {
if (![ConfigManager instance].is_duty_cycling && self.currState != kTrackingStoppedState && !self.isFleet) {
/* If we are not using geofencing, and the tracking is not manually turned off, then we don't need to listen
to any transitions. We just turn on the tracking here and never stop. Turning off all transitions makes
it easier for us to ignore silent push as well as the transitions generated from here.
Expand Down Expand Up @@ -240,7 +240,7 @@ -(void) handleStart:(NSString*) transition withUserInfo:(NSDictionary*) userInfo
// Start location services so that we can get the current location
// We will receive the first location asynchronously
[TripDiaryActions createGeofenceHere:self.locMgr withGeofenceLocator:_geofenceLocator inState:self.currState];
} else {
} else if (!self.isFleet) {
// Technically, we don't need this since we move to the ongoing state in the init code.
// but if tracking is stopped, we can skip that, and then if we turn it on again, we
// need to turn everything on here as well
Expand All @@ -253,17 +253,17 @@ -(void) handleStart:(NSString*) transition withUserInfo:(NSDictionary*) userInfo
object:CFCTransitionNOP];
} else if ([transition isEqualToString:CFCTransitionBeaconFound]) {
if (self.isFleet) {
NSLog(@"Got transition %@ in state %@ with fleet mode, starting location tracking",
transition,
[TripDiaryStateMachine getStateName:self.currState]);
[LocalNotificationManager addNotification:[NSString stringWithFormat:
@"Got transition %@ in state %@ with fleet mode, starting location tracking",
transition,
[TripDiaryStateMachine getStateName:self.currState]]];
[TripDiaryActions startTracking:transition withLocationMgr:self.locMgr];
[TripDiaryActions deleteGeofence:self.locMgr];
} else {
NSLog(@"Got transition %@ in state %@ with fleet mode, not sure why this happened, starting location tracking anyway",
transition,
[TripDiaryStateMachine getStateName:self.currState]);
[TripDiaryActions startTracking:transition withLocationMgr:self.locMgr];
[TripDiaryActions deleteGeofence:self.locMgr];
[LocalNotificationManager addNotification:[NSString stringWithFormat:
@"ERROR: Got transition %@ in state %@ without fleet mode",
transition,
[TripDiaryStateMachine getStateName:self.currState]]];

}
[[NSNotificationCenter defaultCenter] postNotificationName:CFCTransitionNotificationName
Expand All @@ -281,13 +281,15 @@ -(void) handleStart:(NSString*) transition withUserInfo:(NSDictionary*) userInfo
[self setState:kStartState withChecks:FALSE];
} else if ([transition isEqualToString:CFCTransitionExitedGeofence]) {
if (self.isFleet) {
NSLog(@"Got transition %@ in state %@ with fleet mode, checking for beacons before starting location tracking",
transition,
[TripDiaryStateMachine getStateName:self.currState]);
[LocalNotificationManager addNotification:[NSString stringWithFormat:
@"Got transition %@ in state %@ with fleet mode, checking for beacons before starting location tracking",
transition,
[TripDiaryStateMachine getStateName:self.currState]]];
} else {
NSLog(@"Got transition %@ in state %@ in non-fleet mode, starting location tracking",
transition,
[TripDiaryStateMachine getStateName:self.currState]);
[LocalNotificationManager addNotification:[NSString stringWithFormat:
@"Got transition %@ in state %@ in non-fleet mode, starting location tracking",
transition,
[TripDiaryStateMachine getStateName:self.currState]]];
// We first start tracking and then delete the geofence to make sure that we are always tracking something
[TripDiaryActions startTracking:transition withLocationMgr:self.locMgr];
[TripDiaryActions deleteGeofence:self.locMgr];
Expand Down Expand Up @@ -331,13 +333,15 @@ - (void) handleWaitingForTripStart:(NSString*) transition withUserInfo:(NSDicti
*/

if (self.isFleet) {
NSLog(@"Got transition %@ in state %@ with fleet mode, checking for beacons before starting location tracking",
transition,
[TripDiaryStateMachine getStateName:self.currState]);
[LocalNotificationManager addNotification:[NSString stringWithFormat:
@"Got transition %@ in state %@ with fleet mode, checking for beacons before starting location tracking",
transition,
[TripDiaryStateMachine getStateName:self.currState]]];
} else {
NSLog(@"Got transition %@ in state %@ in non-fleet mode, starting location tracking",
transition,
[TripDiaryStateMachine getStateName:self.currState]);
[LocalNotificationManager addNotification:[NSString stringWithFormat:
@"Got transition %@ in state %@ in non-fleet mode, starting location tracking",
transition,
[TripDiaryStateMachine getStateName:self.currState]]];
// We first start tracking and then delete the geofence to make sure that we are always tracking something
[TripDiaryActions startTracking:transition withLocationMgr:self.locMgr];
[TripDiaryActions deleteGeofence:self.locMgr];
Expand All @@ -347,29 +351,36 @@ - (void) handleWaitingForTripStart:(NSString*) transition withUserInfo:(NSDicti
}
} else if ([transition isEqualToString:CFCTransitionBeaconFound]) {
if (self.isFleet) {
NSLog(@"Got transition %@ in state %@ with fleet mode, starting location tracking",
transition,
[TripDiaryStateMachine getStateName:self.currState]);
[LocalNotificationManager addNotification:[NSString stringWithFormat:
@"Got transition %@ in state %@ with fleet mode, starting location tracking",
transition,
[TripDiaryStateMachine getStateName:self.currState]]];
[TripDiaryActions startTracking:transition withLocationMgr:self.locMgr];
[TripDiaryActions deleteGeofence:self.locMgr];
} else {
NSLog(@"Got transition %@ in state %@ with fleet mode, not sure why this happened, starting location tracking anyway",
transition,
[TripDiaryStateMachine getStateName:self.currState]);
[TripDiaryActions startTracking:transition withLocationMgr:self.locMgr];
[TripDiaryActions deleteGeofence:self.locMgr];
[LocalNotificationManager addNotification:[NSString stringWithFormat:
@"ERROR: Got transition %@ in state %@ without fleet mode",
transition,
[TripDiaryStateMachine getStateName:self.currState]]];

}
[[NSNotificationCenter defaultCenter] postNotificationName:CFCTransitionNotificationName
object:CFCTransitionTripStarted];

} else if ([transition isEqualToString:CFCTransitionVisitEnded]) {
if ([ConfigManager instance].ios_use_visit_notifications_for_detection) {
// We first start tracking and then delete the geofence to make sure that we are always tracking something
[TripDiaryActions startTracking:transition withLocationMgr:self.locMgr];
[TripDiaryActions deleteGeofence:self.locMgr];
[[NSNotificationCenter defaultCenter] postNotificationName:CFCTransitionNotificationName
object:CFCTransitionTripStarted];
if (!self.isFleet) {
// We first start tracking and then delete the geofence to make sure that we are always tracking something
[TripDiaryActions startTracking:transition withLocationMgr:self.locMgr];
[TripDiaryActions deleteGeofence:self.locMgr];
[[NSNotificationCenter defaultCenter] postNotificationName:CFCTransitionNotificationName
object:CFCTransitionTripStarted];
} else {
[LocalNotificationManager addNotification:[NSString stringWithFormat:
@"Got transition %@ in state %@ with fleet mode, ignoring, no beacon found",
transition,
[TripDiaryStateMachine getStateName:self.currState]]];
}
}
} else if ([transition isEqualToString:CFCTransitionTripStarted]) {
[self setState:kOngoingTripState withChecks:TRUE];
Expand Down Expand Up @@ -446,8 +457,10 @@ - (void) handleOngoingTrip:(NSString*) transition withUserInfo:(NSDictionary*) u
}
} else if ([transition isEqualToString:CFCTransitionTripEndDetected]) {
if (self.isFleet) {
NSLog(@"Got transition %@ in state %@ with fleet mode, still seeing beacon but no location updates, ignoring",
transition, [TripDiaryStateMachine getStateName:self.currState]);
[LocalNotificationManager addNotification:[NSString stringWithFormat:
@"Got transition %@ in state %@ with fleet mode, still seeing beacon but no location updates, ignoring",
transition,
[TripDiaryStateMachine getStateName:self.currState]]];
} else {
[TripDiaryActions createGeofenceHere:self.locMgr withGeofenceLocator:_geofenceLocator inState:self.currState];
}
Expand All @@ -461,14 +474,18 @@ - (void) handleOngoingTrip:(NSString*) transition withUserInfo:(NSDictionary*) u
// on the other hand, maybe createGeofence will find that we are outside the geofence, so will generate CFCTransitionTripRestarted
// so let's try to create the geofence here for consistency, but also force the EndTripTracking
if (self.isFleet) {
NSLog(@"Got transition %@ in state %@ with fleet mode, beacon is gone, we need to stop tracking",
transition, [TripDiaryStateMachine getStateName:self.currState]);
[LocalNotificationManager addNotification:[NSString stringWithFormat:
@"Got transition %@ in state %@ with fleet mode, beacon is gone, we need to stop tracking",
transition,
[TripDiaryStateMachine getStateName:self.currState]]];
[TripDiaryActions createGeofenceHere:self.locMgr withGeofenceLocator:_geofenceLocator inState:self.currState];
[[NSNotificationCenter defaultCenter] postNotificationName:CFCTransitionNotificationName
object:CFCTransitionEndTripTracking];
} else {
NSLog(@"Got transition %@ in state %@ with non-fleet mode, beacon is gone, ignoring",
transition, [TripDiaryStateMachine getStateName:self.currState]);
[LocalNotificationManager addNotification:[NSString stringWithFormat:
@"Got transition %@ in state %@ with non-fleet mode, beacon is gone, ignoring",
transition,
[TripDiaryStateMachine getStateName:self.currState]]];
}
} else if ([transition isEqualToString:CFCTransitionEndTripTracking]) {
// [TripDiaryActions pushTripToServer];
Expand Down

0 comments on commit b0850bf

Please sign in to comment.