Skip to content

Commit

Permalink
Merge pull request #224 from shankari/hack_work_profile
Browse files Browse the repository at this point in the history
👷🔧 🪠 Plumb through support for requesting bluetooth scan permissions …
  • Loading branch information
shankari authored Apr 15, 2024
2 parents a83ae18 + 32a9b92 commit 7c8b7fa
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 55 deletions.
16 changes: 8 additions & 8 deletions src/android/DataCollectionPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,6 @@ public void pluginInitialize() {
new StatsEvent(myActivity, R.string.app_launched));

TripDiaryStateMachineReceiver.initOnUpgrade(myActivity);

// Ask for bluetooth permissions
// We will change this with future releases, we just ran out of time implementing this into the front end
mControlDelegate.checkAndPromptBluetoothScanPermissions();
}

@Override
Expand Down Expand Up @@ -125,6 +121,14 @@ public boolean execute(String action, JSONArray data, final CallbackContext call
Log.d(cordova.getActivity(), TAG, "checking fitness permissions");
mControlDelegate.checkMotionActivityPermissions(callbackContext);
return true;
} else if (action.equals("fixBluetoothPermissions")) {
Log.d(cordova.getActivity(), TAG, "fixing bluetooth permissions");
mControlDelegate.checkAndPromptBluetoothScanPermissions(callbackContext);
return true;
} else if (action.equals("isValidBluetoothPermissions")) {
Log.d(cordova.getActivity(), TAG, "checking bluetooth permissions");
mControlDelegate.checkBluetoothPermissions(callbackContext);
return true;
} else if (action.equals("fixShowNotifications")) {
Log.d(cordova.getActivity(), TAG, "fixing notification enable");
mControlDelegate.checkAndPromptShowNotificationsEnabled(callbackContext);
Expand Down Expand Up @@ -153,10 +157,6 @@ public boolean execute(String action, JSONArray data, final CallbackContext call
Log.d(cordova.getActivity(), TAG, "checking ignored battery optimizations");
mControlDelegate.checkIgnoreBatteryOptimizations(callbackContext);
return true;
} else if (action.equals("bluetoothScanPermissions")) {
Log.d(cordova.getActivity(), TAG, "requesting bluetooth scan permissions");
mControlDelegate.checkAndPromptBluetoothScanPermissions(callbackContext);
return true;
} else if (action.equals("storeBatteryLevel")) {
Context ctxt = cordova.getActivity();
TripDiaryStateMachineReceiver.saveBatteryAndSimulateUser(ctxt);
Expand Down
22 changes: 19 additions & 3 deletions src/android/verification/SensorControlBackgroundChecker.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package edu.berkeley.eecs.emission.cordova.tracker.verification;
// Auto fixed by post-plugin hook
package edu.berkeley.eecs.emission.cordova.tracker.verification;
// Auto fixed by post-plugin hook
import edu.berkeley.eecs.emission.R;
// Auto fixed by post-plugin hook

// Auto fixed by post-plugin hook
import android.app.PendingIntent;
import android.content.Context;
Expand Down Expand Up @@ -35,6 +37,7 @@
import edu.berkeley.eecs.emission.cordova.tracker.location.actions.LocationTrackingActions;
import edu.berkeley.eecs.emission.cordova.unifiedlogger.Log;
import edu.berkeley.eecs.emission.cordova.unifiedlogger.NotificationHelper;
import edu.berkeley.eecs.emission.cordova.usercache.UserCacheFactory;



Expand Down Expand Up @@ -89,6 +92,15 @@ public static void checkAppState(final Context ctxt) {
// requests here.
Log.i(ctxt, TAG, "All settings are valid, checking current state");
Log.i(ctxt, TAG, "Current location settings are "+response);
boolean isFleet = false;
try {
JSONObject config = (JSONObject) UserCacheFactory.getUserCache(ctxt).getDocument("config/app_ui_config", false);
isFleet = (config != null && config.has("tracking") && config.getJSONObject("tracking").getBoolean("bluetooth_only"));
} catch (JSONException e) {
Log.d(ctxt, 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)
}

// Now that we know that the location settings are correct, we start the permission checks
boolean[] allOtherChecks = new boolean[]{
Expand All @@ -100,7 +112,11 @@ public static void checkAppState(final Context ctxt) {
boolean allOtherChecksPass = true;
for (boolean check: allOtherChecks) {
allOtherChecksPass = allOtherChecksPass && check;
}
}
if (isFleet) {
allOtherChecksPass = allOtherChecksPass &&
SensorControlChecks.checkBluetoothPermissions(ctxt);
}

/*
Using index-based iteration since we need to start from index 1 instead of 0 and array slices
Expand Down
10 changes: 10 additions & 0 deletions src/android/verification/SensorControlChecks.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,16 @@ public static boolean checkMotionActivityPermissions(final Context ctxt) {
return version29Check || permCheck;
}

// TODO: Figure out how to integrate this with the background code
// https://github.com/e-mission/e-mission-docs/issues/680#issuecomment-953403832
public static boolean checkBluetoothPermissions(final Context ctxt) {
// apps before version 31 did not need to prompt for bluetooth permissions
boolean version32Check = Build.VERSION.SDK_INT < Build.VERSION_CODES.S;
boolean permCheck = ContextCompat.checkSelfPermission(ctxt, SensorControlConstants.BLUETOOTH_SCAN) == PermissionChecker.PERMISSION_GRANTED;
Log.i(ctxt, TAG, "version32Check "+version32Check+" permCheck "+permCheck+" retVal = "+(version32Check || permCheck));
return version32Check || permCheck;
}

public static boolean checkNotificationsEnabled(final Context ctxt) {
NotificationManagerCompat nMgr = NotificationManagerCompat.from(ctxt);
boolean appDisabled = nMgr.areNotificationsEnabled();
Expand Down
60 changes: 21 additions & 39 deletions src/android/verification/SensorControlForegroundDelegate.java
Original file line number Diff line number Diff line change
Expand Up @@ -420,17 +420,24 @@ public void checkAndPromptLocationPermissions(CallbackContext cordovaCallback) {
}
}

public void checkBluetoothPermissions(CallbackContext cordovaCallback) {
boolean validPerms = SensorControlChecks.checkBluetoothPermissions(cordova.getActivity());
if(validPerms) {
cordovaCallback.success();
} else {
cordovaCallback.error(cordova.getActivity().getString(R.string.activity_permission_off));
}
}

/**
* Check to see if the user has the ability to scan for bluetooth devices, if not prompt them asking for it.
*
* @param cordovaCallback
*/
public void checkAndPromptBluetoothScanPermissions(CallbackContext cordovaCallback) {
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.S){
Log.d(cordova.getActivity(), TAG, "Older build version than API 31, return success!");
cordovaCallback.success();
} else if (cordova.hasPermission(SensorControlConstants.BLUETOOTH_SCAN)){
Log.d(cordova.getActivity(), TAG, "User has already enabled bluetooth scan!");
boolean validPerms = SensorControlChecks.checkBluetoothPermissions(cordova.getActivity());
if(validPerms) {
SensorControlBackgroundChecker.restartFSMIfStartState(cordova.getActivity());
cordovaCallback.success();
} else {
Log.d(cordova.getActivity(), TAG, "User has not enabled bluetooth scan, requesting now...");
Expand All @@ -444,25 +451,6 @@ public void checkAndPromptBluetoothScanPermissions(CallbackContext cordovaCallba
}
}

/**
* Overloaded version of function aboe so we can use on native side.
*/
public void checkAndPromptBluetoothScanPermissions() {
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.S){
Log.d(cordova.getActivity(), TAG, "Older build version than API 31, return success!");
} else if (cordova.hasPermission(SensorControlConstants.BLUETOOTH_SCAN)){
Log.d(cordova.getActivity(), TAG, "User has already enabled bluetooth scan!");
} else {
Log.d(cordova.getActivity(), TAG, "User has not enabled bluetooth scan, requesting now...");
this.permissionChecker = getPermissionChecker(
SensorControlConstants.ENABLE_BLUETOOTH_SCAN,
SensorControlConstants.BLUETOOTH_SCAN,
"Please enable \'Nearby devices\' permission to use the scanner.",
"Please enable \'Nearby devices\' permission to use the scanner.");
this.permissionChecker.requestPermission();
}
}

public void checkMotionActivityPermissions(CallbackContext cordovaCallback) {
boolean validPerms = SensorControlChecks.checkMotionActivityPermissions(cordova.getActivity());
if(validPerms) {
Expand Down Expand Up @@ -775,6 +763,15 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
}
permissionChecker = null;
break;
case SensorControlConstants.ENABLE_BLUETOOTH_SCAN:
if (SensorControlChecks.checkBluetoothPermissions(cordova.getActivity())) {
SensorControlBackgroundChecker.restartFSMIfStartState(cordova.getActivity());
cordovaCallback.success();
} else {
permissionChecker.generateErrorCallback();
}
permissionChecker = null;
break;
case SensorControlConstants.ENABLE_NOTIFICATIONS:
Log.d(mAct, TAG, requestCode + " is our code, handling callback");
Log.d(mAct, TAG, "Got notification callback from launching app settings");
Expand Down Expand Up @@ -814,21 +811,6 @@ public void run() {
}
}
});
case SensorControlConstants.ENABLE_BLUETOOTH_SCAN:
if (cordovaCallback == null) {
break;
}

Log.d(mAct, TAG, requestCode + " is our code, handling callback");
Log.d(mAct, TAG, "Got bluetooth callback from launching app settings");
if (cordova.hasPermission(SensorControlConstants.BLUETOOTH_SCAN)) {
Log.d(mAct, TAG, "Bluetooth permissions are allowed after settings page opened!");
cordovaCallback.success();
} else {
Log.d(mAct, TAG, "Bluetooth permissions are NOT allowed after settings page opened!");
cordovaCallback.error("Please enable \'Nearby devices\' permission to use the scanner.");
}
break;
default:
Log.d(cordova.getActivity(), TAG, "Got unsupported request code " + requestCode + " , ignoring...");
}
Expand Down
15 changes: 10 additions & 5 deletions www/datacollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,6 @@ var DataCollection = {
exec(resolve, reject, "DataCollection", "isValidLocationPermissions", []);
});
},
bluetoothScanPermissions: function () {
return new Promise(function(resolve, reject) {
exec(resolve, reject, "DataCollection", "bluetoothScanPermissions", []);
});
},
fixFitnessPermissions: function () {
return new Promise(function(resolve, reject) {
exec(resolve, reject, "DataCollection", "fixFitnessPermissions", []);
Expand All @@ -56,6 +51,16 @@ var DataCollection = {
exec(resolve, reject, "DataCollection", "isValidFitnessPermissions", []);
});
},
fixBluetoothPermissions: function () {
return new Promise(function(resolve, reject) {
exec(resolve, reject, "DataCollection", "fixBluetoothPermissions", []);
});
},
isValidBluetoothPermissions: function () {
return new Promise(function(resolve, reject) {
exec(resolve, reject, "DataCollection", "isValidBluetoothPermissions", []);
});
},
fixShowNotifications: function () {
return new Promise(function(resolve, reject) {
exec(resolve, reject, "DataCollection", "fixShowNotifications", []);
Expand Down

0 comments on commit 7c8b7fa

Please sign in to comment.