Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b631c17b authored by Eugene Susla's avatar Eugene Susla
Browse files

Treat first boot time as a usage event

This allows us to not rely on usage data being backed up/restored

Test: presubmit
Bug: 153607914
Change-Id: I66d5c255eb09e0e8c8e2cc22cea85e31ffebe466
parent 97aaeaf9
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.content.pm.PackageManager.FLAG_PERMISSION_AUTO_REVOKED
import android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET
import android.content.pm.PackageManager.PERMISSION_GRANTED
@@ -54,6 +55,7 @@ import android.provider.DeviceConfig
import android.provider.Settings
import android.util.Log
import androidx.annotation.MainThread
import androidx.preference.PreferenceManager
import com.android.permissioncontroller.Constants
import com.android.permissioncontroller.Constants.ACTION_MANAGE_AUTO_REVOKE
import com.android.permissioncontroller.Constants.AUTO_REVOKE_NOTIFICATION_ID
@@ -119,6 +121,8 @@ private fun getCheckFrequencyMs(context: Context) = when {
private val SERVER_LOG_ID =
    PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_UNUSED_APP_PERMISSION_REVOKED

private val PREF_KEY_FIRST_BOOT_TIME = "first_boot_time"

fun isAutoRevokeEnabled(context: Context): Boolean {
    return getCheckFrequencyMs(context) > 0 &&
            getUnusedThresholdMs(context) > 0 &&
@@ -131,6 +135,9 @@ fun isAutoRevokeEnabled(context: Context): Boolean {
class AutoRevokeOnBootReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent?) {
        // Init firstBootTime
        val firstBootTime = context.firstBootTime

        if (DEBUG) {
            Log.i(LOG_TAG, "scheduleAutoRevokePermissions " +
                "with frequency ${getCheckFrequencyMs(context)}ms " +
@@ -171,6 +178,7 @@ private suspend fun revokePermissionsOnUnusedApps(context: Context):
    }

    val now = System.currentTimeMillis()
    val firstBootTime = context.firstBootTime

    val unusedApps = AllPackageInfosLiveData.getInitializedValue(staleOk = true).toMutableMap()

@@ -193,6 +201,9 @@ private suspend fun revokePermissionsOnUnusedApps(context: Context):
            // Limit by install time
            lastTimeVisible = Math.max(lastTimeVisible, packageInfo.firstInstallTime)

            // Limit by first boot time
            lastTimeVisible = Math.max(lastTimeVisible, firstBootTime)

            // Handle cross-profile apps
            if (context.isPackageCrossProfile(pkgName)) {
                for ((otherUser, otherStats) in userStats) {
@@ -374,6 +385,21 @@ private fun Context.forParentUser(): Context {

private inline fun <reified T> Context.getSystemService() = getSystemService(T::class.java)!!

val Context.sharedPreferences: SharedPreferences get() {
    return PreferenceManager.getDefaultSharedPreferences(this)
}

private val Context.firstBootTime: Long get() {
    var time = sharedPreferences.getLong(PREF_KEY_FIRST_BOOT_TIME, -1L)
    if (time > 0) {
        return time
    }
    // This is the first boot
    time = System.currentTimeMillis()
    sharedPreferences.edit().putLong(PREF_KEY_FIRST_BOOT_TIME, time).apply()
    return time
}

/**
 * A job to check for apps unused in the last [getUnusedThresholdMs]ms every
 * [getCheckFrequencyMs]ms and [revokePermissionsOnUnusedApps] for them