Merge "Convert event IDs from String to int."

This commit is contained in:
TreeHugger Robot
2021-06-15 17:02:03 +00:00
committed by Android (Google) Code Review
10 changed files with 340 additions and 143 deletions

View File

@@ -16,6 +16,11 @@
package com.android.server.tare;
import static com.android.server.tare.EconomicPolicy.REGULATION_BASIC_INCOME;
import static com.android.server.tare.EconomicPolicy.REGULATION_BIRTHRIGHT;
import static com.android.server.tare.EconomicPolicy.eventToString;
import static com.android.server.tare.TareUtils.narcToString;
import android.annotation.NonNull;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -85,23 +90,25 @@ class Agent {
if (transaction.delta > 0 && newArcsInCirculation > maxCirculationAllowed) {
final long newDelta = maxCirculationAllowed - mCurrentNarcsInCirculation;
Slog.i(TAG, "Would result in too many credits in circulation. Decreasing transaction "
+ transaction.reason + (transaction.tag == null ? "" : ":" + transaction.tag)
+ eventToString(transaction.eventId)
+ (transaction.tag == null ? "" : ":" + transaction.tag)
+ " for <" + userId + ">" + pkgName + " by " + (transaction.delta - newDelta));
transaction = new Ledger.Transaction(
transaction.startTimeMs, transaction.endTimeMs,
transaction.reason, transaction.tag, newDelta);
transaction.eventId, transaction.tag, newDelta);
}
final long originalBalance = ledger.getCurrentBalance();
if (transaction.delta > 0
&& originalBalance + transaction.delta
> mCompleteEconomicPolicy.getMaxSatiatedBalance()) {
final long newDelta = mCompleteEconomicPolicy.getMaxSatiatedBalance() - originalBalance;
Slog.i(TAG, "Would result in becoming too rich. Decreasing transaction "
+ transaction.reason + (transaction.tag == null ? "" : ":" + transaction.tag)
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));
transaction = new Ledger.Transaction(
transaction.startTimeMs, transaction.endTimeMs,
transaction.reason, transaction.tag, newDelta);
transaction.eventId, transaction.tag, newDelta);
}
ledger.recordTransaction(transaction);
mCurrentNarcsInCirculation += transaction.delta;
@@ -129,7 +136,7 @@ class Agent {
if (ledger.getCurrentBalance() < minBalance) {
final long shortfall = minBalance - getBalanceLocked(userId, pkgName);
recordTransactionLocked(userId, pkgName, ledger,
new Ledger.Transaction(now, now, "UNIVERSAL_BASIC_INCOME",
new Ledger.Transaction(now, now, REGULATION_BASIC_INCOME,
null, (long) (perc * shortfall)));
}
}
@@ -165,7 +172,7 @@ class Agent {
}
recordTransactionLocked(userId, pkgName, ledger,
new Ledger.Transaction(now, now, "BIRTHRIGHT", null,
new Ledger.Transaction(now, now, REGULATION_BIRTHRIGHT, null,
Math.min(maxBirthright, mIrs.getMinBalanceLocked(userId, pkgName))));
}
}
@@ -185,7 +192,7 @@ class Agent {
final long now = System.currentTimeMillis();
recordTransactionLocked(userId, pkgName, ledger,
new Ledger.Transaction(now, now, "BIRTHRIGHT", null,
new Ledger.Transaction(now, now, REGULATION_BIRTHRIGHT, null,
Math.min(maxBirthright, mIrs.getMinBalanceLocked(userId, pkgName))));
}
@@ -223,6 +230,6 @@ class Agent {
@GuardedBy("mLock")
void dumpLocked(IndentingPrintWriter pw) {
pw.print("Current GDP: ");
pw.println(mCurrentNarcsInCirculation);
pw.println(narcToString(mCurrentNarcsInCirculation));
}
}

View File

@@ -24,26 +24,31 @@ import static com.android.server.tare.TareUtils.arcToNarc;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.ArrayMap;
import android.util.SparseArray;
/**
* Policy defining pricing information and daily ARC requirements and suggestions for
* AlarmManager.
*/
public class AlarmManagerEconomicPolicy extends EconomicPolicy {
public static final String ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE =
"ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE";
public static final String ACTION_ALARM_WAKEUP_EXACT = "ALARM_WAKEUP_EXACT";
public static final String ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE =
"ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE";
public static final String ACTION_ALARM_WAKEUP_INEXACT = "ALARM_WAKEUP_INEXACT";
public static final String ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE =
"ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE";
public static final String ACTION_ALARM_NONWAKEUP_EXACT = "ALARM_NONWAKEUP_EXACT";
public static final String ACTION_ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE =
"ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE";
public static final String ACTION_ALARM_NONWAKEUP_INEXACT = "ALARM_NONWAKEUP_INEXACT";
public static final String ACTION_ALARM_CLOCK = "ALARM_CLOCK";
public static final int ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE =
TYPE_ACTION | POLICY_AM | 0;
public static final int ACTION_ALARM_WAKEUP_EXACT =
TYPE_ACTION | POLICY_AM | 1;
public static final int ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE =
TYPE_ACTION | POLICY_AM | 2;
public static final int ACTION_ALARM_WAKEUP_INEXACT =
TYPE_ACTION | POLICY_AM | 3;
public static final int ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE =
TYPE_ACTION | POLICY_AM | 4;
public static final int ACTION_ALARM_NONWAKEUP_EXACT =
TYPE_ACTION | POLICY_AM | 5;
public static final int ACTION_ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE =
TYPE_ACTION | POLICY_AM | 6;
public static final int ACTION_ALARM_NONWAKEUP_INEXACT =
TYPE_ACTION | POLICY_AM | 7;
public static final int ACTION_ALARM_CLOCK =
TYPE_ACTION | POLICY_AM | 8;
private static final int[] COST_MODIFIERS = new int[]{
COST_MODIFIER_CHARGING,
@@ -52,8 +57,8 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy {
COST_MODIFIER_PROCESS_STATE
};
private final ArrayMap<String, Action> mActions = new ArrayMap<>();
private final ArrayMap<String, Reward> mRewards = new ArrayMap<>();
private final SparseArray<Action> mActions = new SparseArray<>();
private final SparseArray<Reward> mRewards = new SparseArray<>();
AlarmManagerEconomicPolicy(InternalResourceService irs) {
super(irs);
@@ -86,14 +91,14 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy {
@Nullable
@Override
Action getAction(@NonNull String actionName) {
return mActions.get(actionName);
Action getAction(@AppAction int actionId) {
return mActions.get(actionId);
}
@Nullable
@Override
Reward getReward(@NonNull String rewardName) {
return mRewards.get(rewardName);
Reward getReward(@UtilityReward int rewardId) {
return mRewards.get(rewardId);
}
private void loadActions() {

View File

@@ -18,9 +18,9 @@ package com.android.server.tare;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.IndentingPrintWriter;
import android.util.SparseArray;
import libcore.util.EmptyArray;
@@ -29,9 +29,9 @@ import libcore.util.EmptyArray;
public class CompleteEconomicPolicy extends EconomicPolicy {
private final ArraySet<EconomicPolicy> mEnabledEconomicPolicies = new ArraySet<>();
/** Lazily populated set of actions covered by this policy. */
private final ArrayMap<String, Action> mActions = new ArrayMap<>();
private final SparseArray<Action> mActions = new SparseArray<>();
/** Lazily populated set of rewards covered by this policy. */
private final ArrayMap<String, Reward> mRewards = new ArrayMap<>();
private final SparseArray<Reward> mRewards = new SparseArray<>();
private final int[] mCostModifiers;
private final long mMaxSatiatedBalance;
private final long mMaxSatiatedCirculation;
@@ -93,37 +93,37 @@ public class CompleteEconomicPolicy extends EconomicPolicy {
@Nullable
@Override
public Action getAction(@NonNull String actionName) {
if (mActions.containsKey(actionName)) {
return mActions.get(actionName);
public Action getAction(@AppAction int actionId) {
if (mActions.contains(actionId)) {
return mActions.get(actionId);
}
long ctp = 0, price = 0;
boolean exists = false;
for (int i = 0; i < mEnabledEconomicPolicies.size(); ++i) {
Action a = mEnabledEconomicPolicies.valueAt(i).getAction(actionName);
Action a = mEnabledEconomicPolicies.valueAt(i).getAction(actionId);
if (a != null) {
exists = true;
ctp += a.costToProduce;
price += a.basePrice;
}
}
final Action action = exists ? new Action(actionName, ctp, price) : null;
mActions.put(actionName, action);
final Action action = exists ? new Action(actionId, ctp, price) : null;
mActions.put(actionId, action);
return action;
}
@Nullable
@Override
public Reward getReward(@NonNull String rewardName) {
if (mRewards.containsKey(rewardName)) {
return mRewards.get(rewardName);
public Reward getReward(@UtilityReward int rewardId) {
if (mRewards.contains(rewardId)) {
return mRewards.get(rewardId);
}
long instantReward = 0, ongoingReward = 0, maxReward = 0;
boolean exists = false;
for (int i = 0; i < mEnabledEconomicPolicies.size(); ++i) {
Reward r = mEnabledEconomicPolicies.valueAt(i).getReward(rewardName);
Reward r = mEnabledEconomicPolicies.valueAt(i).getReward(rewardId);
if (r != null) {
exists = true;
instantReward += r.instantReward;
@@ -132,8 +132,8 @@ public class CompleteEconomicPolicy extends EconomicPolicy {
}
}
final Reward reward = exists
? new Reward(rewardName, instantReward, ongoingReward, maxReward) : null;
mRewards.put(rewardName, reward);
? new Reward(rewardId, instantReward, ongoingReward, maxReward) : null;
mRewards.put(rewardId, reward);
return reward;
}

View File

@@ -23,9 +23,9 @@ import static com.android.server.tare.Modifier.COST_MODIFIER_PROCESS_STATE;
import static com.android.server.tare.Modifier.NUM_COST_MODIFIERS;
import android.annotation.CallSuper;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StringDef;
import android.util.IndentingPrintWriter;
import java.lang.annotation.Retention;
@@ -40,14 +40,65 @@ import java.lang.annotation.RetentionPolicy;
public abstract class EconomicPolicy {
private static final String TAG = "TARE-" + EconomicPolicy.class.getSimpleName();
// fixme ensure actions and rewards never use the same strings
static final String REWARD_TOP_ACTIVITY = "REWARD_TOP_ACTIVITY";
static final String REWARD_NOTIFICATION_SEEN = "REWARD_NOTIFICATION_SEEN";
static final String REWARD_NOTIFICATION_INTERACTION = "REWARD_NOTIFICATION_INTERACTION";
static final String REWARD_WIDGET_INTERACTION = "REWARD_WIDGET_INTERACTION";
static final String REWARD_OTHER_USER_INTERACTION = "REWARD_OTHER_USER_INTERACTION";
private static final int SHIFT_TYPE = 30;
static final int MASK_TYPE = 0b11 << SHIFT_TYPE;
static final int TYPE_REGULATION = 0 << SHIFT_TYPE;
static final int TYPE_ACTION = 1 << SHIFT_TYPE;
static final int TYPE_REWARD = 2 << SHIFT_TYPE;
@StringDef({
private static final int SHIFT_POLICY = 29;
static final int MASK_POLICY = 0b1 << SHIFT_POLICY;
static final int POLICY_AM = 0 << SHIFT_POLICY;
static final int POLICY_JS = 1 << SHIFT_POLICY;
static final int MASK_EVENT = ~0 - (0b111 << SHIFT_POLICY);
static final int REGULATION_BASIC_INCOME = TYPE_REGULATION | 0;
static final int REGULATION_BIRTHRIGHT = TYPE_REGULATION | 1;
static final int REGULATION_TAX = TYPE_REGULATION | 2;
static final int REWARD_NOTIFICATION_SEEN = TYPE_REWARD | 0;
static final int REWARD_NOTIFICATION_INTERACTION = TYPE_REWARD | 1;
static final int REWARD_TOP_ACTIVITY = TYPE_REWARD | 2;
static final int REWARD_WIDGET_INTERACTION = TYPE_REWARD | 3;
static final int REWARD_OTHER_USER_INTERACTION = TYPE_REWARD | 4;
@IntDef({
AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE,
AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_EXACT,
AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE,
AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_INEXACT,
AlarmManagerEconomicPolicy.ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE,
AlarmManagerEconomicPolicy.ACTION_ALARM_NONWAKEUP_EXACT,
AlarmManagerEconomicPolicy.ACTION_ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE,
AlarmManagerEconomicPolicy.ACTION_ALARM_NONWAKEUP_INEXACT,
AlarmManagerEconomicPolicy.ACTION_ALARM_CLOCK,
JobSchedulerEconomicPolicy.ACTION_JOB_MAX_START,
JobSchedulerEconomicPolicy.ACTION_JOB_MAX_RUNNING,
JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_START,
JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_RUNNING,
JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_START,
JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING,
JobSchedulerEconomicPolicy.ACTION_JOB_LOW_START,
JobSchedulerEconomicPolicy.ACTION_JOB_LOW_RUNNING,
JobSchedulerEconomicPolicy.ACTION_JOB_MIN_START,
JobSchedulerEconomicPolicy.ACTION_JOB_MIN_RUNNING,
JobSchedulerEconomicPolicy.ACTION_JOB_TIMEOUT,
})
@Retention(RetentionPolicy.SOURCE)
public @interface AppAction {
}
@IntDef({
TYPE_ACTION,
TYPE_REGULATION,
TYPE_REWARD,
})
@Retention(RetentionPolicy.SOURCE)
public @interface EventType {
}
@IntDef({
REWARD_TOP_ACTIVITY,
REWARD_NOTIFICATION_SEEN,
REWARD_NOTIFICATION_INTERACTION,
@@ -59,8 +110,8 @@ public abstract class EconomicPolicy {
}
static class Action {
@NonNull
public final String name;
/** Unique id (including across policies) for this action. */
public final int id;
/**
* How many ARCs the system says it takes to perform this action.
*/
@@ -72,25 +123,25 @@ public abstract class EconomicPolicy {
*/
public final long basePrice;
Action(@NonNull String name, long costToProduce, long basePrice) {
this.name = name;
Action(int id, long costToProduce, long basePrice) {
this.id = id;
this.costToProduce = costToProduce;
this.basePrice = basePrice;
}
}
static class Reward {
@NonNull
/** Unique id (including across policies) for this reward. */
@UtilityReward
public final String name;
public final int id;
public final long instantReward;
/** Reward credited per second of ongoing activity. */
public final long ongoingRewardPerSecond;
/** The maximum amount an app can earn from this reward within a 24 hour period. */
public final long maxDailyReward;
Reward(@NonNull String name, long instantReward, long ongoingReward, long maxDailyReward) {
this.name = name;
Reward(int id, long instantReward, long ongoingReward, long maxDailyReward) {
this.id = id;
this.instantReward = instantReward;
this.ongoingRewardPerSecond = ongoingReward;
this.maxDailyReward = maxDailyReward;
@@ -139,16 +190,16 @@ public abstract class EconomicPolicy {
abstract int[] getCostModifiers();
@Nullable
abstract Action getAction(@NonNull String actionName);
abstract Action getAction(@AppAction int actionId);
@Nullable
abstract Reward getReward(@NonNull String rewardName);
abstract Reward getReward(@UtilityReward int rewardId);
void dump(IndentingPrintWriter pw) {
}
final long getCostOfAction(@NonNull String actionName, int userId, @NonNull String pkgName) {
final Action action = getAction(actionName);
final long getCostOfAction(int actionId, int userId, @NonNull String pkgName) {
final Action action = getAction(actionId);
if (action == null) {
return 0;
}
@@ -214,6 +265,111 @@ public abstract class EconomicPolicy {
return modifier;
}
@EventType
static int getEventType(int eventId) {
return eventId & MASK_TYPE;
}
@NonNull
static String eventToString(int eventId) {
switch (eventId & MASK_TYPE) {
case TYPE_ACTION:
return actionToString(eventId);
case TYPE_REGULATION:
return regulationToString(eventId);
case TYPE_REWARD:
return rewardToString(eventId);
default:
return "UNKNOWN_EVENT:" + Integer.toHexString(eventId);
}
}
@NonNull
static String actionToString(int eventId) {
switch (eventId & MASK_POLICY) {
case POLICY_AM:
switch (eventId) {
case AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE:
return "ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE";
case AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_EXACT:
return "ALARM_WAKEUP_EXACT";
case AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE:
return "ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE";
case AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_INEXACT:
return "ALARM_WAKEUP_INEXACT";
case AlarmManagerEconomicPolicy.ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE:
return "ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE";
case AlarmManagerEconomicPolicy.ACTION_ALARM_NONWAKEUP_EXACT:
return "ALARM_NONWAKEUP_EXACT";
case AlarmManagerEconomicPolicy.ACTION_ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE:
return "ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE";
case AlarmManagerEconomicPolicy.ACTION_ALARM_NONWAKEUP_INEXACT:
return "ALARM_NONWAKEUP_INEXACT";
case AlarmManagerEconomicPolicy.ACTION_ALARM_CLOCK:
return "ALARM_CLOCK";
}
case POLICY_JS:
switch (eventId) {
case JobSchedulerEconomicPolicy.ACTION_JOB_MAX_START:
return "JOB_MAX_START";
case JobSchedulerEconomicPolicy.ACTION_JOB_MAX_RUNNING:
return "JOB_MAX_RUNNING";
case JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_START:
return "JOB_HIGH_START";
case JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_RUNNING:
return "JOB_HIGH_RUNNING";
case JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_START:
return "JOB_DEFAULT_START";
case JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING:
return "JOB_DEFAULT_RUNNING";
case JobSchedulerEconomicPolicy.ACTION_JOB_LOW_START:
return "JOB_LOW_START";
case JobSchedulerEconomicPolicy.ACTION_JOB_LOW_RUNNING:
return "JOB_LOW_RUNNING";
case JobSchedulerEconomicPolicy.ACTION_JOB_MIN_START:
return "JOB_MIN_START";
case JobSchedulerEconomicPolicy.ACTION_JOB_MIN_RUNNING:
return "JOB_MIN_RUNNING";
case JobSchedulerEconomicPolicy.ACTION_JOB_TIMEOUT:
return "JOB_TIMEOUT";
}
}
return "UNKNOWN_ACTION:" + Integer.toHexString(eventId);
}
@NonNull
static String regulationToString(int eventId) {
switch (eventId) {
case REGULATION_BASIC_INCOME:
return "BASIC_INCOME";
case REGULATION_BIRTHRIGHT:
return "BIRTHRIGHT";
case REGULATION_TAX:
return "TAX";
}
return "UNKNOWN_REGULATION:" + Integer.toHexString(eventId);
}
@NonNull
static String rewardToString(int eventId) {
switch (eventId) {
case REWARD_TOP_ACTIVITY:
return "REWARD_TOP_ACTIVITY";
case REWARD_NOTIFICATION_SEEN:
return "REWARD_NOTIFICATION_SEEN";
case REWARD_NOTIFICATION_INTERACTION:
return "REWARD_NOTIFICATION_INTERACTION";
case REWARD_WIDGET_INTERACTION:
return "REWARD_WIDGET_INTERACTION";
case REWARD_OTHER_USER_INTERACTION:
return "REWARD_OTHER_USER_INTERACTION";
}
return "UNKNOWN_REWARD:" + Integer.toHexString(eventId);
}
protected static void dumpActiveModifiers(IndentingPrintWriter pw) {
for (int i = 0; i < NUM_COST_MODIFIERS; ++i) {
pw.print("Modifier ");

View File

@@ -29,8 +29,8 @@ interface EconomyManagerInternal {
interface BalanceChangeListener {
/**
* Called when an app runs out of funds.
* {@link #noteOngoingEventStopped(int, String, String, String)} must still be called to formally
* end the action.
* {@link #noteOngoingEventStopped(int, String, int, String)} must still be called to
* formally end the action.
*/
void onBankruptcy(int userId, @NonNull String pkgName);
@@ -61,20 +61,20 @@ interface EconomyManagerInternal {
*
* @param tag An optional tag that can be used to differentiate the same event for the same app.
*/
void noteInstantaneousEvent(int userId, @NonNull String pkgName, @NonNull String event,
void noteInstantaneousEvent(int userId, @NonNull String pkgName, int eventId,
@Nullable String tag);
/**
* Note that a long-running event is starting. The event must be specified in one of the
* EconomicPolicies. You must always call
* {@link #noteOngoingEventStopped(int, String, String, String)} to end the event. Ongoing
* {@link #noteOngoingEventStopped(int, String, int, String)} to end the event. Ongoing
* events will be separated and grouped by event-tag combinations. There must be an equal
* number of start() and stop() calls for the same event-tag combination in order for the
* tracking to finally stop (ie. ongoing events are ref-counted).
*
* @param tag An optional tag that can be used to differentiate the same event for the same app.
*/
void noteOngoingEventStarted(int userId, @NonNull String pkgName, @NonNull String event,
void noteOngoingEventStarted(int userId, @NonNull String pkgName, int eventId,
@Nullable String tag);
/**
@@ -85,6 +85,6 @@ interface EconomyManagerInternal {
*
* @param tag An optional tag that can be used to differentiate the same event for the same app.
*/
void noteOngoingEventStopped(int userId, @NonNull String pkgName, @NonNull String event,
void noteOngoingEventStopped(int userId, @NonNull String pkgName, int eventId,
@Nullable String tag);
}

View File

@@ -374,18 +374,18 @@ public class InternalResourceService extends SystemService {
}
@Override
public void noteInstantaneousEvent(int userId, @NonNull String pkgName,
@NonNull String event, @Nullable String tag) {
public void noteInstantaneousEvent(int userId, @NonNull String pkgName, int eventId,
@Nullable String tag) {
}
@Override
public void noteOngoingEventStarted(int userId, @NonNull String pkgName,
@NonNull String event, @Nullable String tag) {
public void noteOngoingEventStarted(int userId, @NonNull String pkgName, int eventId,
@Nullable String tag) {
}
@Override
public void noteOngoingEventStopped(int userId, @NonNull String pkgName,
@NonNull String event, @Nullable String tag) {
public void noteOngoingEventStopped(int userId, @NonNull String pkgName, int eventId,
@Nullable String tag) {
}
}
}

View File

@@ -23,24 +23,24 @@ import static com.android.server.tare.TareUtils.arcToNarc;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.ArrayMap;
import android.util.SparseArray;
/**
* Policy defining pricing information and daily ARC requirements and suggestions for
* JobScheduler.
*/
public class JobSchedulerEconomicPolicy extends EconomicPolicy {
public static final String ACTION_JOB_MAX_START = "JOB_MAX_START";
public static final String ACTION_JOB_MAX_RUNNING = "JOB_MAX_RUNNING";
public static final String ACTION_JOB_HIGH_START = "JOB_HIGH_START";
public static final String ACTION_JOB_HIGH_RUNNING = "JOB_HIGH_RUNNING";
public static final String ACTION_JOB_DEFAULT_START = "JOB_DEFAULT_START";
public static final String ACTION_JOB_DEFAULT_RUNNING = "JOB_DEFAULT_RUNNING";
public static final String ACTION_JOB_LOW_START = "JOB_LOW_START";
public static final String ACTION_JOB_LOW_RUNNING = "JOB_LOW_RUNNING";
public static final String ACTION_JOB_MIN_START = "JOB_MIN_START";
public static final String ACTION_JOB_MIN_RUNNING = "JOB_MIN_RUNNING";
public static final String ACTION_JOB_TIMEOUT = "JOB_TIMEOUT";
public static final int ACTION_JOB_MAX_START = TYPE_ACTION | POLICY_JS | 0;
public static final int ACTION_JOB_MAX_RUNNING = TYPE_ACTION | POLICY_JS | 1;
public static final int ACTION_JOB_HIGH_START = TYPE_ACTION | POLICY_JS | 2;
public static final int ACTION_JOB_HIGH_RUNNING = TYPE_ACTION | POLICY_JS | 3;
public static final int ACTION_JOB_DEFAULT_START = TYPE_ACTION | POLICY_JS | 4;
public static final int ACTION_JOB_DEFAULT_RUNNING = TYPE_ACTION | POLICY_JS | 5;
public static final int ACTION_JOB_LOW_START = TYPE_ACTION | POLICY_JS | 6;
public static final int ACTION_JOB_LOW_RUNNING = TYPE_ACTION | POLICY_JS | 7;
public static final int ACTION_JOB_MIN_START = TYPE_ACTION | POLICY_JS | 8;
public static final int ACTION_JOB_MIN_RUNNING = TYPE_ACTION | POLICY_JS | 9;
public static final int ACTION_JOB_TIMEOUT = TYPE_ACTION | POLICY_JS | 10;
private static final int[] COST_MODIFIERS = new int[]{
COST_MODIFIER_CHARGING,
@@ -48,8 +48,8 @@ public class JobSchedulerEconomicPolicy extends EconomicPolicy {
COST_MODIFIER_PROCESS_STATE
};
private final ArrayMap<String, Action> mActions = new ArrayMap<>();
private final ArrayMap<String, Reward> mRewards = new ArrayMap<>();
private final SparseArray<Action> mActions = new SparseArray<>();
private final SparseArray<Reward> mRewards = new SparseArray<>();
JobSchedulerEconomicPolicy(InternalResourceService irs) {
super(irs);
@@ -81,14 +81,14 @@ public class JobSchedulerEconomicPolicy extends EconomicPolicy {
@Nullable
@Override
Action getAction(@NonNull String actionName) {
return mActions.get(actionName);
Action getAction(@AppAction int actionId) {
return mActions.get(actionId);
}
@Nullable
@Override
Reward getReward(@NonNull String rewardName) {
return mRewards.get(rewardName);
Reward getReward(@UtilityReward int rewardId) {
return mRewards.get(rewardId);
}
private void loadActions() {

View File

@@ -18,12 +18,13 @@ package com.android.server.tare;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
import static com.android.server.tare.TareUtils.narcToArc;
import static com.android.server.tare.TareUtils.dumpTime;
import static com.android.server.tare.TareUtils.narcToString;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.ArrayMap;
import android.util.IndentingPrintWriter;
import android.util.SparseLongArray;
import java.util.ArrayList;
import java.util.List;
@@ -35,17 +36,16 @@ class Ledger {
static class Transaction {
public final long startTimeMs;
public final long endTimeMs;
@NonNull
public final String reason;
public final int eventId;
@Nullable
public final String tag;
public final long delta;
Transaction(long startTimeMs, long endTimeMs,
@NonNull String reason, @Nullable String tag, long delta) {
int eventId, @Nullable String tag, long delta) {
this.startTimeMs = startTimeMs;
this.endTimeMs = endTimeMs;
this.reason = reason;
this.eventId = eventId;
this.tag = tag;
this.delta = delta;
}
@@ -54,7 +54,7 @@ class Ledger {
/** Last saved balance. This doesn't take currently ongoing events into account. */
private long mCurrentBalance = 0;
private final List<Transaction> mTransactions = new ArrayList<>();
private final ArrayMap<String, Long> mCumulativeDeltaPerReason = new ArrayMap<>();
private final SparseLongArray mCumulativeDeltaPerReason = new SparseLongArray();
private long mEarliestSumTime;
Ledger() {
@@ -68,16 +68,12 @@ class Ledger {
mTransactions.add(transaction);
mCurrentBalance += transaction.delta;
Long sum = mCumulativeDeltaPerReason.get(transaction.reason);
if (sum == null) {
sum = 0L;
}
sum += transaction.delta;
mCumulativeDeltaPerReason.put(transaction.reason, sum);
final long sum = mCumulativeDeltaPerReason.get(transaction.eventId);
mCumulativeDeltaPerReason.put(transaction.eventId, sum + transaction.delta);
mEarliestSumTime = Math.min(mEarliestSumTime, transaction.startTimeMs);
}
long get24HourSum(@NonNull String reason, final long now) {
long get24HourSum(int eventId, final long now) {
final long windowStartTime = now - 24 * HOUR_IN_MILLIS;
if (mEarliestSumTime < windowStartTime) {
// Need to redo sums
@@ -87,8 +83,7 @@ class Ledger {
if (transaction.endTimeMs <= windowStartTime) {
break;
}
final Long sumObj = mCumulativeDeltaPerReason.get(transaction.reason);
long sum = sumObj == null ? 0 : sumObj;
long sum = mCumulativeDeltaPerReason.get(transaction.eventId);
if (transaction.startTimeMs >= windowStartTime) {
sum += transaction.delta;
} else {
@@ -97,24 +92,23 @@ class Ledger {
* transaction.delta)
/ (transaction.endTimeMs - transaction.startTimeMs);
}
mCumulativeDeltaPerReason.put(transaction.reason, sum);
mCumulativeDeltaPerReason.put(transaction.eventId, sum);
}
mEarliestSumTime = windowStartTime;
}
Long sum = mCumulativeDeltaPerReason.get(reason);
if (sum == null) {
return 0;
}
return sum;
return mCumulativeDeltaPerReason.get(eventId);
}
void dump(IndentingPrintWriter pw) {
pw.println("Ledger{");
pw.increaseIndent();
pw.print("cur balance", narcToArc(getCurrentBalance())).println();
pw.decreaseIndent();
pw.println("}");
pw.print("Current balance", narcToString(getCurrentBalance())).println();
mTransactions.forEach((transaction) -> {
dumpTime(pw, transaction.startTimeMs);
pw.print("--");
dumpTime(pw, transaction.endTimeMs);
pw.print(": ");
pw.print(EconomicPolicy.eventToString(transaction.eventId));
pw.print(" --> ");
pw.println(narcToString(transaction.delta));
});
}
}

View File

@@ -16,12 +16,47 @@
package com.android.server.tare;
import android.annotation.NonNull;
import android.annotation.SuppressLint;
import android.util.IndentingPrintWriter;
import java.text.SimpleDateFormat;
class TareUtils {
private static final long NARC_IN_ARC = 1_000_000_000L;
@SuppressLint("SimpleDateFormat")
private static final SimpleDateFormat sDumpDateFormat =
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
static long arcToNarc(int arcs) {
return arcs * 1_000_000_000L;
return arcs * NARC_IN_ARC;
}
static void dumpTime(IndentingPrintWriter pw, long time) {
pw.print(sDumpDateFormat.format(time));
}
static int narcToArc(long narcs) {
return (int) (narcs / 1_000_000_000);
return (int) (narcs / NARC_IN_ARC);
}
@NonNull
static String narcToString(long narcs) {
if (narcs == 0) {
return "0 ARCs";
}
final long sub = Math.abs(narcs) % NARC_IN_ARC;
final long arcs = narcToArc(narcs);
if (arcs == 0) {
return sub + " narcs";
}
StringBuilder sb = new StringBuilder();
sb.append(arcs);
if (sub > 0) {
sb.append(".").append(sub / (NARC_IN_ARC / 1000));
}
sb.append(" ARCs");
return sb.toString();
}
}

View File

@@ -36,40 +36,40 @@ public class LedgerTest {
public void testInitialState() {
final Ledger ledger = new Ledger();
assertEquals(0, ledger.getCurrentBalance());
assertEquals(0, ledger.get24HourSum("anything", 0));
assertEquals(0, ledger.get24HourSum(0, 0));
}
@Test
public void testMultipleTransactions() {
final Ledger ledger = new Ledger();
ledger.recordTransaction(new Ledger.Transaction(0, 1000, "test", null, 5));
ledger.recordTransaction(new Ledger.Transaction(0, 1000, 1, null, 5));
assertEquals(5, ledger.getCurrentBalance());
assertEquals(5, ledger.get24HourSum("test", 60_000));
ledger.recordTransaction(new Ledger.Transaction(2000, 2000, "test", null, 25));
assertEquals(5, ledger.get24HourSum(1, 60_000));
ledger.recordTransaction(new Ledger.Transaction(2000, 2000, 1, null, 25));
assertEquals(30, ledger.getCurrentBalance());
assertEquals(30, ledger.get24HourSum("test", 60_000));
ledger.recordTransaction(new Ledger.Transaction(5000, 5500, "test", null, -10));
assertEquals(30, ledger.get24HourSum(1, 60_000));
ledger.recordTransaction(new Ledger.Transaction(5000, 5500, 1, null, -10));
assertEquals(20, ledger.getCurrentBalance());
assertEquals(20, ledger.get24HourSum("test", 60_000));
assertEquals(20, ledger.get24HourSum(1, 60_000));
}
@Test
public void test24HourSum() {
final Ledger ledger = new Ledger();
ledger.recordTransaction(new Ledger.Transaction(0, 1000, "test", null, 500));
assertEquals(500, ledger.get24HourSum("test", 24 * HOUR_IN_MILLIS));
ledger.recordTransaction(new Ledger.Transaction(0, 1000, 1, null, 500));
assertEquals(500, ledger.get24HourSum(1, 24 * HOUR_IN_MILLIS));
ledger.recordTransaction(
new Ledger.Transaction(2 * HOUR_IN_MILLIS, 3 * HOUR_IN_MILLIS, "test", null, 2500));
assertEquals(3000, ledger.get24HourSum("test", 24 * HOUR_IN_MILLIS));
new Ledger.Transaction(2 * HOUR_IN_MILLIS, 3 * HOUR_IN_MILLIS, 1, null, 2500));
assertEquals(3000, ledger.get24HourSum(1, 24 * HOUR_IN_MILLIS));
ledger.recordTransaction(
new Ledger.Transaction(4 * HOUR_IN_MILLIS, 4 * HOUR_IN_MILLIS, "test", null, 1));
assertEquals(3001, ledger.get24HourSum("test", 24 * HOUR_IN_MILLIS));
assertEquals(2501, ledger.get24HourSum("test", 25 * HOUR_IN_MILLIS));
assertEquals(2501, ledger.get24HourSum("test", 26 * HOUR_IN_MILLIS));
new Ledger.Transaction(4 * HOUR_IN_MILLIS, 4 * HOUR_IN_MILLIS, 1, null, 1));
assertEquals(3001, ledger.get24HourSum(1, 24 * HOUR_IN_MILLIS));
assertEquals(2501, ledger.get24HourSum(1, 25 * HOUR_IN_MILLIS));
assertEquals(2501, ledger.get24HourSum(1, 26 * HOUR_IN_MILLIS));
// Pro-rated as the second transaction phases out
assertEquals(1251,
ledger.get24HourSum("test", 26 * HOUR_IN_MILLIS + 30 * MINUTE_IN_MILLIS));
assertEquals(1, ledger.get24HourSum("test", 27 * HOUR_IN_MILLIS));
assertEquals(0, ledger.get24HourSum("test", 28 * HOUR_IN_MILLIS));
ledger.get24HourSum(1, 26 * HOUR_IN_MILLIS + 30 * MINUTE_IN_MILLIS));
assertEquals(1, ledger.get24HourSum(1, 27 * HOUR_IN_MILLIS));
assertEquals(0, ledger.get24HourSum(1, 28 * HOUR_IN_MILLIS));
}
}