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

Commit bcb4ad88 authored by Philip P. Moltmann's avatar Philip P. Moltmann
Browse files

Listen to real app-ops + small bug fixes

Bug: 162547999
Test: Starte phone call and launched ReviewOngoingUsageFragment
Change-Id: I57a9c269303769769f9debbe227b153d78abc61e
parent aae32ffb
Loading
Loading
Loading
Loading
+20 −17
Original line number Diff line number Diff line
@@ -17,10 +17,9 @@
package com.android.permissioncontroller.permission.data

import android.app.AppOpsManager
import android.app.AppOpsManager.OP_FLAGS_ALL
import android.app.AppOpsManager.OP_FLAGS_ALL_TRUSTED
import android.app.Application
import android.os.UserHandle
import android.util.Log
import com.android.permissioncontroller.PermissionControllerApplication
import kotlinx.coroutines.Job
import java.util.function.Consumer
@@ -28,14 +27,17 @@ import java.util.function.Consumer
/**
 * LiveData that loads the last usage of each of a list of app ops for every package.
 *
 * <p>For app-ops with duration the end of the access is considered.
 *
 * @param app The current application
 * @param opNames The names of the app ops we wish to search for
 * @param
 * @param usageDurationMs how much ago can an access have happened to be considered
 */
// TODO: listen for updates
class OpUsageLiveData(
    private val app: Application,
    private val opNames: List<String>,
    private val usageDurationMs: Long = DEFAULT_SEARCH_RANGE_MS
    private val usageDurationMs: Long
) : SmartAsyncMediatorLiveData<@JvmSuppressWildcards Map<String, List<OpAccess>>>(),
        Consumer<AppOpsManager.HistoricalOps> {
    val appOpsManager = app.getSystemService(AppOpsManager::class.java)!!
@@ -43,19 +45,27 @@ class OpUsageLiveData(
    override suspend fun loadDataAndPostValue(job: Job) {
        val now = System.currentTimeMillis()
        val opMap = mutableMapOf<String, MutableList<OpAccess>>()
        /*

        val packageOps = appOpsManager.getPackagesForOps(opNames.toTypedArray())
        for (packageOp in packageOps) {
            for (opEntry in packageOp.ops) {
                val user = UserHandle.getUserHandleForUid(packageOp.uid)
                val lastAccessTime: Long = opEntry.getLastAccessTime(OP_FLAGS_ALL)
                Log.i("ops", "ops for entry ${packageOp.packageName}: $lastAccessTime, running: ${opEntry.isRunning}")
                val lastAccessTime: Long = opEntry.getLastAccessTime(OP_FLAGS_ALL_TRUSTED)

                if (lastAccessTime == -1L) {
                    // There was no access, so skip
                    continue
                }
                if (opEntry.isRunning || lastAccessTime > (now - usageDurationMs)) {

                var lastAccessDuration = opEntry.getLastDuration(OP_FLAGS_ALL_TRUSTED)

                // Some accesses have no duration
                if (lastAccessDuration == -1L) {
                    lastAccessDuration = 0
                }

                if (opEntry.isRunning ||
                        lastAccessTime + lastAccessDuration > (now - usageDurationMs)) {
                    val accessList = opMap.getOrPut(opEntry.opStr) { mutableListOf() }
                    val accessTime = if (opEntry.isRunning) {
                        -1
@@ -66,13 +76,7 @@ class OpUsageLiveData(
                }
            }
        }
        for (opName in opNames) {
            Log.i("ops", "ops for $opName: ${opMap[opName]}")
        }
         */

        opMap["phone_call"] = mutableListOf()
        opMap["video_call"] = mutableListOf()
        postValue(opMap)
    }

@@ -104,13 +108,12 @@ class OpUsageLiveData(
    }

    companion object : DataRepository<Pair<List<String>, Long>, OpUsageLiveData>() {
        private const val DEFAULT_SEARCH_RANGE_MS = 5000L
        override fun newValue(key: Pair<List<String>, Long>): OpUsageLiveData {
            return OpUsageLiveData(PermissionControllerApplication.get(), key.first, key.second)
        }

        operator fun get(ops: List<String>): OpUsageLiveData {
            return get(ops to DEFAULT_SEARCH_RANGE_MS)
        operator fun get(ops: List<String>, usageDurationMs: Long): OpUsageLiveData {
            return get(ops to usageDurationMs)
        }
    }
}
+13 −8
Original line number Diff line number Diff line
@@ -69,12 +69,15 @@ import java.util.Map;
 */
public class ReviewOngoingUsageFragment extends PreferenceFragmentCompat {

    // TODO: Replace with OPSTR... APIs
    static final String PHONE_CALL = "android:phone_call_microphone";
    static final String VIDEO_CALL = "android:phone_call_camera";

    private @NonNull PermissionUsages mPermissionUsages;
    private boolean mPermissionUsagesLoaded;
    private @Nullable AlertDialog mDialog;
    static final String PHONE_CALL = "phone_call";
    static final String VIDEO_CALL = "video_call";
    private OpUsageLiveData mOpUsageLiveData;
    private @Nullable Map<String, List<OpAccess>> mOpUsage;
    private long mStartTime;

    /**
@@ -101,11 +104,13 @@ public class ReviewOngoingUsageFragment extends PreferenceFragmentCompat {
            permissions = new String[] {CAMERA, LOCATION, MICROPHONE};
        }
        ArrayList<String> appOps = new ArrayList<>(List.of(PHONE_CALL, VIDEO_CALL));
        mOpUsageLiveData = OpUsageLiveData.Companion.get(appOps);
        mOpUsageLiveData = OpUsageLiveData.Companion.get(appOps, numMillis);
        mOpUsageLiveData.observe(this, new Observer<Map<String, List<OpAccess>>>() {

            @Override
            public void onChanged(Map<String, List<OpAccess>> stringMap) {
            public void onChanged(Map<String, List<OpAccess>> opUsage) {
                mOpUsage = opUsage;
                mOpUsageLiveData.removeObserver(this);

                if (mPermissionUsagesLoaded) {
                    onPermissionUsagesLoaded();
                }
@@ -118,7 +123,7 @@ public class ReviewOngoingUsageFragment extends PreferenceFragmentCompat {

    private void onPermissionUsagesLoaded() {
        mPermissionUsagesLoaded = true;
        if (getActivity() == null || !mOpUsageLiveData.isInitialized()) {
        if (getActivity() == null || mOpUsage == null) {
            return;
        }

@@ -166,7 +171,7 @@ public class ReviewOngoingUsageFragment extends PreferenceFragmentCompat {
            }
        }

        if (usages.isEmpty()) {
        if (usages.isEmpty() && mOpUsage.isEmpty()) {
            getActivity().finish();
            return;
        }
@@ -226,7 +231,7 @@ public class ReviewOngoingUsageFragment extends PreferenceFragmentCompat {

    private @NonNull View createDialogView(
            @NonNull List<Pair<AppPermissionUsage, List<GroupUsage>>> usages) {
        Map<String, List<OpAccess>> otherAccesses = mOpUsageLiveData.getValue();
        Map<String, List<OpAccess>> otherAccesses = mOpUsage;
        Context context = getActivity();
        LayoutInflater inflater = LayoutInflater.from(context);
        View contentView = inflater.inflate(R.layout.ongoing_usage_dialog_content, null);