diff --git a/plugin.xml b/plugin.xml index 8b2275c..fd645ad 100644 --- a/plugin.xml +++ b/plugin.xml @@ -1,7 +1,7 @@ + version="1.8.7"> DataCollection Background data collection FTW! This is the part that I really diff --git a/src/android/verification/SensorControlChecks.java b/src/android/verification/SensorControlChecks.java index be5eecb..e22db76 100644 --- a/src/android/verification/SensorControlChecks.java +++ b/src/android/verification/SensorControlChecks.java @@ -8,6 +8,8 @@ import android.os.Build; import android.os.PowerManager; import android.content.pm.PackageManager; +import android.app.admin.DevicePolicyManager; +import android.content.ComponentName; import androidx.annotation.RequiresApi; import androidx.core.app.NotificationManagerCompat; @@ -113,15 +115,43 @@ public static boolean checkNotificationsUnpaused(final Context ctxt) { } return appUnpaused; } + + /** + * Check if the app is installed on a work profile. + * + * We need this check as Android automatically exempts apps installed on a workprofile from hibernation. + * This means that the "Pause app activity if unused" option is greyed out, which blocks users from continuing + * past the permissions screen. + */ + public static boolean checkWorkProfile(final Context ctxt) { + DevicePolicyManager devicePolicyManager = (DevicePolicyManager) ctxt.getSystemService(ctxt.DEVICE_POLICY_SERVICE); + List activeAdmins = devicePolicyManager.getActiveAdmins(); + boolean workProfile = false; + if (activeAdmins != null){ + for (ComponentName admin : activeAdmins){ + String packageName = admin.getPackageName(); + boolean profileOwner = devicePolicyManager.isProfileOwnerApp(packageName); + Log.d(ctxt, TAG, "admin: " + packageName + " profile: " + profileOwner); + if (profileOwner){ + workProfile = true; + } + } + } + return workProfile; + } public static boolean checkUnusedAppsUnrestricted(final Context ctxt) { - ListenableFuture future = PackageManagerCompat.getUnusedAppRestrictionsStatus(ctxt); + // Check to see if we are on a work profile first + if (checkWorkProfile(ctxt)){ + return true; + } + 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 true; + case UnusedAppRestrictionsConstants.ERROR: return false; case UnusedAppRestrictionsConstants.FEATURE_NOT_AVAILABLE: return true; case UnusedAppRestrictionsConstants.DISABLED: return true; case UnusedAppRestrictionsConstants.API_30_BACKPORT: