diff --git a/plugin.xml b/plugin.xml index 2931f91..3399bf5 100644 --- a/plugin.xml +++ b/plugin.xml @@ -1,7 +1,7 @@ + version="1.7.1"> DataCollection Background data collection FTW! This is the part that I really diff --git a/src/android/verification/SensorControlBackgroundChecker.java b/src/android/verification/SensorControlBackgroundChecker.java index 7fcc429..43ccb73 100644 --- a/src/android/verification/SensorControlBackgroundChecker.java +++ b/src/android/verification/SensorControlBackgroundChecker.java @@ -24,6 +24,10 @@ import org.json.JSONObject; import java.util.Arrays; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import edu.berkeley.eecs.emission.cordova.tracker.Constants; import edu.berkeley.eecs.emission.cordova.tracker.ExplicitIntent; @@ -90,8 +94,7 @@ public static void checkAppState(final Context ctxt) { boolean[] allOtherChecks = new boolean[]{ SensorControlChecks.checkLocationPermissions(ctxt), SensorControlChecks.checkMotionActivityPermissions(ctxt), - SensorControlChecks.checkNotificationsEnabled(ctxt), - SensorControlChecks.checkUnusedAppsUnrestricted(ctxt) + SensorControlChecks.checkNotificationsEnabled(ctxt) }; boolean allOtherChecksPass = true; for (boolean check: allOtherChecks) { @@ -113,14 +116,14 @@ public static void checkAppState(final Context ctxt) { } else if (allOtherChecks[0]) { Log.i(ctxt, TAG, "all checks = "+allOtherChecksPass+" but location permission status "+allOtherChecks[0]+" should be true "+ - " so one of the non-location checks must be false: loc permission, motion permission, notification, unused apps" + Arrays.toString(allOtherChecks)); + " so one of the non-location checks must be false: loc permission, motion permission, notification" + Arrays.toString(allOtherChecks)); Log.i(ctxt, TAG, "a non-local check failed, generating only user visible notification"); generateOpenAppSettingsNotification(ctxt); } else { Log.i(ctxt, TAG, "location settings are valid, but location permission is not, generating tracking error and visible notification"); Log.i(ctxt, TAG, "curr status check results = " + - " loc permission, motion permission, notification, unused apps "+ Arrays.toString(allOtherChecks)); + " loc permission, motion permission, notification "+ Arrays.toString(allOtherChecks)); ctxt.sendBroadcast(new ExplicitIntent(ctxt, R.string.transition_tracking_error)); generateOpenAppSettingsNotification(ctxt); } @@ -130,6 +133,27 @@ else if (allOtherChecks[0]) { generateOpenAppSettingsNotification(ctxt); } }); + + /* + * AsyncTask is deprecated, so let's try to use the standard concurrent utilities here. + * Haven't used raw java concurrent utilities for 20 years (new Thread(...)) anyone? + * So this code snippet is based on + * https://stackoverflow.com/a/64969640/4040267 + * + * Do we need to do anything in the UI thread. The `checkUnusedAppsUnrestricted` + * doesn't say anything about which thread to call it from. What about + * generateOpenAppSettingsNotification? Nothing in the NotificationManager indicates that + * it needs to run on the UI thread either. + */ + ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); + + executor.schedule(() -> { + if (!SensorControlChecks.checkUnusedAppsUnrestricted(ctxt)) { + Log.i(ctxt, TAG, "all current settings and permissions are probably valid, but could be reset later"); + Log.i(ctxt, TAG, "don't generate a tracking error right now, but let's ask the user to avoid the reset "); + generateOpenAppSettingsNotification(ctxt); + } + }, 1, TimeUnit.MINUTES); } public static void generateOpenAppSettingsNotification(Context ctxt) { diff --git a/src/android/verification/SensorControlChecks.java b/src/android/verification/SensorControlChecks.java index 40e8fc7..855ea1d 100644 --- a/src/android/verification/SensorControlChecks.java +++ b/src/android/verification/SensorControlChecks.java @@ -105,7 +105,9 @@ public static boolean checkNotificationsUnpaused(final Context ctxt) { public static boolean checkUnusedAppsUnrestricted(final Context ctxt) { ListenableFuture future = PackageManagerCompat.getUnusedAppRestrictionsStatus(ctxt); try { + Log.i(ctxt, TAG, "About to call future.get to read the restriction status"); Integer appRestrictionStatus = future.get(); + Log.i(ctxt, TAG, "Received "+appRestrictionStatus+" from future.get"); switch(appRestrictionStatus) { case UnusedAppRestrictionsConstants.ERROR: return false; case UnusedAppRestrictionsConstants.FEATURE_NOT_AVAILABLE: return true; @@ -116,8 +118,10 @@ public static boolean checkUnusedAppsUnrestricted(final Context ctxt) { return false; } } catch (ExecutionException | InterruptedException e) { + Log.e(ctxt, TAG, "Got exception from future.get" + e); return false; } + Log.e(ctxt, TAG, "Random final false"); return false; } } diff --git a/src/android/verification/SensorControlForegroundDelegate.java b/src/android/verification/SensorControlForegroundDelegate.java index b7cf3db..0905af9 100644 --- a/src/android/verification/SensorControlForegroundDelegate.java +++ b/src/android/verification/SensorControlForegroundDelegate.java @@ -28,6 +28,7 @@ import android.content.IntentSender; import android.content.pm.PackageManager; import android.net.Uri; +import android.os.AsyncTask; import android.os.Build; import android.provider.Settings; @@ -552,12 +553,17 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { case SensorControlConstants.REMOVE_UNUSED_APP_RESTRICTIONS: Log.d(mAct, TAG, requestCode + " is our code, handling callback"); Log.d(mAct, TAG, "Got unused app restrictions callback from launching app settings"); + AsyncTask.execute(new Runnable() { + @Override + public void run() { if (SensorControlChecks.checkUnusedAppsUnrestricted(cordova.getActivity())) { - SensorControlBackgroundChecker.restartFSMIfStartState(cordova.getActivity()); + // SensorControlBackgroundChecker.restartFSMIfStartState(cordova.getActivity()); cordovaCallback.success(); } else { cordovaCallback.error(cordova.getActivity().getString(R.string.unused_apps_restricted)); } + } + }); break; default: Log.d(cordova.getActivity(), TAG, "Got unsupported request code " + requestCode + " , ignoring...");