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

Commit 8832165c authored by mrulhania's avatar mrulhania
Browse files

Create interface for historical registry

This CL aims to provide a base for sqlite
historical registry implementation.
no functional changes in this CL.

Bug: 377584611
Test: build
Flag: EXEMPT bug fix
Change-Id: I4e5d878dc339838d893b854928b770f472823ab8
parent 4966dab9
Loading
Loading
Loading
Loading
+19 −8
Original line number Original line Diff line number Diff line
@@ -367,7 +367,7 @@ public class AppOpsService extends IAppOpsService.Stub {
    private static final Duration RATE_LIMITER_WINDOW = Duration.ofMillis(10);
    private static final Duration RATE_LIMITER_WINDOW = Duration.ofMillis(10);
    private final RateLimiter mRateLimiter = new RateLimiter(RATE_LIMITER_WINDOW);
    private final RateLimiter mRateLimiter = new RateLimiter(RATE_LIMITER_WINDOW);


    volatile @NonNull HistoricalRegistry mHistoricalRegistry;
    volatile @NonNull HistoricalRegistryInterface mHistoricalRegistry;


    /*
    /*
     * These are app op restrictions imposed per user from various parties.
     * These are app op restrictions imposed per user from various parties.
@@ -1056,8 +1056,12 @@ public class AppOpsService extends IAppOpsService.Stub {
        AppOpsManager.invalidateAppOpModeCache();
        AppOpsManager.invalidateAppOpModeCache();
        AppOpsManager.disableAppOpModeCache();
        AppOpsManager.disableAppOpModeCache();


        if (Flags.enableAllSqliteAppopsAccesses()) {
            mHistoricalRegistry = new HistoricalRegistrySql(context);
        } else {
            mHistoricalRegistry = new HistoricalRegistry(this, context);
            mHistoricalRegistry = new HistoricalRegistry(this, context);
        }
        }
    }


    public void publish() {
    public void publish() {
        ServiceManager.addService(Context.APP_OPS_SERVICE, asBinder());
        ServiceManager.addService(Context.APP_OPS_SERVICE, asBinder());
@@ -1424,7 +1428,7 @@ public class AppOpsService extends IAppOpsService.Stub {


    @GuardedBy("this")
    @GuardedBy("this")
    private void packageRemovedLocked(int uid, String packageName) {
    private void packageRemovedLocked(int uid, String packageName) {
        getIoHandler().post(PooledLambda.obtainRunnable(HistoricalRegistry::clearHistory,
        getIoHandler().post(PooledLambda.obtainRunnable(HistoricalRegistryInterface::clearHistory,
                mHistoricalRegistry, uid, packageName));
                mHistoricalRegistry, uid, packageName));


        UidState uidState = mUidStates.get(uid);
        UidState uidState = mUidStates.get(uid);
@@ -1992,10 +1996,12 @@ public class AppOpsService extends IAppOpsService.Stub {
                        new String[attributionChainExemptPackages.size()]) : null;
                        new String[attributionChainExemptPackages.size()]) : null;


        // Must not hold the appops lock
        // Must not hold the appops lock
        getIoHandler().post(PooledLambda.obtainRunnable(HistoricalRegistry::getHistoricalOps,
        getIoHandler().post(PooledLambda.obtainRunnable(
                HistoricalRegistryInterface::getHistoricalOps,
                mHistoricalRegistry, uid, packageName, attributionTag, opNamesArray, dataType,
                mHistoricalRegistry, uid, packageName, attributionTag, opNamesArray, dataType,
                filter, beginTimeMillis, endTimeMillis, flags, chainExemptPkgArray,
                filter, beginTimeMillis, endTimeMillis, flags, chainExemptPkgArray,
                callback).recycleOnUse());
                callback
        ).recycleOnUse());
    }
    }


    @Override
    @Override
@@ -2024,7 +2030,7 @@ public class AppOpsService extends IAppOpsService.Stub {


        // Must not hold the appops lock
        // Must not hold the appops lock
        getIoHandler().post(PooledLambda.obtainRunnable(
        getIoHandler().post(PooledLambda.obtainRunnable(
                HistoricalRegistry::getHistoricalOpsFromDiskRaw,
                HistoricalRegistryInterface::getHistoricalOpsFromDiskRaw,
                mHistoricalRegistry, uid, packageName, attributionTag, opNamesArray, dataType,
                mHistoricalRegistry, uid, packageName, attributionTag, opNamesArray, dataType,
                filter, beginTimeMillis, endTimeMillis, flags, chainExemptPkgArray,
                filter, beginTimeMillis, endTimeMillis, flags, chainExemptPkgArray,
                callback).recycleOnUse());
                callback).recycleOnUse());
@@ -6961,7 +6967,6 @@ public class AppOpsService extends IAppOpsService.Stub {
        offsetHistory_enforcePermission();
        offsetHistory_enforcePermission();
        // Must not hold the appops lock
        // Must not hold the appops lock
        mHistoricalRegistry.offsetHistory(offsetMillis);
        mHistoricalRegistry.offsetHistory(offsetMillis);
        mHistoricalRegistry.offsetDiscreteHistory(offsetMillis);
    }
    }


    @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_APPOPS)
    @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_APPOPS)
@@ -7002,7 +7007,13 @@ public class AppOpsService extends IAppOpsService.Stub {
            SystemClock.sleep(offlineDurationMillis);
            SystemClock.sleep(offlineDurationMillis);
        }
        }


        mHistoricalRegistry = new HistoricalRegistry(mHistoricalRegistry);
        if (Flags.enableAllSqliteAppopsAccesses()) {
            mHistoricalRegistry = new HistoricalRegistrySql(
                    (HistoricalRegistrySql) mHistoricalRegistry);
        } else {
            mHistoricalRegistry = new HistoricalRegistry((HistoricalRegistry) mHistoricalRegistry);
        }

        mHistoricalRegistry.systemReady(mContext.getContentResolver());
        mHistoricalRegistry.systemReady(mContext.getContentResolver());
        mHistoricalRegistry.persistPendingHistory();
        mHistoricalRegistry.persistPendingHistory();
    }
    }
+1 −1
Original line number Original line Diff line number Diff line
@@ -163,7 +163,7 @@ final class AttributedOp {
    public void rejected(@AppOpsManager.UidState int uidState, @AppOpsManager.OpFlags int flags) {
    public void rejected(@AppOpsManager.UidState int uidState, @AppOpsManager.OpFlags int flags) {
        rejected(System.currentTimeMillis(), uidState, flags);
        rejected(System.currentTimeMillis(), uidState, flags);


        mAppOpsService.mHistoricalRegistry.incrementOpRejected(parent.op, parent.uid,
        mAppOpsService.mHistoricalRegistry.incrementOpRejectedCount(parent.op, parent.uid,
                parent.packageName, tag, uidState, flags);
                parent.packageName, tag, uidState, flags);
    }
    }


+41 −26
Original line number Original line Diff line number Diff line
@@ -128,7 +128,7 @@ import java.util.concurrent.TimeUnit;
 */
 */
// TODO (bug:122218838): Make sure we handle start of epoch time
// TODO (bug:122218838): Make sure we handle start of epoch time
// TODO (bug:122218838): Validate changed time is handled correctly
// TODO (bug:122218838): Validate changed time is handled correctly
final class HistoricalRegistry {
final class HistoricalRegistry implements HistoricalRegistryInterface {
    private static final boolean DEBUG = false;
    private static final boolean DEBUG = false;
    private static final boolean KEEP_WTF_LOG = Build.IS_DEBUGGABLE;
    private static final boolean KEEP_WTF_LOG = Build.IS_DEBUGGABLE;


@@ -218,7 +218,8 @@ final class HistoricalRegistry {
        mDiscreteRegistry = other.mDiscreteRegistry;
        mDiscreteRegistry = other.mDiscreteRegistry;
    }
    }


    void systemReady(@NonNull ContentResolver resolver) {
    @Override
    public void systemReady(@NonNull ContentResolver resolver) {
        mDiscreteRegistry.systemReady();
        mDiscreteRegistry.systemReady();
        final Uri uri = Settings.Global.getUriFor(Settings.Global.APPOP_HISTORY_PARAMETERS);
        final Uri uri = Settings.Global.getUriFor(Settings.Global.APPOP_HISTORY_PARAMETERS);
        resolver.registerContentObserver(uri, false, new ContentObserver(
        resolver.registerContentObserver(uri, false, new ContentObserver(
@@ -320,8 +321,10 @@ final class HistoricalRegistry {
                + "=" + setting + " resetting!");
                + "=" + setting + " resetting!");
    }
    }


    void dump(String prefix, PrintWriter pw, int filterUid, @Nullable String filterPackage,

            @Nullable String filterAttributionTag, int filterOp,
    @Override
    public void dump(String prefix, PrintWriter pw, int filterUid,
            @Nullable String filterPackage, @Nullable String filterAttributionTag, int filterOp,
            @HistoricalOpsRequestFilter int filter) {
            @HistoricalOpsRequestFilter int filter) {
        synchronized (mOnDiskLock) {
        synchronized (mOnDiskLock) {
            synchronized (mInMemoryLock) {
            synchronized (mInMemoryLock) {
@@ -366,7 +369,8 @@ final class HistoricalRegistry {
        }
        }
    }
    }


    void dumpDiscreteData(@NonNull PrintWriter pw, int uidFilter,
    @Override
    public void dumpDiscreteData(@NonNull PrintWriter pw, int uidFilter,
            @Nullable String packageNameFilter, @Nullable String attributionTagFilter,
            @Nullable String packageNameFilter, @Nullable String attributionTagFilter,
            @HistoricalOpsRequestFilter int filter, int dumpOp,
            @HistoricalOpsRequestFilter int filter, int dumpOp,
            @NonNull SimpleDateFormat sdf, @NonNull Date date, @NonNull String prefix,
            @NonNull SimpleDateFormat sdf, @NonNull Date date, @NonNull String prefix,
@@ -381,7 +385,8 @@ final class HistoricalRegistry {
        }
        }
    }
    }


    void getHistoricalOpsFromDiskRaw(int uid, @Nullable String packageName,
    @Override
    public void getHistoricalOpsFromDiskRaw(int uid, @Nullable String packageName,
            @Nullable String attributionTag, @Nullable String[] opNames,
            @Nullable String attributionTag, @Nullable String[] opNames,
            @OpHistoryFlags int historyFlags, @HistoricalOpsRequestFilter int filter,
            @OpHistoryFlags int historyFlags, @HistoricalOpsRequestFilter int filter,
            long beginTimeMillis, long endTimeMillis, @OpFlags int flags,
            long beginTimeMillis, long endTimeMillis, @OpFlags int flags,
@@ -414,11 +419,12 @@ final class HistoricalRegistry {
        callback.sendResult(payload);
        callback.sendResult(payload);
    }
    }


    void getHistoricalOps(int uid, @Nullable String packageName, @Nullable String attributionTag,
    @Override
            @Nullable String[] opNames, @OpHistoryFlags int historyFlags,
    public void getHistoricalOps(int uid, @Nullable String packageName,
            @HistoricalOpsRequestFilter int filter, long beginTimeMillis, long endTimeMillis,
            @Nullable String attributionTag, @Nullable String[] opNames,
            @OpFlags int flags, @Nullable String[] attributionExemptPkgs,
            @OpHistoryFlags int historyFlags, @HistoricalOpsRequestFilter int filter,
            @NonNull RemoteCallback callback) {
            long beginTimeMillis, long endTimeMillis, @OpFlags int flags,
            @Nullable String[] attributionExemptPkgs, @NonNull RemoteCallback callback) {
        final long currentTimeMillis = System.currentTimeMillis();
        final long currentTimeMillis = System.currentTimeMillis();
        if (endTimeMillis == Long.MAX_VALUE) {
        if (endTimeMillis == Long.MAX_VALUE) {
            endTimeMillis = currentTimeMillis;
            endTimeMillis = currentTimeMillis;
@@ -493,7 +499,8 @@ final class HistoricalRegistry {
        callback.sendResult(payload);
        callback.sendResult(payload);
    }
    }


    void incrementOpAccessedCount(int op, int uid, @NonNull String packageName,
    @Override
    public void incrementOpAccessedCount(int op, int uid, @NonNull String packageName,
            @NonNull String deviceId, @Nullable String attributionTag, @UidState int uidState,
            @NonNull String deviceId, @Nullable String attributionTag, @UidState int uidState,
            @OpFlags int flags, long accessTime,
            @OpFlags int flags, long accessTime,
            @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId,
            @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId,
@@ -515,7 +522,8 @@ final class HistoricalRegistry {
        }
        }
    }
    }


    void incrementOpRejected(int op, int uid, @NonNull String packageName,
    @Override
    public void incrementOpRejectedCount(int op, int uid, @NonNull String packageName,
            @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags) {
            @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags) {
        synchronized (mInMemoryLock) {
        synchronized (mInMemoryLock) {
            if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
            if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
@@ -530,7 +538,8 @@ final class HistoricalRegistry {
        }
        }
    }
    }


    void increaseOpAccessDuration(int op, int uid, @NonNull String packageName,
    @Override
    public void increaseOpAccessDuration(int op, int uid, @NonNull String packageName,
            @NonNull String deviceId, @Nullable String attributionTag, @UidState int uidState,
            @NonNull String deviceId, @Nullable String attributionTag, @UidState int uidState,
            @OpFlags int flags, long eventStartTime, long increment,
            @OpFlags int flags, long eventStartTime, long increment,
            @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId) {
            @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId) {
@@ -550,7 +559,8 @@ final class HistoricalRegistry {
        }
        }
    }
    }


    void setHistoryParameters(@HistoricalMode int mode,
    @Override
    public void setHistoryParameters(@HistoricalMode int mode,
            long baseSnapshotInterval, long intervalCompressionMultiplier) {
            long baseSnapshotInterval, long intervalCompressionMultiplier) {
        synchronized (mOnDiskLock) {
        synchronized (mOnDiskLock) {
            synchronized (mInMemoryLock) {
            synchronized (mInMemoryLock) {
@@ -585,7 +595,8 @@ final class HistoricalRegistry {
        }
        }
    }
    }


    void offsetHistory(long offsetMillis) {
    @Override
    public void offsetHistory(long offsetMillis) {
        synchronized (mOnDiskLock) {
        synchronized (mOnDiskLock) {
            synchronized (mInMemoryLock) {
            synchronized (mInMemoryLock) {
                if (!isPersistenceInitializedMLocked()) {
                if (!isPersistenceInitializedMLocked()) {
@@ -607,13 +618,11 @@ final class HistoricalRegistry {
                mPersistence.persistHistoricalOpsDLocked(history);
                mPersistence.persistHistoricalOpsDLocked(history);
            }
            }
        }
        }
    }

    void offsetDiscreteHistory(long offsetMillis) {
        mDiscreteRegistry.offsetHistory(offsetMillis);
        mDiscreteRegistry.offsetHistory(offsetMillis);
    }
    }


    void addHistoricalOps(HistoricalOps ops) {
    @Override
    public void addHistoricalOps(HistoricalOps ops) {
        final List<HistoricalOps> pendingWrites;
        final List<HistoricalOps> pendingWrites;
        synchronized (mInMemoryLock) {
        synchronized (mInMemoryLock) {
            if (!isPersistenceInitializedMLocked()) {
            if (!isPersistenceInitializedMLocked()) {
@@ -634,7 +643,8 @@ final class HistoricalRegistry {
        offsetHistory(offsetMillis);
        offsetHistory(offsetMillis);
    }
    }


    void resetHistoryParameters() {
    @Override
    public void resetHistoryParameters() {
        if (!isPersistenceInitializedMLocked()) {
        if (!isPersistenceInitializedMLocked()) {
            Slog.d(LOG_TAG, "Interaction before persistence initialized");
            Slog.d(LOG_TAG, "Interaction before persistence initialized");
            return;
            return;
@@ -644,7 +654,8 @@ final class HistoricalRegistry {
        mDiscreteRegistry.setDebugMode(false);
        mDiscreteRegistry.setDebugMode(false);
    }
    }


    void clearHistory(int uid, String packageName) {
    @Override
    public void clearHistory(int uid, String packageName) {
        synchronized (mOnDiskLock) {
        synchronized (mOnDiskLock) {
            synchronized (mInMemoryLock) {
            synchronized (mInMemoryLock) {
                if (!isPersistenceInitializedMLocked()) {
                if (!isPersistenceInitializedMLocked()) {
@@ -668,11 +679,13 @@ final class HistoricalRegistry {
        mDiscreteRegistry.clearHistory(uid, packageName);
        mDiscreteRegistry.clearHistory(uid, packageName);
    }
    }


    void writeAndClearDiscreteHistory() {
    @Override
    public void writeAndClearDiscreteHistory() {
        mDiscreteRegistry.writeAndClearOldAccessHistory();
        mDiscreteRegistry.writeAndClearOldAccessHistory();
    }
    }


    void clearAllHistory() {
    @Override
    public void clearAllHistory() {
        clearHistoricalRegistry();
        clearHistoricalRegistry();
        mDiscreteRegistry.clearHistory();
        mDiscreteRegistry.clearHistory();
    }
    }
@@ -741,7 +754,8 @@ final class HistoricalRegistry {
        return mCurrentHistoricalOps;
        return mCurrentHistoricalOps;
    }
    }


    void shutdown() {
    @Override
    public void shutdown() {
        synchronized (mInMemoryLock) {
        synchronized (mInMemoryLock) {
            if (mMode == AppOpsManager.HISTORICAL_MODE_DISABLED) {
            if (mMode == AppOpsManager.HISTORICAL_MODE_DISABLED) {
                return;
                return;
@@ -752,7 +766,8 @@ final class HistoricalRegistry {
        mDiscreteRegistry.shutdown();
        mDiscreteRegistry.shutdown();
    }
    }


    void persistPendingHistory() {
    @Override
    public void persistPendingHistory() {
        final List<HistoricalOps> pendingWrites;
        final List<HistoricalOps> pendingWrites;
        synchronized (mOnDiskLock) {
        synchronized (mOnDiskLock) {
            synchronized (mInMemoryLock) {
            synchronized (mInMemoryLock) {
+153 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.appop;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppOpsManager;
import android.content.ContentResolver;
import android.os.RemoteCallback;

import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * A registry to record app operation access events, which are generated upon an application's
 * access to private data or system resources. These events are stored in both aggregated
 * and individual/discrete formats.
 */
public interface HistoricalRegistryInterface {
    /**
     * A callback to inform system components are ready.
     */
    void systemReady(@NonNull ContentResolver resolver);

    /**
     * Callback for system shutdown.
     */
    void shutdown();

    /**
     * Dumps aggregated/historical events to the console based on the filters.
     */
    void dump(String prefix, PrintWriter pw, int filterUid,
            @Nullable String filterPackage, @Nullable String filterAttributionTag, int filterOp,
            @AppOpsManager.HistoricalOpsRequestFilter int filter);

    /**
     * Dumps discrete/individual events to the console based on filters.
     */
    void dumpDiscreteData(@NonNull PrintWriter pw, int uidFilter,
            @Nullable String packageNameFilter, @Nullable String attributionTagFilter,
            @AppOpsManager.HistoricalOpsRequestFilter int filter, int dumpOp,
            @NonNull SimpleDateFormat sdf, @NonNull Date date, @NonNull String prefix,
            int nDiscreteOps);

    /**
     * Record duration for given op.
     */
    void increaseOpAccessDuration(int op, int uid, @NonNull String packageName,
            @NonNull String deviceId, @Nullable String attributionTag,
            @AppOpsManager.UidState int uidState,
            @AppOpsManager.OpFlags int flags, long eventStartTime, long increment,
            @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId);

    /**
     * Record access counts for given op.
     */
    void incrementOpAccessedCount(int op, int uid, @NonNull String packageName,
            @NonNull String deviceId, @Nullable String attributionTag,
            @AppOpsManager.UidState int uidState,
            @AppOpsManager.OpFlags int flags, long accessTime,
            @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId,
            int accessCount);

    /**
     * Record rejected counts for given op.
     */
    void incrementOpRejectedCount(int op, int uid, @NonNull String packageName,
            @Nullable String attributionTag, @AppOpsManager.UidState int uidState,
            @AppOpsManager.OpFlags int flags);

    /**
     * Read historical ops from both aggregated and discrete events based on input filter.
     */
    void getHistoricalOps(int uid, @Nullable String packageName, @Nullable String attributionTag,
            @Nullable String[] opNames, @AppOpsManager.OpHistoryFlags int historyFlags,
            @AppOpsManager.HistoricalOpsRequestFilter int filter, long beginTimeMillis,
            long endTimeMillis,
            @AppOpsManager.OpFlags int flags, @Nullable String[] attributionExemptPkgs,
            @NonNull RemoteCallback callback);

    /**
     * Remove app op events for a given UID and package.
     */
    void clearHistory(int uid, String packageName);

    /**
     * A periodic callback from {@link AppOpsService} to flush the in memory discrete
     * app op events to disk/database.
     */
    void writeAndClearDiscreteHistory();

    /**
     * A callback flush the in memory app op events to disk/database.
     */
    void persistPendingHistory();

    /**
     * Set history parameters.
     *
     * @param mode - Whether historical registry is Active, Passive or Disabled.
     * @param baseSnapshotInterval - Interval between 2 snapshots, default 15 minutes.
     * @param intervalCompressionMultiplier - Interval compression multiplier, default is 10.
     */
    void setHistoryParameters(@AppOpsManager.HistoricalMode int mode,
            long baseSnapshotInterval, long intervalCompressionMultiplier);

    /**
     * Reset history parameters to defaults.
     */
    void resetHistoryParameters();

    /**
     * Remove all app op accesses from both aggregated and individual event's storage.
     */
    void clearAllHistory();

    /**
     * Offsets the history by the given duration.
     */
    void offsetHistory(long offsetMillis);

    /**
     * Retrieve historical app op stats for a period form disk.
     */
    void getHistoricalOpsFromDiskRaw(int uid, @Nullable String packageName,
            @Nullable String attributionTag, @Nullable String[] opNames,
            @AppOpsManager.OpHistoryFlags int historyFlags,
            @AppOpsManager.HistoricalOpsRequestFilter int filter,
            long beginTimeMillis, long endTimeMillis, @AppOpsManager.OpFlags int flags,
            String[] attributionExemptedPackages, @NonNull RemoteCallback callback);

    /**
     * Adds ops to the history directly. This could be useful for testing especially
     * when the historical registry operates in passive mode.
     */
    void addHistoricalOps(AppOpsManager.HistoricalOps ops);
}
+145 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.appop;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppOpsManager;
import android.content.ContentResolver;
import android.content.Context;
import android.os.RemoteCallback;

import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

// TODO add more documentation later

/**
 * This historical registry implementation store app events in sqlite. The data is stored in 2
 * tables 1) discrete events 2) aggregated events.
 */
public class HistoricalRegistrySql implements HistoricalRegistryInterface {
    // TODO impl will be added in a separate CL
    HistoricalRegistrySql(Context context) {
    }

    HistoricalRegistrySql(HistoricalRegistrySql other) {
    }

    @Override
    public void systemReady(@NonNull ContentResolver resolver) {

    }

    @Override
    public void shutdown() {

    }

    @Override
    public void dump(String prefix, PrintWriter pw, int filterUid,
            @Nullable String filterPackage, @Nullable String filterAttributionTag, int filterOp,
            int filter) {

    }

    @Override
    public void dumpDiscreteData(@NonNull PrintWriter pw, int uidFilter,
            @Nullable String packageNameFilter, @Nullable String attributionTagFilter, int filter,
            int dumpOp, @NonNull SimpleDateFormat sdf, @NonNull Date date, @NonNull String prefix,
            int nDiscreteOps) {

    }

    @Override
    public void increaseOpAccessDuration(int op, int uid, @NonNull String packageName,
            @NonNull String deviceId, @Nullable String attributionTag, int uidState, int flags,
            long eventStartTime, long increment, int attributionFlags, int attributionChainId) {

    }

    @Override
    public void incrementOpAccessedCount(int op, int uid, @NonNull String packageName,
            @NonNull String deviceId, @Nullable String attributionTag, int uidState, int flags,
            long accessTime, int attributionFlags, int attributionChainId, int accessCount) {

    }

    @Override
    public void incrementOpRejectedCount(int op, int uid, @NonNull String packageName,
            @Nullable String attributionTag, int uidState, int flags) {

    }

    @Override
    public void getHistoricalOps(int uid, @Nullable String packageName,
            @Nullable String attributionTag, @Nullable String[] opNames, int historyFlags,
            int filter, long beginTimeMillis, long endTimeMillis, int flags,
            @Nullable String[] attributionExemptPkgs, @NonNull RemoteCallback callback) {

    }

    @Override
    public void clearHistory(int uid, String packageName) {

    }

    @Override
    public void writeAndClearDiscreteHistory() {

    }

    @Override
    public void persistPendingHistory() {

    }

    @Override
    public void setHistoryParameters(int mode, long baseSnapshotInterval,
            long intervalCompressionMultiplier) {

    }

    @Override
    public void resetHistoryParameters() {

    }

    @Override
    public void clearAllHistory() {

    }

    @Override
    public void offsetHistory(long offsetMillis) {

    }

    @Override
    public void getHistoricalOpsFromDiskRaw(int uid, @Nullable String packageName,
            @Nullable String attributionTag, @Nullable String[] opNames, int historyFlags,
            int filter, long beginTimeMillis, long endTimeMillis, int flags,
            String[] attributionExemptedPackages, @NonNull RemoteCallback callback) {

    }

    @Override
    public void addHistoricalOps(AppOpsManager.HistoricalOps ops) {

    }
}