Merge "Make TARE DeviceConfig-urable." into tm-dev
This commit is contained in:
@@ -16,8 +16,10 @@
|
||||
|
||||
package android.app.tare;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.SystemService;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Provides access to the resource economy service.
|
||||
@@ -26,6 +28,69 @@ import android.content.Context;
|
||||
*/
|
||||
@SystemService(Context.RESOURCE_ECONOMY_SERVICE)
|
||||
public class EconomyManager {
|
||||
private static final String TAG = "TARE-" + EconomyManager.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* 1 ARC = 1 GIGA-CAKE!
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final long CAKE_IN_ARC = 1_000_000_000L;
|
||||
|
||||
/** @hide */
|
||||
public static long arcToCake(int arcs) {
|
||||
return arcs * CAKE_IN_ARC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a configuration string to get the value in cakes.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static long parseCreditValue(@Nullable final String val, final long defaultValCakes) {
|
||||
String trunc;
|
||||
if (val == null || (trunc = val.trim()).isEmpty()) {
|
||||
return defaultValCakes;
|
||||
}
|
||||
long multiplier;
|
||||
if (trunc.endsWith("c")) {
|
||||
trunc = trunc.substring(0, trunc.length() - 1);
|
||||
multiplier = 1;
|
||||
} else if (trunc.endsWith("ck")) {
|
||||
trunc = trunc.substring(0, trunc.length() - 2);
|
||||
multiplier = 1;
|
||||
} else if (trunc.endsWith("A")) {
|
||||
trunc = trunc.substring(0, trunc.length() - 1);
|
||||
multiplier = CAKE_IN_ARC;
|
||||
} else if (trunc.endsWith("ARC")) {
|
||||
trunc = trunc.substring(0, trunc.length() - 3);
|
||||
multiplier = CAKE_IN_ARC;
|
||||
} else {
|
||||
// Don't risk using the wrong units
|
||||
Log.e(TAG, "Couldn't determine units of credit value: " + val);
|
||||
return defaultValCakes;
|
||||
}
|
||||
|
||||
// Allow people to shorten notation (eg. Mc for Megacake).
|
||||
if (trunc.endsWith("k")) {
|
||||
trunc = trunc.substring(0, trunc.length() - 1);
|
||||
multiplier *= 1_000;
|
||||
} else if (trunc.endsWith("M")) {
|
||||
trunc = trunc.substring(0, trunc.length() - 1);
|
||||
multiplier *= 1_000_000;
|
||||
} else if (trunc.endsWith("G")) {
|
||||
trunc = trunc.substring(0, trunc.length() - 1);
|
||||
multiplier *= 1_000_000_000;
|
||||
}
|
||||
|
||||
try {
|
||||
return Long.parseLong(trunc) * multiplier;
|
||||
} catch (NumberFormatException e) {
|
||||
Log.e(TAG, "Malformed config string: " + val + " to " + trunc, e);
|
||||
return defaultValCakes;
|
||||
}
|
||||
}
|
||||
|
||||
// Keys for AlarmManager TARE factors
|
||||
/** @hide */
|
||||
public static final String KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED =
|
||||
@@ -276,179 +341,201 @@ public class EconomyManager {
|
||||
|
||||
// Default values AlarmManager factors
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED = 500;
|
||||
public static final long DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED_CAKES = arcToCake(500);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP = 200;
|
||||
public static final long DEFAULT_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES =
|
||||
arcToCake(256);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP = 160;
|
||||
public static final long DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP_CAKES = arcToCake(160);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_MAX_SATIATED_BALANCE = 1440;
|
||||
public static final long DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES = arcToCake(960);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT = 4000;
|
||||
public static final long DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT_CAKES = arcToCake(2880);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_HARD_CONSUMPTION_LIMIT = 28_800;
|
||||
public static final long DEFAULT_AM_HARD_CONSUMPTION_LIMIT_CAKES = arcToCake(15_000);
|
||||
// TODO: add AlarmManager modifier default values
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_REWARD_TOP_ACTIVITY_INSTANT = 0;
|
||||
public static final long DEFAULT_AM_REWARD_TOP_ACTIVITY_INSTANT_CAKES = arcToCake(0);
|
||||
/** @hide */
|
||||
public static final float DEFAULT_AM_REWARD_TOP_ACTIVITY_ONGOING = 0.01f;
|
||||
// 10 megacakes = .01 ARC
|
||||
public static final long DEFAULT_AM_REWARD_TOP_ACTIVITY_ONGOING_CAKES = 10_000_000;
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_REWARD_TOP_ACTIVITY_MAX = 500;
|
||||
public static final long DEFAULT_AM_REWARD_TOP_ACTIVITY_MAX_CAKES = arcToCake(500);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_REWARD_NOTIFICATION_SEEN_INSTANT = 3;
|
||||
public static final long DEFAULT_AM_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES = arcToCake(3);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_REWARD_NOTIFICATION_SEEN_ONGOING = 0;
|
||||
public static final long DEFAULT_AM_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES = arcToCake(0);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_REWARD_NOTIFICATION_SEEN_MAX = 60;
|
||||
public static final long DEFAULT_AM_REWARD_NOTIFICATION_SEEN_MAX_CAKES = arcToCake(60);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_INSTANT = 5;
|
||||
public static final long DEFAULT_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_INSTANT_CAKES =
|
||||
arcToCake(5);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_ONGOING = 0;
|
||||
public static final long DEFAULT_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_ONGOING_CAKES =
|
||||
arcToCake(0);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_MAX = 500;
|
||||
public static final long DEFAULT_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_MAX_CAKES =
|
||||
arcToCake(500);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT = 5;
|
||||
public static final long DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES =
|
||||
arcToCake(5);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING = 0;
|
||||
public static final long DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES =
|
||||
arcToCake(0);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_MAX = 500;
|
||||
public static final long DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES = arcToCake(500);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_REWARD_WIDGET_INTERACTION_INSTANT = 10;
|
||||
public static final long DEFAULT_AM_REWARD_WIDGET_INTERACTION_INSTANT_CAKES = arcToCake(10);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_REWARD_WIDGET_INTERACTION_ONGOING = 0;
|
||||
public static final long DEFAULT_AM_REWARD_WIDGET_INTERACTION_ONGOING_CAKES = arcToCake(0);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_REWARD_WIDGET_INTERACTION_MAX = 500;
|
||||
public static final long DEFAULT_AM_REWARD_WIDGET_INTERACTION_MAX_CAKES = arcToCake(500);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_INSTANT = 10;
|
||||
public static final long DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES = arcToCake(10);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_ONGOING = 0;
|
||||
public static final long DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES = arcToCake(0);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_MAX = 500;
|
||||
public static final long DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_MAX_CAKES = arcToCake(500);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP = 3;
|
||||
public static final long DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP_CAKES =
|
||||
arcToCake(3);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP = 3;
|
||||
public static final long DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP_CAKES =
|
||||
arcToCake(3);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_CTP = 3;
|
||||
public static final long DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_CTP_CAKES = arcToCake(3);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP = 3;
|
||||
public static final long DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP_CAKES = arcToCake(3);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP = 1;
|
||||
public static final long DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP_CAKES =
|
||||
arcToCake(1);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP = 1;
|
||||
public static final long DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP_CAKES = arcToCake(1);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP = 1;
|
||||
public static final long DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP_CAKES =
|
||||
arcToCake(1);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP = 1;
|
||||
public static final long DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP_CAKES = arcToCake(1);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_CTP = 5;
|
||||
public static final long DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_CTP_CAKES = arcToCake(5);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE = 5;
|
||||
public static final long
|
||||
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE_CAKES = arcToCake(5);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE = 4;
|
||||
public static final long
|
||||
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE_CAKES = arcToCake(4);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE = 4;
|
||||
public static final long DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE_CAKES = arcToCake(4);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE = 3;
|
||||
public static final long DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE_CAKES = arcToCake(3);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_BASE_PRICE = 3;
|
||||
public static final long
|
||||
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_BASE_PRICE_CAKES =
|
||||
arcToCake(3);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE = 2;
|
||||
public static final long DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE_CAKES =
|
||||
arcToCake(2);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE =
|
||||
2;
|
||||
public static final long
|
||||
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE_CAKES =
|
||||
arcToCake(2);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE = 1;
|
||||
public static final long DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE_CAKES =
|
||||
arcToCake(1);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE = 10;
|
||||
public static final long DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE_CAKES = arcToCake(10);
|
||||
|
||||
// Default values JobScheduler factors
|
||||
// TODO: add time_since_usage variable to min satiated balance factors
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED = 20000;
|
||||
public static final long DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED_CAKES = arcToCake(15000);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP = 10000;
|
||||
public static final long DEFAULT_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES =
|
||||
arcToCake(7500);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP = 2000;
|
||||
public static final long DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES = arcToCake(2000);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_MAX_SATIATED_BALANCE = 60000;
|
||||
public static final long DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES = arcToCake(60000);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT = 100_000;
|
||||
public static final long DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT_CAKES = arcToCake(29_000);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_HARD_CONSUMPTION_LIMIT = 460_000;
|
||||
// TODO: set hard limit based on device type (phone vs tablet vs etc) + battery size
|
||||
public static final long DEFAULT_JS_HARD_CONSUMPTION_LIMIT_CAKES = arcToCake(250_000);
|
||||
// TODO: add JobScheduler modifier default values
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_REWARD_TOP_ACTIVITY_INSTANT = 0;
|
||||
public static final long DEFAULT_JS_REWARD_TOP_ACTIVITY_INSTANT_CAKES = arcToCake(0);
|
||||
/** @hide */
|
||||
public static final float DEFAULT_JS_REWARD_TOP_ACTIVITY_ONGOING = 0.5f;
|
||||
public static final long DEFAULT_JS_REWARD_TOP_ACTIVITY_ONGOING_CAKES = CAKE_IN_ARC / 2;
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_REWARD_TOP_ACTIVITY_MAX = 15000;
|
||||
public static final long DEFAULT_JS_REWARD_TOP_ACTIVITY_MAX_CAKES = arcToCake(15000);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_REWARD_NOTIFICATION_SEEN_INSTANT = 1;
|
||||
public static final long DEFAULT_JS_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES = arcToCake(1);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_REWARD_NOTIFICATION_SEEN_ONGOING = 0;
|
||||
public static final long DEFAULT_JS_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES = arcToCake(0);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_REWARD_NOTIFICATION_SEEN_MAX = 10;
|
||||
public static final long DEFAULT_JS_REWARD_NOTIFICATION_SEEN_MAX_CAKES = arcToCake(10);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT = 5;
|
||||
public static final long DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES =
|
||||
arcToCake(5);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING = 0;
|
||||
public static final long DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES =
|
||||
arcToCake(0);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX = 5000;
|
||||
public static final long DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES = arcToCake(5000);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_REWARD_WIDGET_INTERACTION_INSTANT = 10;
|
||||
public static final long DEFAULT_JS_REWARD_WIDGET_INTERACTION_INSTANT_CAKES = arcToCake(10);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_REWARD_WIDGET_INTERACTION_ONGOING = 0;
|
||||
public static final long DEFAULT_JS_REWARD_WIDGET_INTERACTION_ONGOING_CAKES = arcToCake(0);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_REWARD_WIDGET_INTERACTION_MAX = 5000;
|
||||
public static final long DEFAULT_JS_REWARD_WIDGET_INTERACTION_MAX_CAKES = arcToCake(5000);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_INSTANT = 10;
|
||||
public static final long DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES = arcToCake(10);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_ONGOING = 0;
|
||||
public static final long DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES = arcToCake(0);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX = 5000;
|
||||
public static final long DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX_CAKES = arcToCake(5000);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_ACTION_JOB_MAX_START_CTP = 3;
|
||||
public static final long DEFAULT_JS_ACTION_JOB_MAX_START_CTP_CAKES = arcToCake(3);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_ACTION_JOB_MAX_RUNNING_CTP = 2;
|
||||
public static final long DEFAULT_JS_ACTION_JOB_MAX_RUNNING_CTP_CAKES = arcToCake(2);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_ACTION_JOB_HIGH_START_CTP = 3;
|
||||
public static final long DEFAULT_JS_ACTION_JOB_HIGH_START_CTP_CAKES = arcToCake(3);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_CTP = 2;
|
||||
public static final long DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_CTP_CAKES = arcToCake(2);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_ACTION_JOB_DEFAULT_START_CTP = 3;
|
||||
public static final long DEFAULT_JS_ACTION_JOB_DEFAULT_START_CTP_CAKES = arcToCake(3);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_CTP = 2;
|
||||
public static final long DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_CTP_CAKES = arcToCake(2);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_ACTION_JOB_LOW_START_CTP = 3;
|
||||
public static final long DEFAULT_JS_ACTION_JOB_LOW_START_CTP_CAKES = arcToCake(3);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_ACTION_JOB_LOW_RUNNING_CTP = 2;
|
||||
public static final long DEFAULT_JS_ACTION_JOB_LOW_RUNNING_CTP_CAKES = arcToCake(2);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_ACTION_JOB_MIN_START_CTP = 3;
|
||||
public static final long DEFAULT_JS_ACTION_JOB_MIN_START_CTP_CAKES = arcToCake(3);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_ACTION_JOB_MIN_RUNNING_CTP = 2;
|
||||
public static final long DEFAULT_JS_ACTION_JOB_MIN_RUNNING_CTP_CAKES = arcToCake(2);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP = 30;
|
||||
public static final long DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP_CAKES = arcToCake(30);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_ACTION_JOB_MAX_START_BASE_PRICE = 10;
|
||||
public static final long DEFAULT_JS_ACTION_JOB_MAX_START_BASE_PRICE_CAKES = arcToCake(10);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE = 5;
|
||||
public static final long DEFAULT_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE_CAKES = arcToCake(5);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_ACTION_JOB_HIGH_START_BASE_PRICE = 8;
|
||||
public static final long DEFAULT_JS_ACTION_JOB_HIGH_START_BASE_PRICE_CAKES = arcToCake(8);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE = 4;
|
||||
public static final long DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE_CAKES = arcToCake(4);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE = 6;
|
||||
public static final long DEFAULT_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE_CAKES = arcToCake(6);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE = 3;
|
||||
public static final long DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE_CAKES = arcToCake(3);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_ACTION_JOB_LOW_START_BASE_PRICE = 4;
|
||||
public static final long DEFAULT_JS_ACTION_JOB_LOW_START_BASE_PRICE_CAKES = arcToCake(4);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE = 2;
|
||||
public static final long DEFAULT_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE_CAKES = arcToCake(2);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_ACTION_JOB_MIN_START_BASE_PRICE = 2;
|
||||
public static final long DEFAULT_JS_ACTION_JOB_MIN_START_BASE_PRICE_CAKES = arcToCake(2);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE = 1;
|
||||
public static final long DEFAULT_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE_CAKES = arcToCake(1);
|
||||
/** @hide */
|
||||
public static final int DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE = 60;
|
||||
public static final long DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE_CAKES = arcToCake(60);
|
||||
}
|
||||
|
||||
@@ -16,43 +16,43 @@
|
||||
|
||||
package com.android.server.tare;
|
||||
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_CTP;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_CTP;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_HARD_CONSUMPTION_LIMIT;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_MAX_SATIATED_BALANCE;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_MAX;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_INSTANT;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_MAX;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_ONGOING;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_INSTANT;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_MAX;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_ONGOING;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_TOP_ACTIVITY_INSTANT;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_TOP_ACTIVITY_MAX;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_TOP_ACTIVITY_ONGOING;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_WIDGET_INTERACTION_INSTANT;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_WIDGET_INTERACTION_MAX;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_WIDGET_INTERACTION_ONGOING;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_CTP_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_CTP_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_HARD_CONSUMPTION_LIMIT_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_MAX_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_MAX_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_TOP_ACTIVITY_INSTANT_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_TOP_ACTIVITY_MAX_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_TOP_ACTIVITY_ONGOING_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_WIDGET_INTERACTION_INSTANT_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_WIDGET_INTERACTION_MAX_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_WIDGET_INTERACTION_ONGOING_CAKES;
|
||||
import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE;
|
||||
import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALARMCLOCK_CTP;
|
||||
import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_BASE_PRICE;
|
||||
@@ -97,12 +97,12 @@ import static com.android.server.tare.Modifier.COST_MODIFIER_CHARGING;
|
||||
import static com.android.server.tare.Modifier.COST_MODIFIER_DEVICE_IDLE;
|
||||
import static com.android.server.tare.Modifier.COST_MODIFIER_POWER_SAVE_MODE;
|
||||
import static com.android.server.tare.Modifier.COST_MODIFIER_PROCESS_STATE;
|
||||
import static com.android.server.tare.TareUtils.arcToCake;
|
||||
import static com.android.server.tare.TareUtils.cakeToString;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.ContentResolver;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.provider.Settings;
|
||||
import android.util.IndentingPrintWriter;
|
||||
import android.util.KeyValueListParser;
|
||||
@@ -157,14 +157,15 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy {
|
||||
AlarmManagerEconomicPolicy(InternalResourceService irs) {
|
||||
super(irs);
|
||||
mInternalResourceService = irs;
|
||||
loadConstants("");
|
||||
loadConstants("", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
void setup() {
|
||||
super.setup();
|
||||
void setup(@NonNull DeviceConfig.Properties properties) {
|
||||
super.setup(properties);
|
||||
ContentResolver resolver = mInternalResourceService.getContext().getContentResolver();
|
||||
loadConstants(Settings.Global.getString(resolver, TARE_ALARM_MANAGER_CONSTANTS));
|
||||
loadConstants(Settings.Global.getString(resolver, TARE_ALARM_MANAGER_CONSTANTS),
|
||||
properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -178,6 +179,11 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy {
|
||||
|
||||
@Override
|
||||
long getMaxSatiatedBalance() {
|
||||
// TODO(230501287): adjust balance based on whether the app has the SCHEDULE_EXACT_ALARM
|
||||
// permission granted. Apps without the permission granted shouldn't need a high balance
|
||||
// since they won't be able to use exact alarms. Apps with the permission granted could
|
||||
// have a higher balance, or perhaps just those with the USE_EXACT_ALARM permission since
|
||||
// that is limited to specific use cases.
|
||||
return mMaxSatiatedBalance;
|
||||
}
|
||||
|
||||
@@ -209,7 +215,8 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy {
|
||||
return mRewards.get(rewardId);
|
||||
}
|
||||
|
||||
private void loadConstants(String policyValuesString) {
|
||||
private void loadConstants(String policyValuesString,
|
||||
@Nullable DeviceConfig.Properties properties) {
|
||||
mActions.clear();
|
||||
mRewards.clear();
|
||||
|
||||
@@ -219,145 +226,159 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy {
|
||||
Slog.e(TAG, "Global setting key incorrect: ", e);
|
||||
}
|
||||
|
||||
mMinSatiatedBalanceExempted = arcToCake(mParser.getInt(KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED,
|
||||
DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED));
|
||||
mMinSatiatedBalanceOther = arcToCake(mParser.getInt(KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP,
|
||||
DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP));
|
||||
mMaxSatiatedBalance = arcToCake(mParser.getInt(KEY_AM_MAX_SATIATED_BALANCE,
|
||||
DEFAULT_AM_MAX_SATIATED_BALANCE));
|
||||
mInitialSatiatedConsumptionLimit = arcToCake(mParser.getInt(
|
||||
KEY_AM_INITIAL_CONSUMPTION_LIMIT, DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT));
|
||||
mMinSatiatedBalanceExempted = getConstantAsCake(mParser, properties,
|
||||
KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED,
|
||||
DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED_CAKES);
|
||||
mMinSatiatedBalanceOther = getConstantAsCake(mParser, properties,
|
||||
KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP,
|
||||
DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP_CAKES);
|
||||
mMaxSatiatedBalance = getConstantAsCake(mParser, properties,
|
||||
KEY_AM_MAX_SATIATED_BALANCE,
|
||||
DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES);
|
||||
mInitialSatiatedConsumptionLimit = getConstantAsCake(mParser, properties,
|
||||
KEY_AM_INITIAL_CONSUMPTION_LIMIT, DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT_CAKES);
|
||||
mHardSatiatedConsumptionLimit = Math.max(mInitialSatiatedConsumptionLimit,
|
||||
arcToCake(mParser.getInt(
|
||||
KEY_AM_HARD_CONSUMPTION_LIMIT, DEFAULT_AM_HARD_CONSUMPTION_LIMIT)));
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_HARD_CONSUMPTION_LIMIT, DEFAULT_AM_HARD_CONSUMPTION_LIMIT_CAKES));
|
||||
|
||||
final long exactAllowWhileIdleWakeupBasePrice = arcToCake(
|
||||
mParser.getInt(KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE,
|
||||
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE));
|
||||
final long exactAllowWhileIdleWakeupBasePrice = getConstantAsCake(mParser, properties,
|
||||
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE,
|
||||
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE_CAKES);
|
||||
|
||||
mActions.put(ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE,
|
||||
new Action(ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE,
|
||||
arcToCake(mParser.getInt(
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP,
|
||||
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP)),
|
||||
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP_CAKES),
|
||||
exactAllowWhileIdleWakeupBasePrice));
|
||||
mActions.put(ACTION_ALARM_WAKEUP_EXACT,
|
||||
new Action(ACTION_ALARM_WAKEUP_EXACT,
|
||||
arcToCake(mParser.getInt(KEY_AM_ACTION_ALARM_EXACT_WAKEUP_CTP,
|
||||
DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_CTP)),
|
||||
arcToCake(mParser.getInt(KEY_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE,
|
||||
DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE))));
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_ACTION_ALARM_EXACT_WAKEUP_CTP,
|
||||
DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_CTP_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE,
|
||||
DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE_CAKES)));
|
||||
|
||||
final long inexactAllowWhileIdleWakeupBasePrice =
|
||||
arcToCake(mParser.getInt(
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE,
|
||||
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE));
|
||||
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE_CAKES);
|
||||
|
||||
mActions.put(ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE,
|
||||
new Action(ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE,
|
||||
arcToCake(mParser.getInt(
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP,
|
||||
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP)),
|
||||
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP_CAKES),
|
||||
inexactAllowWhileIdleWakeupBasePrice));
|
||||
mActions.put(ACTION_ALARM_WAKEUP_INEXACT,
|
||||
new Action(ACTION_ALARM_WAKEUP_INEXACT,
|
||||
arcToCake(mParser.getInt(
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP,
|
||||
DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP)),
|
||||
arcToCake(mParser.getInt(
|
||||
DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE,
|
||||
DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE))));
|
||||
|
||||
final long exactAllowWhileIdleNonWakeupBasePrice =
|
||||
arcToCake(mParser.getInt(
|
||||
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_BASE_PRICE,
|
||||
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE));
|
||||
DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE_CAKES)));
|
||||
|
||||
final long exactAllowWhileIdleNonWakeupBasePrice = getConstantAsCake(mParser, properties,
|
||||
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_BASE_PRICE,
|
||||
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE_CAKES);
|
||||
mActions.put(ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE,
|
||||
new Action(ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE,
|
||||
arcToCake(mParser.getInt(
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP,
|
||||
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP)),
|
||||
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP_CAKES),
|
||||
exactAllowWhileIdleNonWakeupBasePrice));
|
||||
|
||||
mActions.put(ACTION_ALARM_NONWAKEUP_EXACT,
|
||||
new Action(ACTION_ALARM_NONWAKEUP_EXACT,
|
||||
arcToCake(mParser.getInt(
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP,
|
||||
DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP)),
|
||||
arcToCake(mParser.getInt(
|
||||
DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE,
|
||||
DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE))));
|
||||
|
||||
final long inexactAllowWhileIdleNonWakeupBasePrice =
|
||||
arcToCake(mParser.getInt(
|
||||
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE,
|
||||
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE));
|
||||
DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE_CAKES)));
|
||||
|
||||
final long inexactAllowWhileIdleNonWakeupBasePrice = getConstantAsCake(mParser, properties,
|
||||
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE,
|
||||
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE_CAKES);
|
||||
final long inexactAllowWhileIdleNonWakeupCtp = getConstantAsCake(mParser, properties,
|
||||
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP,
|
||||
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP_CAKES);
|
||||
mActions.put(ACTION_ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE,
|
||||
new Action(ACTION_ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE,
|
||||
arcToCake(mParser.getInt(
|
||||
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP,
|
||||
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP)),
|
||||
inexactAllowWhileIdleNonWakeupCtp,
|
||||
inexactAllowWhileIdleNonWakeupBasePrice));
|
||||
|
||||
mActions.put(ACTION_ALARM_NONWAKEUP_INEXACT,
|
||||
new Action(ACTION_ALARM_NONWAKEUP_INEXACT,
|
||||
arcToCake(mParser.getInt(
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP,
|
||||
DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP)),
|
||||
arcToCake(mParser.getInt(
|
||||
DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE,
|
||||
DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE))));
|
||||
DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE_CAKES)));
|
||||
mActions.put(ACTION_ALARM_CLOCK,
|
||||
new Action(ACTION_ALARM_CLOCK,
|
||||
arcToCake(mParser.getInt(
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_ACTION_ALARM_ALARMCLOCK_CTP,
|
||||
DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_CTP)),
|
||||
arcToCake(mParser.getInt(
|
||||
DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_CTP_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE,
|
||||
DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE))));
|
||||
DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE_CAKES)));
|
||||
|
||||
mRewards.put(REWARD_TOP_ACTIVITY, new Reward(REWARD_TOP_ACTIVITY,
|
||||
arcToCake(mParser.getInt(KEY_AM_REWARD_TOP_ACTIVITY_INSTANT,
|
||||
DEFAULT_AM_REWARD_TOP_ACTIVITY_INSTANT)),
|
||||
(long) (arcToCake(1) * mParser.getFloat(KEY_AM_REWARD_TOP_ACTIVITY_ONGOING,
|
||||
DEFAULT_AM_REWARD_TOP_ACTIVITY_ONGOING)),
|
||||
arcToCake(mParser.getInt(KEY_AM_REWARD_TOP_ACTIVITY_MAX,
|
||||
DEFAULT_AM_REWARD_TOP_ACTIVITY_MAX))));
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_REWARD_TOP_ACTIVITY_INSTANT,
|
||||
DEFAULT_AM_REWARD_TOP_ACTIVITY_INSTANT_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_REWARD_TOP_ACTIVITY_ONGOING,
|
||||
DEFAULT_AM_REWARD_TOP_ACTIVITY_ONGOING_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_REWARD_TOP_ACTIVITY_MAX,
|
||||
DEFAULT_AM_REWARD_TOP_ACTIVITY_MAX_CAKES)));
|
||||
mRewards.put(REWARD_NOTIFICATION_SEEN, new Reward(REWARD_NOTIFICATION_SEEN,
|
||||
arcToCake(mParser.getInt(KEY_AM_REWARD_NOTIFICATION_SEEN_INSTANT,
|
||||
DEFAULT_AM_REWARD_NOTIFICATION_SEEN_INSTANT)),
|
||||
arcToCake(mParser.getInt(KEY_AM_REWARD_NOTIFICATION_SEEN_ONGOING,
|
||||
DEFAULT_AM_REWARD_NOTIFICATION_SEEN_ONGOING)),
|
||||
arcToCake(mParser.getInt(KEY_AM_REWARD_NOTIFICATION_SEEN_MAX,
|
||||
DEFAULT_AM_REWARD_NOTIFICATION_SEEN_MAX))));
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_REWARD_NOTIFICATION_SEEN_INSTANT,
|
||||
DEFAULT_AM_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_REWARD_NOTIFICATION_SEEN_ONGOING,
|
||||
DEFAULT_AM_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_REWARD_NOTIFICATION_SEEN_MAX,
|
||||
DEFAULT_AM_REWARD_NOTIFICATION_SEEN_MAX_CAKES)));
|
||||
mRewards.put(REWARD_NOTIFICATION_INTERACTION,
|
||||
new Reward(REWARD_NOTIFICATION_INTERACTION,
|
||||
arcToCake(mParser.getInt(
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT,
|
||||
DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT)),
|
||||
arcToCake(mParser.getInt(
|
||||
DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING,
|
||||
DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING)),
|
||||
arcToCake(mParser.getInt(
|
||||
DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_REWARD_NOTIFICATION_INTERACTION_MAX,
|
||||
DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_MAX))));
|
||||
DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES)));
|
||||
mRewards.put(REWARD_WIDGET_INTERACTION, new Reward(REWARD_WIDGET_INTERACTION,
|
||||
arcToCake(mParser.getInt(KEY_AM_REWARD_WIDGET_INTERACTION_INSTANT,
|
||||
DEFAULT_AM_REWARD_WIDGET_INTERACTION_INSTANT)),
|
||||
arcToCake(mParser.getInt(KEY_AM_REWARD_WIDGET_INTERACTION_ONGOING,
|
||||
DEFAULT_AM_REWARD_WIDGET_INTERACTION_ONGOING)),
|
||||
arcToCake(mParser.getInt(KEY_AM_REWARD_WIDGET_INTERACTION_MAX,
|
||||
DEFAULT_AM_REWARD_WIDGET_INTERACTION_MAX))));
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_REWARD_WIDGET_INTERACTION_INSTANT,
|
||||
DEFAULT_AM_REWARD_WIDGET_INTERACTION_INSTANT_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_REWARD_WIDGET_INTERACTION_ONGOING,
|
||||
DEFAULT_AM_REWARD_WIDGET_INTERACTION_ONGOING_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_REWARD_WIDGET_INTERACTION_MAX,
|
||||
DEFAULT_AM_REWARD_WIDGET_INTERACTION_MAX_CAKES)));
|
||||
mRewards.put(REWARD_OTHER_USER_INTERACTION,
|
||||
new Reward(REWARD_OTHER_USER_INTERACTION,
|
||||
arcToCake(mParser.getInt(KEY_AM_REWARD_OTHER_USER_INTERACTION_INSTANT,
|
||||
DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_INSTANT)),
|
||||
arcToCake(mParser.getInt(
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_REWARD_OTHER_USER_INTERACTION_INSTANT,
|
||||
DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_REWARD_OTHER_USER_INTERACTION_ONGOING,
|
||||
DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_ONGOING)),
|
||||
arcToCake(mParser.getInt(
|
||||
DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_AM_REWARD_OTHER_USER_INTERACTION_MAX,
|
||||
DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_MAX))));
|
||||
DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_MAX_CAKES)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.server.tare;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.util.ArraySet;
|
||||
import android.util.IndentingPrintWriter;
|
||||
import android.util.SparseArray;
|
||||
@@ -57,10 +58,10 @@ public class CompleteEconomicPolicy extends EconomicPolicy {
|
||||
}
|
||||
|
||||
@Override
|
||||
void setup() {
|
||||
super.setup();
|
||||
void setup(@NonNull DeviceConfig.Properties properties) {
|
||||
super.setup(properties);
|
||||
for (int i = 0; i < mEnabledEconomicPolicies.size(); ++i) {
|
||||
mEnabledEconomicPolicies.valueAt(i).setup();
|
||||
mEnabledEconomicPolicies.valueAt(i).setup(properties);
|
||||
}
|
||||
updateMaxBalances();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.server.tare;
|
||||
|
||||
import static android.app.tare.EconomyManager.parseCreditValue;
|
||||
|
||||
import static com.android.server.tare.Modifier.COST_MODIFIER_CHARGING;
|
||||
import static com.android.server.tare.Modifier.COST_MODIFIER_DEVICE_IDLE;
|
||||
import static com.android.server.tare.Modifier.COST_MODIFIER_POWER_SAVE_MODE;
|
||||
@@ -27,7 +29,9 @@ import android.annotation.CallSuper;
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.util.IndentingPrintWriter;
|
||||
import android.util.KeyValueListParser;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -170,7 +174,7 @@ public abstract class EconomicPolicy {
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
void setup() {
|
||||
void setup(@NonNull DeviceConfig.Properties properties) {
|
||||
for (int i = 0; i < NUM_COST_MODIFIERS; ++i) {
|
||||
final Modifier modifier = COST_MODIFIER_BY_INDEX[i];
|
||||
if (modifier != null) {
|
||||
@@ -409,6 +413,22 @@ public abstract class EconomicPolicy {
|
||||
return "UNKNOWN_REWARD:" + Integer.toHexString(eventId);
|
||||
}
|
||||
|
||||
protected long getConstantAsCake(@NonNull KeyValueListParser parser,
|
||||
@Nullable DeviceConfig.Properties properties, String key, long defaultValCake) {
|
||||
// Don't cross the streams! Mixing Settings/local user config changes with DeviceConfig
|
||||
// config can cause issues since the scales may be different, so use one or the other.
|
||||
if (parser.size() > 0) {
|
||||
// User settings take precedence. Just stick with the Settings constants, even if there
|
||||
// are invalid values. It's not worth the time to evaluate all the key/value pairs to
|
||||
// make sure there are valid ones before deciding.
|
||||
return parseCreditValue(parser.getString(key, null), defaultValCake);
|
||||
}
|
||||
if (properties != null) {
|
||||
return parseCreditValue(properties.getString(key, null), defaultValCake);
|
||||
}
|
||||
return defaultValCake;
|
||||
}
|
||||
|
||||
protected static void dumpActiveModifiers(IndentingPrintWriter pw) {
|
||||
for (int i = 0; i < NUM_COST_MODIFIERS; ++i) {
|
||||
pw.print("Modifier ");
|
||||
|
||||
@@ -731,7 +731,7 @@ public class InternalResourceService extends SystemService {
|
||||
registerListeners();
|
||||
mCurrentBatteryLevel = getCurrentBatteryLevel();
|
||||
mHandler.post(this::setupHeavyWork);
|
||||
mCompleteEconomicPolicy.setup();
|
||||
mCompleteEconomicPolicy.setup(mConfigObserver.getAllDeviceConfigProperties());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1014,10 +1014,17 @@ public class InternalResourceService extends SystemService {
|
||||
Settings.Global.getUriFor(TARE_ALARM_MANAGER_CONSTANTS), false, this);
|
||||
mContentResolver.registerContentObserver(
|
||||
Settings.Global.getUriFor(TARE_JOB_SCHEDULER_CONSTANTS), false, this);
|
||||
onPropertiesChanged(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_TARE));
|
||||
onPropertiesChanged(getAllDeviceConfigProperties());
|
||||
updateEnabledStatus();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
DeviceConfig.Properties getAllDeviceConfigProperties() {
|
||||
// Don't want to cache the Properties object locally in case it ends up being large,
|
||||
// especially since it'll only be used once/infrequently (during setup or on a change).
|
||||
return DeviceConfig.getProperties(DeviceConfig.NAMESPACE_TARE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(boolean selfChange, Uri uri) {
|
||||
if (uri.equals(Settings.Global.getUriFor(Settings.Global.ENABLE_TARE))) {
|
||||
@@ -1030,6 +1037,7 @@ public class InternalResourceService extends SystemService {
|
||||
|
||||
@Override
|
||||
public void onPropertiesChanged(DeviceConfig.Properties properties) {
|
||||
boolean economicPolicyUpdated = false;
|
||||
synchronized (mLock) {
|
||||
for (String name : properties.getKeyset()) {
|
||||
if (name == null) {
|
||||
@@ -1039,6 +1047,12 @@ public class InternalResourceService extends SystemService {
|
||||
case KEY_DC_ENABLE_TARE:
|
||||
updateEnabledStatus();
|
||||
break;
|
||||
default:
|
||||
if (!economicPolicyUpdated
|
||||
&& (name.startsWith("am") || name.startsWith("js"))) {
|
||||
updateEconomicPolicy();
|
||||
economicPolicyUpdated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1072,7 +1086,7 @@ public class InternalResourceService extends SystemService {
|
||||
mCompleteEconomicPolicy.tearDown();
|
||||
mCompleteEconomicPolicy = new CompleteEconomicPolicy(InternalResourceService.this);
|
||||
if (mIsEnabled && mBootPhase >= PHASE_SYSTEM_SERVICES_READY) {
|
||||
mCompleteEconomicPolicy.setup();
|
||||
mCompleteEconomicPolicy.setup(getAllDeviceConfigProperties());
|
||||
if (initialLimit != mCompleteEconomicPolicy.getInitialSatiatedConsumptionLimit()
|
||||
|| hardLimit
|
||||
!= mCompleteEconomicPolicy.getHardSatiatedConsumptionLimit()) {
|
||||
|
||||
@@ -16,48 +16,48 @@
|
||||
|
||||
package com.android.server.tare;
|
||||
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_CTP;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_START_CTP;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_CTP;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_START_BASE_PRICE;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_START_CTP;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_RUNNING_CTP;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_START_BASE_PRICE;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_START_CTP;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_RUNNING_CTP;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_START_BASE_PRICE;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_START_CTP;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_RUNNING_CTP;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_START_BASE_PRICE;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_START_CTP;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_HARD_CONSUMPTION_LIMIT;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_MAX_SATIATED_BALANCE;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_INSTANT;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_MAX;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_ONGOING;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_INSTANT;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_ONGOING;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_INSTANT;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_MAX;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_ONGOING;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_INSTANT;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_MAX;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_ONGOING;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_CTP_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_START_CTP_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_CTP_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_START_BASE_PRICE_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_START_CTP_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_RUNNING_CTP_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_START_BASE_PRICE_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_START_CTP_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_RUNNING_CTP_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_START_BASE_PRICE_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_START_CTP_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_RUNNING_CTP_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_START_BASE_PRICE_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_START_CTP_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_HARD_CONSUMPTION_LIMIT_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_MAX_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_INSTANT_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_MAX_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_ONGOING_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_INSTANT_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_MAX_CAKES;
|
||||
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_ONGOING_CAKES;
|
||||
import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE;
|
||||
import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_RUNNING_CTP;
|
||||
import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE;
|
||||
@@ -106,12 +106,12 @@ import static com.android.server.tare.Modifier.COST_MODIFIER_CHARGING;
|
||||
import static com.android.server.tare.Modifier.COST_MODIFIER_DEVICE_IDLE;
|
||||
import static com.android.server.tare.Modifier.COST_MODIFIER_POWER_SAVE_MODE;
|
||||
import static com.android.server.tare.Modifier.COST_MODIFIER_PROCESS_STATE;
|
||||
import static com.android.server.tare.TareUtils.arcToCake;
|
||||
import static com.android.server.tare.TareUtils.cakeToString;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.ContentResolver;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.provider.Settings;
|
||||
import android.util.IndentingPrintWriter;
|
||||
import android.util.KeyValueListParser;
|
||||
@@ -159,14 +159,15 @@ public class JobSchedulerEconomicPolicy extends EconomicPolicy {
|
||||
JobSchedulerEconomicPolicy(InternalResourceService irs) {
|
||||
super(irs);
|
||||
mInternalResourceService = irs;
|
||||
loadConstants("");
|
||||
loadConstants("", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
void setup() {
|
||||
super.setup();
|
||||
void setup(@NonNull DeviceConfig.Properties properties) {
|
||||
super.setup(properties);
|
||||
ContentResolver resolver = mInternalResourceService.getContext().getContentResolver();
|
||||
loadConstants(Settings.Global.getString(resolver, TARE_JOB_SCHEDULER_CONSTANTS));
|
||||
loadConstants(Settings.Global.getString(resolver, TARE_JOB_SCHEDULER_CONSTANTS),
|
||||
properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -211,7 +212,8 @@ public class JobSchedulerEconomicPolicy extends EconomicPolicy {
|
||||
return mRewards.get(rewardId);
|
||||
}
|
||||
|
||||
private void loadConstants(String policyValuesString) {
|
||||
private void loadConstants(String policyValuesString,
|
||||
@Nullable DeviceConfig.Properties properties) {
|
||||
mActions.clear();
|
||||
mRewards.clear();
|
||||
|
||||
@@ -221,118 +223,153 @@ public class JobSchedulerEconomicPolicy extends EconomicPolicy {
|
||||
Slog.e(TAG, "Global setting key incorrect: ", e);
|
||||
}
|
||||
|
||||
mMinSatiatedBalanceExempted = arcToCake(
|
||||
mParser.getInt(KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED,
|
||||
DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED));
|
||||
mMinSatiatedBalanceOther = arcToCake(
|
||||
mParser.getInt(KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP,
|
||||
DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP));
|
||||
mMaxSatiatedBalance = arcToCake(mParser.getInt(KEY_JS_MAX_SATIATED_BALANCE,
|
||||
DEFAULT_JS_MAX_SATIATED_BALANCE));
|
||||
mInitialSatiatedConsumptionLimit = arcToCake(mParser.getInt(
|
||||
KEY_JS_INITIAL_CONSUMPTION_LIMIT, DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT));
|
||||
mMinSatiatedBalanceExempted = getConstantAsCake(mParser, properties,
|
||||
KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED,
|
||||
DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED_CAKES);
|
||||
mMinSatiatedBalanceOther = getConstantAsCake(mParser, properties,
|
||||
KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP,
|
||||
DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES);
|
||||
mMaxSatiatedBalance = getConstantAsCake(mParser, properties,
|
||||
KEY_JS_MAX_SATIATED_BALANCE,
|
||||
DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES);
|
||||
mInitialSatiatedConsumptionLimit = getConstantAsCake(mParser, properties,
|
||||
KEY_JS_INITIAL_CONSUMPTION_LIMIT,
|
||||
DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT_CAKES);
|
||||
mHardSatiatedConsumptionLimit = Math.max(mInitialSatiatedConsumptionLimit,
|
||||
arcToCake(mParser.getInt(
|
||||
KEY_JS_HARD_CONSUMPTION_LIMIT, DEFAULT_JS_HARD_CONSUMPTION_LIMIT)));
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_HARD_CONSUMPTION_LIMIT,
|
||||
DEFAULT_JS_HARD_CONSUMPTION_LIMIT_CAKES));
|
||||
|
||||
mActions.put(ACTION_JOB_MAX_START, new Action(ACTION_JOB_MAX_START,
|
||||
arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_MAX_START_CTP,
|
||||
DEFAULT_JS_ACTION_JOB_MAX_START_CTP)),
|
||||
arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_MAX_START_BASE_PRICE,
|
||||
DEFAULT_JS_ACTION_JOB_MAX_START_BASE_PRICE))));
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_ACTION_JOB_MAX_START_CTP,
|
||||
DEFAULT_JS_ACTION_JOB_MAX_START_CTP_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_ACTION_JOB_MAX_START_BASE_PRICE,
|
||||
DEFAULT_JS_ACTION_JOB_MAX_START_BASE_PRICE_CAKES)));
|
||||
mActions.put(ACTION_JOB_MAX_RUNNING, new Action(ACTION_JOB_MAX_RUNNING,
|
||||
arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_MAX_RUNNING_CTP,
|
||||
DEFAULT_JS_ACTION_JOB_MAX_RUNNING_CTP)),
|
||||
arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE,
|
||||
DEFAULT_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE))));
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_ACTION_JOB_MAX_RUNNING_CTP,
|
||||
DEFAULT_JS_ACTION_JOB_MAX_RUNNING_CTP_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE,
|
||||
DEFAULT_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE_CAKES)));
|
||||
mActions.put(ACTION_JOB_HIGH_START, new Action(ACTION_JOB_HIGH_START,
|
||||
arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_HIGH_START_CTP,
|
||||
DEFAULT_JS_ACTION_JOB_HIGH_START_CTP)),
|
||||
arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_HIGH_START_BASE_PRICE,
|
||||
DEFAULT_JS_ACTION_JOB_HIGH_START_BASE_PRICE))));
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_ACTION_JOB_HIGH_START_CTP,
|
||||
DEFAULT_JS_ACTION_JOB_HIGH_START_CTP_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_ACTION_JOB_HIGH_START_BASE_PRICE,
|
||||
DEFAULT_JS_ACTION_JOB_HIGH_START_BASE_PRICE_CAKES)));
|
||||
mActions.put(ACTION_JOB_HIGH_RUNNING, new Action(ACTION_JOB_HIGH_RUNNING,
|
||||
arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_HIGH_RUNNING_CTP,
|
||||
DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_CTP)),
|
||||
arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE,
|
||||
DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE))));
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_ACTION_JOB_HIGH_RUNNING_CTP,
|
||||
DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_CTP_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE,
|
||||
DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE_CAKES)));
|
||||
mActions.put(ACTION_JOB_DEFAULT_START, new Action(ACTION_JOB_DEFAULT_START,
|
||||
arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_DEFAULT_START_CTP,
|
||||
DEFAULT_JS_ACTION_JOB_DEFAULT_START_CTP)),
|
||||
arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE,
|
||||
DEFAULT_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE))));
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_ACTION_JOB_DEFAULT_START_CTP,
|
||||
DEFAULT_JS_ACTION_JOB_DEFAULT_START_CTP_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE,
|
||||
DEFAULT_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE_CAKES)));
|
||||
mActions.put(ACTION_JOB_DEFAULT_RUNNING, new Action(ACTION_JOB_DEFAULT_RUNNING,
|
||||
arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_DEFAULT_RUNNING_CTP,
|
||||
DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_CTP)),
|
||||
arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE,
|
||||
DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE))));
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_ACTION_JOB_DEFAULT_RUNNING_CTP,
|
||||
DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_CTP_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE,
|
||||
DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE_CAKES)));
|
||||
mActions.put(ACTION_JOB_LOW_START, new Action(ACTION_JOB_LOW_START,
|
||||
arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_LOW_START_CTP,
|
||||
DEFAULT_JS_ACTION_JOB_LOW_START_CTP)),
|
||||
arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_LOW_START_BASE_PRICE,
|
||||
DEFAULT_JS_ACTION_JOB_LOW_START_BASE_PRICE))));
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_ACTION_JOB_LOW_START_CTP,
|
||||
DEFAULT_JS_ACTION_JOB_LOW_START_CTP_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_ACTION_JOB_LOW_START_BASE_PRICE,
|
||||
DEFAULT_JS_ACTION_JOB_LOW_START_BASE_PRICE_CAKES)));
|
||||
mActions.put(ACTION_JOB_LOW_RUNNING, new Action(ACTION_JOB_LOW_RUNNING,
|
||||
arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_LOW_RUNNING_CTP,
|
||||
DEFAULT_JS_ACTION_JOB_LOW_RUNNING_CTP)),
|
||||
arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE,
|
||||
DEFAULT_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE))));
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_ACTION_JOB_LOW_RUNNING_CTP,
|
||||
DEFAULT_JS_ACTION_JOB_LOW_RUNNING_CTP_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE,
|
||||
DEFAULT_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE_CAKES)));
|
||||
mActions.put(ACTION_JOB_MIN_START, new Action(ACTION_JOB_MIN_START,
|
||||
arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_MIN_START_CTP,
|
||||
DEFAULT_JS_ACTION_JOB_MIN_START_CTP)),
|
||||
arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_MIN_START_BASE_PRICE,
|
||||
DEFAULT_JS_ACTION_JOB_MIN_START_BASE_PRICE))));
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_ACTION_JOB_MIN_START_CTP,
|
||||
DEFAULT_JS_ACTION_JOB_MIN_START_CTP_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_ACTION_JOB_MIN_START_BASE_PRICE,
|
||||
DEFAULT_JS_ACTION_JOB_MIN_START_BASE_PRICE_CAKES)));
|
||||
mActions.put(ACTION_JOB_MIN_RUNNING, new Action(ACTION_JOB_MIN_RUNNING,
|
||||
arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_MIN_RUNNING_CTP,
|
||||
DEFAULT_JS_ACTION_JOB_MIN_RUNNING_CTP)),
|
||||
arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE,
|
||||
DEFAULT_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE))));
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_ACTION_JOB_MIN_RUNNING_CTP,
|
||||
DEFAULT_JS_ACTION_JOB_MIN_RUNNING_CTP_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE,
|
||||
DEFAULT_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE_CAKES)));
|
||||
mActions.put(ACTION_JOB_TIMEOUT, new Action(ACTION_JOB_TIMEOUT,
|
||||
arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP,
|
||||
DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP)),
|
||||
arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE,
|
||||
DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE))));
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP,
|
||||
DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE,
|
||||
DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE_CAKES)));
|
||||
|
||||
mRewards.put(REWARD_TOP_ACTIVITY, new Reward(REWARD_TOP_ACTIVITY,
|
||||
arcToCake(mParser.getInt(KEY_JS_REWARD_TOP_ACTIVITY_INSTANT,
|
||||
DEFAULT_JS_REWARD_TOP_ACTIVITY_INSTANT)),
|
||||
(long) (arcToCake(1) * mParser.getFloat(KEY_JS_REWARD_TOP_ACTIVITY_ONGOING,
|
||||
DEFAULT_JS_REWARD_TOP_ACTIVITY_ONGOING)),
|
||||
arcToCake(mParser.getInt(KEY_JS_REWARD_TOP_ACTIVITY_MAX,
|
||||
DEFAULT_JS_REWARD_TOP_ACTIVITY_MAX))));
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_REWARD_TOP_ACTIVITY_INSTANT,
|
||||
DEFAULT_JS_REWARD_TOP_ACTIVITY_INSTANT_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_REWARD_TOP_ACTIVITY_ONGOING,
|
||||
DEFAULT_JS_REWARD_TOP_ACTIVITY_ONGOING_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_REWARD_TOP_ACTIVITY_MAX,
|
||||
DEFAULT_JS_REWARD_TOP_ACTIVITY_MAX_CAKES)));
|
||||
mRewards.put(REWARD_NOTIFICATION_SEEN, new Reward(REWARD_NOTIFICATION_SEEN,
|
||||
arcToCake(mParser.getInt(KEY_JS_REWARD_NOTIFICATION_SEEN_INSTANT,
|
||||
DEFAULT_JS_REWARD_NOTIFICATION_SEEN_INSTANT)),
|
||||
arcToCake(mParser.getInt(KEY_JS_REWARD_NOTIFICATION_SEEN_ONGOING,
|
||||
DEFAULT_JS_REWARD_NOTIFICATION_SEEN_ONGOING)),
|
||||
arcToCake(mParser.getInt(KEY_JS_REWARD_NOTIFICATION_SEEN_MAX,
|
||||
DEFAULT_JS_REWARD_NOTIFICATION_SEEN_MAX))));
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_REWARD_NOTIFICATION_SEEN_INSTANT,
|
||||
DEFAULT_JS_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_REWARD_NOTIFICATION_SEEN_ONGOING,
|
||||
DEFAULT_JS_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_REWARD_NOTIFICATION_SEEN_MAX,
|
||||
DEFAULT_JS_REWARD_NOTIFICATION_SEEN_MAX_CAKES)));
|
||||
mRewards.put(REWARD_NOTIFICATION_INTERACTION,
|
||||
new Reward(REWARD_NOTIFICATION_INTERACTION,
|
||||
arcToCake(mParser.getInt(
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT,
|
||||
DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT)),
|
||||
arcToCake(mParser.getInt(
|
||||
DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING,
|
||||
DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING)),
|
||||
arcToCake(mParser.getInt(
|
||||
DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_REWARD_NOTIFICATION_INTERACTION_MAX,
|
||||
DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX))));
|
||||
DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES)));
|
||||
mRewards.put(REWARD_WIDGET_INTERACTION, new Reward(REWARD_WIDGET_INTERACTION,
|
||||
arcToCake(mParser.getInt(KEY_JS_REWARD_WIDGET_INTERACTION_INSTANT,
|
||||
DEFAULT_JS_REWARD_WIDGET_INTERACTION_INSTANT)),
|
||||
arcToCake(mParser.getInt(KEY_JS_REWARD_WIDGET_INTERACTION_ONGOING,
|
||||
DEFAULT_JS_REWARD_WIDGET_INTERACTION_ONGOING)),
|
||||
arcToCake(mParser.getInt(KEY_JS_REWARD_WIDGET_INTERACTION_MAX,
|
||||
DEFAULT_JS_REWARD_WIDGET_INTERACTION_MAX))));
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_REWARD_WIDGET_INTERACTION_INSTANT,
|
||||
DEFAULT_JS_REWARD_WIDGET_INTERACTION_INSTANT_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_REWARD_WIDGET_INTERACTION_ONGOING,
|
||||
DEFAULT_JS_REWARD_WIDGET_INTERACTION_ONGOING_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_REWARD_WIDGET_INTERACTION_MAX,
|
||||
DEFAULT_JS_REWARD_WIDGET_INTERACTION_MAX_CAKES)));
|
||||
mRewards.put(REWARD_OTHER_USER_INTERACTION,
|
||||
new Reward(REWARD_OTHER_USER_INTERACTION,
|
||||
arcToCake(mParser.getInt(KEY_JS_REWARD_OTHER_USER_INTERACTION_INSTANT,
|
||||
DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_INSTANT)),
|
||||
arcToCake(mParser.getInt(
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_REWARD_OTHER_USER_INTERACTION_INSTANT,
|
||||
DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_REWARD_OTHER_USER_INTERACTION_ONGOING,
|
||||
DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_ONGOING)),
|
||||
arcToCake(mParser.getInt(
|
||||
DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES),
|
||||
getConstantAsCake(mParser, properties,
|
||||
KEY_JS_REWARD_OTHER_USER_INTERACTION_MAX,
|
||||
DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX))));
|
||||
DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX_CAKES)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -18,16 +18,17 @@ The key tenets of TARE are:
|
||||
In an ideal world, the system could be said to most efficiently allocate resources by maximizing its
|
||||
profits — by maximizing the aggregate sum of the difference between an action's price (that
|
||||
the app ends up paying) and the cost to produce by the system. This assumes that more important
|
||||
actions have a higher price than less important actions. With this assumption, maximizing profits
|
||||
implies that the system runs the most important work first and proceeds in decreasing order of
|
||||
importance. Of course, that also means the system will not run anything where an app would pay less
|
||||
for the action than the system's cost to produce that action. Some of this breaks down when we throw
|
||||
TOP apps into the mix — TOP apps pay 0 for all actions, even though the CTP may be greater
|
||||
than 0. This is to ensure ideal user experience for the app the user is actively interacting with.
|
||||
Similar caveats exist for system-critical processes (such as the OS itself) and apps running
|
||||
foreground services (since those could be critical to user experience, as is the case for media and
|
||||
navigation apps). Excluding those caveats/special situations, maximizing profits of actions
|
||||
performed by apps in the background should be the target.
|
||||
actions have a higher price than less important actions and all actors have perfect information and
|
||||
convey that information accurately. With these assumptions, maximizing profits implies that the
|
||||
system runs the most important work first and proceeds in decreasing order of importance. Of course,
|
||||
that also means the system will not run anything where an app would pay less for the action than the
|
||||
system's cost to produce that action. Some of this breaks down when we throw TOP apps into the mix
|
||||
— TOP apps pay 0 for all actions, even though the CTP may be greater than 0. This is to ensure
|
||||
ideal user experience for the app the user is actively interacting with. Similar caveats exist for
|
||||
system-critical processes (such as the OS itself) and apps running foreground services (since those
|
||||
could be critical to user experience, as is the case for media and navigation apps). Excluding those
|
||||
caveats/special situations, maximizing profits of actions performed by apps in the background should
|
||||
be the target.
|
||||
|
||||
To achieve the goal laid out by TARE, we use Android Resource Credits (ARCs for short) as the
|
||||
internal/representative currency of the system.
|
||||
@@ -101,11 +102,37 @@ Tare Improvement Proposal #1 (TIP1) separated allocation (to apps) from supply (
|
||||
allowed apps to accrue credits as appropriate while still limiting the total number of credits
|
||||
consumed.
|
||||
|
||||
# Potential Future Changes
|
||||
|
||||
These are some ideas for further changes. There's no guarantee that they'll be implemented.
|
||||
|
||||
* Include additional components and policies for them. TARE may benefit from adding policies for
|
||||
components such as broadcast dispatching, network traffic, location requests, and sensor usage.
|
||||
* Have a separate "account" for critical/special actions. In other words, have two accounts for each
|
||||
app, where one acts like a special savings account and is only allowed to be used for special
|
||||
actions such as expedited job execution. The second account would have a lower maximum than the
|
||||
main account, but would help to make sure that normal actions don't interfere too much with more
|
||||
critical actions.
|
||||
* Transferring credits from one app to another. For apps that rely on others for some pieces of
|
||||
work, it may be beneficial to allow the requesting app to transfer, donate, or somehow make
|
||||
available some of its own credits to the app doing the work in order to make sure the working app
|
||||
has enough credits available to do the work.
|
||||
* Formulate values based on device hardware. For example, adjust the consumption limit based on the
|
||||
battery size, or the price and/or CTP of actions based on hardware efficiency.
|
||||
* Price discovery via an auction system. Instead of just setting a fixed price that may be modified
|
||||
by device and app states, let an app say how much it's willing to pay for a specific action and
|
||||
then have a small auction when the system needs to decide which app to perform the action for
|
||||
first or how much to charge the app.
|
||||
|
||||
# Definitions
|
||||
|
||||
* ARC: Android Resource Credits are the "currency" units used as an abstraction layer over the real
|
||||
battery drain. They allow the system to standardize costs and prices across various devices.
|
||||
* Cake: A lie; also the smallest unit of an ARC (1 cake = one-billionth of an ARC = 1 nano-ARC).
|
||||
When the apps request to do something, we shall let them eat cake.
|
||||
* NARC: The smallest unit of an ARC. A narc is 1 nano-ARC.
|
||||
* Cost to produce (CTP): An economic term that refers to the total cost incurred by a business to
|
||||
produce a specific quantity of a product or offer a service. In TARE's context, CTP is meant to be
|
||||
the estimated cost t ohe system to accomplish a certain action. These "actions" are basically APIs
|
||||
that apps use to get something done. So the idea is to define the base cost for an app to use a
|
||||
specific API.
|
||||
* Satiated: used to refer to when the device is fully charged (at 100% battery level)
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.server.tare;
|
||||
|
||||
import static android.app.tare.EconomyManager.CAKE_IN_ARC;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.util.IndentingPrintWriter;
|
||||
@@ -26,8 +28,6 @@ import java.text.SimpleDateFormat;
|
||||
import java.time.Clock;
|
||||
|
||||
class TareUtils {
|
||||
private static final long CAKE_IN_ARC = 1_000_000_000L;
|
||||
|
||||
@SuppressLint("SimpleDateFormat")
|
||||
private static final SimpleDateFormat sDumpDateFormat =
|
||||
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
|
||||
@@ -35,10 +35,6 @@ class TareUtils {
|
||||
@VisibleForTesting
|
||||
static Clock sSystemClock = Clock.systemUTC();
|
||||
|
||||
static long arcToCake(int arcs) {
|
||||
return arcs * CAKE_IN_ARC;
|
||||
}
|
||||
|
||||
static void dumpTime(IndentingPrintWriter pw, long time) {
|
||||
pw.print(sDumpDateFormat.format(time));
|
||||
}
|
||||
@@ -56,7 +52,7 @@ class TareUtils {
|
||||
if (cakes == 0) {
|
||||
return "0 ARCs";
|
||||
}
|
||||
final long sub = Math.abs(cakes) % CAKE_IN_ARC;
|
||||
final long sub = cakes % CAKE_IN_ARC;
|
||||
final long arcs = cakeToArc(cakes);
|
||||
if (arcs == 0) {
|
||||
return sub == 1
|
||||
@@ -65,11 +61,11 @@ class TareUtils {
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(arcs);
|
||||
if (sub > 0) {
|
||||
sb.append(".").append(sub / (CAKE_IN_ARC / 1000));
|
||||
if (sub != 0) {
|
||||
sb.append(".").append(String.format("%03d", Math.abs(sub) / (CAKE_IN_ARC / 1000)));
|
||||
}
|
||||
sb.append(" ARC");
|
||||
if (arcs != 1 || sub > 0) {
|
||||
if (arcs != 1 || sub != 0) {
|
||||
sb.append("s");
|
||||
}
|
||||
return sb.toString();
|
||||
|
||||
Reference in New Issue
Block a user