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
This commit is contained in:
Kweku Adams
2021-07-30 11:44:34 -07:00
parent 2f348e59f7
commit 5f35f0d37a
3 changed files with 89 additions and 12 deletions

View File

@@ -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

View File

@@ -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) {

View File

@@ -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;
}
}