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

Commit 6fbd9ca2 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Delete persisted historical app ops on package uninstall"

parents 79d15b87 470b15be
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -3120,6 +3120,15 @@ public class AppOpsManager {
            return mHistoricalUidOps.get(uid);
        }

        /** @hide */
        public void clearHistory(int uid, @NonNull String packageName) {
            HistoricalUidOps historicalUidOps = getOrCreateHistoricalUidOps(uid);
            historicalUidOps.clearHistory(packageName);
            if (historicalUidOps.isEmpty()) {
                mHistoricalUidOps.remove(uid);
            }
        }

        @Override
        public int describeContents() {
            return 0;
@@ -3397,6 +3406,12 @@ public class AppOpsManager {
            return mHistoricalPackageOps.get(packageName);
        }

        private void clearHistory(@NonNull String packageName) {
            if (mHistoricalPackageOps != null) {
                mHistoricalPackageOps.remove(packageName);
            }
        }

        @Override
        public int describeContents() {
            return 0;
+2 −0
Original line number Diff line number Diff line
@@ -905,6 +905,8 @@ public class AppOpsService extends IAppOpsService.Stub {
                    }
                }
            }

            mHistoricalRegistry.clearHistory(uid, packageName);
        }
    }

+35 −0
Original line number Diff line number Diff line
@@ -472,6 +472,25 @@ final class HistoricalRegistry {
                DEFAULT_COMPRESSION_STEP);
    }

    void clearHistory(int uid, String packageName) {
        synchronized (mOnDiskLock) {
            synchronized (mInMemoryLock) {
                if (mMode != AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
                    return;
                }

                for (int index = 0; index < mPendingWrites.size(); index++) {
                    mPendingWrites.get(index).clearHistory(uid, packageName);
                }

                getUpdatedPendingHistoricalOpsMLocked(System.currentTimeMillis())
                        .clearHistory(uid, packageName);

                mPersistence.clearHistoryDLocked(uid, packageName);
            }
        }
    }

    void clearHistory() {
        synchronized (mOnDiskLock) {
            clearHistoryOnDiskLocked();
@@ -628,6 +647,22 @@ final class HistoricalRegistry {
            return new File(baseDir, Long.toString(globalBeginMillis) + HISTORY_FILE_SUFFIX);
        }

        void clearHistoryDLocked(int uid, String packageName) {
            List<HistoricalOps> historicalOps = readHistoryDLocked();

            if (historicalOps == null) {
                return;
            }

            for (int index = 0; index < historicalOps.size(); index++) {
                historicalOps.get(index).clearHistory(uid, packageName);
            }

            clearHistoryDLocked();

            persistHistoricalOpsDLocked(historicalOps);
        }

        void clearHistoryDLocked() {
            mHistoricalAppOpsDir.delete();
        }
+1 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
    <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
    <uses-permission android:name="android.permission.HARDWARE_TEST"/>
    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
    <uses-permission android:name="android.permission.MANAGE_APPOPS"/>

    <application android:testOnly="true"
                 android:debuggable="true">
+45 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;

import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.AppOpsManager.OpEntry;
import android.app.AppOpsManager.PackageOps;
import android.content.Context;
@@ -48,6 +49,7 @@ import android.content.pm.PackageManagerInternal;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Process;
import android.os.RemoteCallback;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
@@ -64,6 +66,9 @@ import org.mockito.quality.Strictness;

import java.io.File;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Unit tests for AppOpsService. Covers functionality that is difficult to test using CTS tests
@@ -258,6 +263,46 @@ public class AppOpsServiceTest {
        assertThat(getLoggedOps()).isNull();
    }


    @Test
    public void testPackageRemovedHistoricalOps() throws InterruptedException {
        mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED);
        mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName);

        AppOpsManager.HistoricalOps historicalOps = new AppOpsManager.HistoricalOps(0, 15000);
        historicalOps.increaseAccessCount(OP_READ_SMS, mMyUid, sMyPackageName,
                AppOpsManager.UID_STATE_PERSISTENT, 0, 1);

        mAppOpsService.addHistoricalOps(historicalOps);

        AtomicReference<AppOpsManager.HistoricalOps> resultOpsRef = new AtomicReference<>();
        AtomicReference<CountDownLatch> latchRef = new AtomicReference<>(new CountDownLatch(1));
        RemoteCallback callback = new RemoteCallback(result -> {
            resultOpsRef.set(result.getParcelable(AppOpsManager.KEY_HISTORICAL_OPS));
            latchRef.get().countDown();
        });

        // First, do a fetch to ensure it's written
        mAppOpsService.getHistoricalOps(mMyUid, sMyPackageName, null, 0, Long.MAX_VALUE, 0,
                callback);

        latchRef.get().await(5, TimeUnit.SECONDS);
        assertThat(latchRef.get().getCount()).isEqualTo(0);
        assertThat(resultOpsRef.get().isEmpty()).isFalse();

        // Then, check it's deleted on removal
        mAppOpsService.packageRemoved(mMyUid, sMyPackageName);

        latchRef.set(new CountDownLatch(1));

        mAppOpsService.getHistoricalOps(mMyUid, sMyPackageName, null, 0, Long.MAX_VALUE, 0,
                callback);

        latchRef.get().await(5, TimeUnit.SECONDS);
        assertThat(latchRef.get().getCount()).isEqualTo(0);
        assertThat(resultOpsRef.get().isEmpty()).isTrue();
    }

    @Test
    public void testUidRemoved() {
        mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED);