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

Commit 5f35f0d3 authored by Kweku Adams's avatar Kweku Adams
Browse files

Add listener for UsageEvents.

Add a listener that will grant rewards for various usage events.

Bug: 158300259
Test: Check dumpsys for TOP reward grant
Change-Id: I2c2b4b3aa40408cb0941db97fb510bce16b1f835
parent 2f348e59
Loading
Loading
Loading
Loading
+14 −10
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import static com.android.server.tare.EconomicPolicy.TYPE_ACTION;
import static com.android.server.tare.EconomicPolicy.TYPE_REWARD;
import static com.android.server.tare.EconomicPolicy.eventToString;
import static com.android.server.tare.EconomicPolicy.getEventType;
import static com.android.server.tare.TareUtils.appToString;
import static com.android.server.tare.TareUtils.getCurrentTimeMillis;
import static com.android.server.tare.TareUtils.narcToString;

@@ -232,8 +233,9 @@ class Agent {
    }

    @GuardedBy("mLock")
    void noteOngoingEventLocked(final int userId, @NonNull final String pkgName, final int eventId,
            @Nullable String tag, final long startElapsed, final boolean updateBalanceCheck) {
    private void noteOngoingEventLocked(final int userId, @NonNull final String pkgName,
            final int eventId, @Nullable String tag, final long startElapsed,
            final boolean updateBalanceCheck) {
        SparseArrayMap<String, OngoingEvent> ongoingEvents =
                mCurrentOngoingEvents.get(userId, pkgName);
        if (ongoingEvents == null) {
@@ -392,8 +394,8 @@ class Agent {
     *                                    registered bills and notify listeners about any changes.
     */
    @GuardedBy("mLock")
    void stopOngoingActionLocked(final int userId, @NonNull final String pkgName, final int eventId,
            @Nullable String tag, final long nowElapsed, final long now,
    private void stopOngoingActionLocked(final int userId, @NonNull final String pkgName,
            final int eventId, @Nullable String tag, final long nowElapsed, final long now,
            final boolean updateBalanceCheck, final boolean notifyOnAffordabilityChange) {
        final Ledger ledger = getLedgerLocked(userId, pkgName);

@@ -402,7 +404,7 @@ class Agent {
        if (ongoingEvents == null) {
            // This may occur if TARE goes from disabled to enabled while an event is already
            // occurring.
            Slog.w(TAG, "No ongoing transactions for <" + userId + ">" + pkgName);
            Slog.w(TAG, "No ongoing transactions for " + appToString(userId, pkgName));
            return;
        }
        final OngoingEvent ongoingEvent = ongoingEvents.get(eventId, tag);
@@ -411,7 +413,7 @@ class Agent {
            // occurring.
            Slog.w(TAG, "Nonexistent ongoing transaction "
                    + eventToString(eventId) + (tag == null ? "" : ":" + tag)
                    + " for <" + userId + ">" + pkgName + " ended");
                    + " for " + appToString(userId, pkgName) + " ended");
            return;
        }
        ongoingEvent.refCount--;
@@ -454,7 +456,8 @@ class Agent {
            Slog.i(TAG, "Would result in too many credits in circulation. Decreasing transaction "
                    + eventToString(transaction.eventId)
                    + (transaction.tag == null ? "" : ":" + transaction.tag)
                    + " for <" + userId + ">" + pkgName + " by " + (transaction.delta - newDelta));
                    + " for " + appToString(userId, pkgName)
                    + " by " + (transaction.delta - newDelta));
            transaction = new Ledger.Transaction(
                    transaction.startTimeMs, transaction.endTimeMs,
                    transaction.eventId, transaction.tag, newDelta);
@@ -467,7 +470,8 @@ class Agent {
            Slog.i(TAG, "Would result in becoming too rich. Decreasing transaction "
                    + eventToString(transaction.eventId)
                    + (transaction.tag == null ? "" : ":" + transaction.tag)
                    + " for <" + userId + ">" + pkgName + " by " + (transaction.delta - newDelta));
                    + " for " + appToString(userId, pkgName)
                    + " by " + (transaction.delta - newDelta));
            transaction = new Ledger.Transaction(
                    transaction.startTimeMs, transaction.endTimeMs,
                    transaction.eventId, transaction.tag, newDelta);
@@ -530,7 +534,7 @@ class Agent {
                }
                if (toReclaim > 0) {
                    Slog.i(TAG, "Reclaiming unused wealth! Taking " + toReclaim
                            + " from <" + userId + ">" + pkgName);
                            + " from " + appToString(userId, pkgName));

                    recordTransactionLocked(userId, pkgName, ledger,
                            new Ledger.Transaction(
@@ -819,7 +823,7 @@ class Agent {

            @Override
            public String toString() {
                return "<" + userId + ">" + packageName;
                return appToString(userId, packageName);
            }

            @Override
+69 −2
Original line number Diff line number Diff line
@@ -19,12 +19,15 @@ package com.android.server.tare;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;

import static com.android.server.tare.TareUtils.appToString;
import static com.android.server.tare.TareUtils.getCurrentTimeMillis;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AlarmManager;
import android.app.tare.IEconomyManager;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStatsManagerInternal;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@@ -154,6 +157,18 @@ public class InternalResourceService extends SystemService {
        }
    };

    private final UsageStatsManagerInternal.UsageEventListener mSurveillanceAgent =
            new UsageStatsManagerInternal.UsageEventListener() {
                /**
                 * Callback to inform listeners of a new event.
                 */
                @Override
                public void onUsageEvent(int userId, @NonNull UsageEvents.Event event) {
                    mHandler.obtainMessage(MSG_PROCESS_USAGE_EVENT, userId, 0, event)
                            .sendToTarget();
                }
            };

    private final AlarmManager.OnAlarmListener mUnusedWealthReclamationListener =
            new AlarmManager.OnAlarmListener() {
                @Override
@@ -168,6 +183,7 @@ public class InternalResourceService extends SystemService {

    private static final int MSG_NOTIFY_AFFORDABILITY_CHANGE_LISTENER = 0;
    private static final int MSG_SCHEDULE_UNUSED_WEALTH_RECLAMATION_EVENT = 1;
    private static final int MSG_PROCESS_USAGE_EVENT = 2;
    private static final String ALARM_TAG_WEALTH_RECLAMATION = "*tare.reclamation*";
    private static final String KEY_PKG = "pkg";

@@ -341,6 +357,42 @@ public class InternalResourceService extends SystemService {
        msg.sendToTarget();
    }

    @GuardedBy("mLock")
    private void processUsageEventLocked(final int userId, @NonNull UsageEvents.Event event) {
        if (!mIsEnabled) {
            return;
        }
        final String pkgName = event.getPackageName();
        if (DEBUG) {
            Slog.d(TAG, "Processing event " + event.getEventType()
                    + " for " + appToString(userId, pkgName));
        }
        final long nowElapsed = SystemClock.elapsedRealtime();
        switch (event.getEventType()) {
            case UsageEvents.Event.ACTIVITY_RESUMED:
                mAgent.noteOngoingEventLocked(userId, pkgName,
                        EconomicPolicy.REWARD_TOP_ACTIVITY, null, nowElapsed);
                break;
            case UsageEvents.Event.ACTIVITY_PAUSED:
            case UsageEvents.Event.ACTIVITY_STOPPED:
            case UsageEvents.Event.ACTIVITY_DESTROYED:
                final long now = getCurrentTimeMillis();
                mAgent.stopOngoingActionLocked(userId, pkgName,
                        EconomicPolicy.REWARD_TOP_ACTIVITY, null, nowElapsed, now);
                break;
            case UsageEvents.Event.USER_INTERACTION:
            case UsageEvents.Event.CHOOSER_ACTION:
                mAgent.noteInstantaneousEventLocked(userId, pkgName,
                        EconomicPolicy.REWARD_OTHER_USER_INTERACTION, null);
                break;
            case UsageEvents.Event.NOTIFICATION_INTERRUPTION:
            case UsageEvents.Event.NOTIFICATION_SEEN:
                mAgent.noteInstantaneousEventLocked(userId, pkgName,
                        EconomicPolicy.REWARD_NOTIFICATION_SEEN, null);
                break;
        }
    }

    @GuardedBy("mLock")
    private void scheduleUnusedWealthReclamationLocked() {
        final long now = getCurrentTimeMillis();
@@ -386,7 +438,7 @@ public class InternalResourceService extends SystemService {
        mPkgCache = mPackageManager.getInstalledPackages(0);
    }

    private void registerReceivers() {
    private void registerListeners() {
        final IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_BATTERY_LEVEL_CHANGED);
        getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
@@ -403,6 +455,9 @@ public class InternalResourceService extends SystemService {
        userFilter.addAction(Intent.ACTION_USER_ADDED);
        getContext()
                .registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, userFilter, null, null);

        UsageStatsManagerInternal usmi = LocalServices.getService(UsageStatsManagerInternal.class);
        usmi.registerListener(mSurveillanceAgent);
    }

    /** Perform long-running and/or heavy setup work. This should be called off the main thread. */
@@ -422,7 +477,7 @@ public class InternalResourceService extends SystemService {
            return;
        }
        synchronized (mLock) {
            registerReceivers();
            registerListeners();
            mCurrentBatteryLevel = getCurrentBatteryLevel();
            mHandler.post(this::setupHeavyWork);
            scheduleUnusedWealthReclamationLocked();
@@ -447,6 +502,9 @@ public class InternalResourceService extends SystemService {
            mPkgCache.clear();
            mUidToPackageCache.clear();
            getContext().unregisterReceiver(mBroadcastReceiver);
            UsageStatsManagerInternal usmi =
                    LocalServices.getService(UsageStatsManagerInternal.class);
            usmi.unregisterListener(mSurveillanceAgent);
        }
    }

@@ -472,6 +530,15 @@ public class InternalResourceService extends SystemService {
                }
                break;

                case MSG_PROCESS_USAGE_EVENT: {
                    final int userId = msg.arg1;
                    final UsageEvents.Event event = (UsageEvents.Event) msg.obj;
                    synchronized (mLock) {
                        processUsageEventLocked(userId, event);
                    }
                }
                break;

                case MSG_SCHEDULE_UNUSED_WEALTH_RECLAMATION_EVENT: {
                    removeMessages(MSG_SCHEDULE_UNUSED_WEALTH_RECLAMATION_EVENT);
                    synchronized (mLock) {
+6 −0
Original line number Diff line number Diff line
@@ -69,4 +69,10 @@ class TareUtils {
        sb.append(" ARCs");
        return sb.toString();
    }

    /** Returns a standardized format for printing userId+pkgName combinations. */
    @NonNull
    static String appToString(int userId, String pkgName) {
        return "<" + userId + ">" + pkgName;
    }
}