blob: 91a291fe20db063d87530b4a34d2228b5ce0d2bc [file] [log] [blame]
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.tare;
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_INITIAL_CONSUMPTION_LIMIT_CAKES;
import static android.app.tare.EconomyManager.DEFAULT_JS_MAX_CONSUMPTION_LIMIT_CAKES;
import static android.app.tare.EconomyManager.DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES;
import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_CONSUMPTION_LIMIT_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_HEADLESS_SYSTEM_APP_CAKES;
import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER_CAKES;
import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES;
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_APP_INSTALL_INSTANT_CAKES;
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_APP_INSTALL_MAX_CAKES;
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_APP_INSTALL_ONGOING_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;
import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_START_CTP;
import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE;
import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_HIGH_RUNNING_CTP;
import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_HIGH_START_BASE_PRICE;
import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_HIGH_START_CTP;
import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE;
import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_LOW_RUNNING_CTP;
import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_LOW_START_BASE_PRICE;
import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_LOW_START_CTP;
import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE;
import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MAX_RUNNING_CTP;
import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MAX_START_BASE_PRICE;
import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MAX_START_CTP;
import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE;
import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MIN_RUNNING_CTP;
import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MIN_START_BASE_PRICE;
import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MIN_START_CTP;
import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE;
import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP;
import static android.app.tare.EconomyManager.KEY_JS_INITIAL_CONSUMPTION_LIMIT;
import static android.app.tare.EconomyManager.KEY_JS_MAX_CONSUMPTION_LIMIT;
import static android.app.tare.EconomyManager.KEY_JS_MAX_SATIATED_BALANCE;
import static android.app.tare.EconomyManager.KEY_JS_MIN_CONSUMPTION_LIMIT;
import static android.app.tare.EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED;
import static android.app.tare.EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP;
import static android.app.tare.EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER;
import static android.app.tare.EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP;
import static android.app.tare.EconomyManager.KEY_JS_REWARD_APP_INSTALL_INSTANT;
import static android.app.tare.EconomyManager.KEY_JS_REWARD_APP_INSTALL_MAX;
import static android.app.tare.EconomyManager.KEY_JS_REWARD_APP_INSTALL_ONGOING;
import static android.app.tare.EconomyManager.KEY_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT;
import static android.app.tare.EconomyManager.KEY_JS_REWARD_NOTIFICATION_INTERACTION_MAX;
import static android.app.tare.EconomyManager.KEY_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING;
import static android.app.tare.EconomyManager.KEY_JS_REWARD_NOTIFICATION_SEEN_INSTANT;
import static android.app.tare.EconomyManager.KEY_JS_REWARD_NOTIFICATION_SEEN_MAX;
import static android.app.tare.EconomyManager.KEY_JS_REWARD_NOTIFICATION_SEEN_ONGOING;
import static android.app.tare.EconomyManager.KEY_JS_REWARD_OTHER_USER_INTERACTION_INSTANT;
import static android.app.tare.EconomyManager.KEY_JS_REWARD_OTHER_USER_INTERACTION_MAX;
import static android.app.tare.EconomyManager.KEY_JS_REWARD_OTHER_USER_INTERACTION_ONGOING;
import static android.app.tare.EconomyManager.KEY_JS_REWARD_TOP_ACTIVITY_INSTANT;
import static android.app.tare.EconomyManager.KEY_JS_REWARD_TOP_ACTIVITY_MAX;
import static android.app.tare.EconomyManager.KEY_JS_REWARD_TOP_ACTIVITY_ONGOING;
import static android.app.tare.EconomyManager.KEY_JS_REWARD_WIDGET_INTERACTION_INSTANT;
import static android.app.tare.EconomyManager.KEY_JS_REWARD_WIDGET_INTERACTION_MAX;
import static android.app.tare.EconomyManager.KEY_JS_REWARD_WIDGET_INTERACTION_ONGOING;
import static android.app.tare.EconomyManager.arcToCake;
import static android.provider.Settings.Global.TARE_JOB_SCHEDULER_CONSTANTS;
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.appToString;
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.util.IndentingPrintWriter;
import android.util.KeyValueListParser;
import android.util.Slog;
import android.util.SparseArray;
/**
* Policy defining pricing information and daily ARC requirements and suggestions for
* JobScheduler.
*/
public class JobSchedulerEconomicPolicy extends EconomicPolicy {
private static final String TAG = "TARE- " + JobSchedulerEconomicPolicy.class.getSimpleName();
public static final int ACTION_JOB_MAX_START = TYPE_ACTION | POLICY_JOB | 0;
public static final int ACTION_JOB_MAX_RUNNING = TYPE_ACTION | POLICY_JOB | 1;
public static final int ACTION_JOB_HIGH_START = TYPE_ACTION | POLICY_JOB | 2;
public static final int ACTION_JOB_HIGH_RUNNING = TYPE_ACTION | POLICY_JOB | 3;
public static final int ACTION_JOB_DEFAULT_START = TYPE_ACTION | POLICY_JOB | 4;
public static final int ACTION_JOB_DEFAULT_RUNNING = TYPE_ACTION | POLICY_JOB | 5;
public static final int ACTION_JOB_LOW_START = TYPE_ACTION | POLICY_JOB | 6;
public static final int ACTION_JOB_LOW_RUNNING = TYPE_ACTION | POLICY_JOB | 7;
public static final int ACTION_JOB_MIN_START = TYPE_ACTION | POLICY_JOB | 8;
public static final int ACTION_JOB_MIN_RUNNING = TYPE_ACTION | POLICY_JOB | 9;
public static final int ACTION_JOB_TIMEOUT = TYPE_ACTION | POLICY_JOB | 10;
public static final int REWARD_APP_INSTALL = TYPE_REWARD | POLICY_JOB | 0;
private static final int[] COST_MODIFIERS = new int[]{
COST_MODIFIER_CHARGING,
COST_MODIFIER_DEVICE_IDLE,
COST_MODIFIER_POWER_SAVE_MODE,
COST_MODIFIER_PROCESS_STATE
};
private long mMinSatiatedBalanceExempted;
private long mMinSatiatedBalanceHeadlessSystemApp;
private long mMinSatiatedBalanceOther;
private long mMinSatiatedBalanceIncrementalAppUpdater;
private long mMaxSatiatedBalance;
private long mInitialSatiatedConsumptionLimit;
private long mMinSatiatedConsumptionLimit;
private long mMaxSatiatedConsumptionLimit;
private final KeyValueListParser mParser = new KeyValueListParser(',');
private final Injector mInjector;
private final SparseArray<Action> mActions = new SparseArray<>();
private final SparseArray<Reward> mRewards = new SparseArray<>();
JobSchedulerEconomicPolicy(InternalResourceService irs, Injector injector) {
super(irs);
mInjector = injector;
loadConstants("", null);
}
@Override
void setup(@NonNull DeviceConfig.Properties properties) {
super.setup(properties);
final ContentResolver resolver = mIrs.getContext().getContentResolver();
loadConstants(mInjector.getSettingsGlobalString(resolver, TARE_JOB_SCHEDULER_CONSTANTS),
properties);
}
@Override
long getMinSatiatedBalance(final int userId, @NonNull final String pkgName) {
if (mIrs.isPackageRestricted(userId, pkgName)) {
return 0;
}
final long baseBalance;
if (mIrs.isPackageExempted(userId, pkgName)) {
baseBalance = mMinSatiatedBalanceExempted;
} else if (mIrs.isHeadlessSystemApp(userId, pkgName)) {
baseBalance = mMinSatiatedBalanceHeadlessSystemApp;
} else {
baseBalance = mMinSatiatedBalanceOther;
}
long minBalance = baseBalance;
final int updateResponsibilityCount = mIrs.getAppUpdateResponsibilityCount(userId, pkgName);
minBalance += updateResponsibilityCount * mMinSatiatedBalanceIncrementalAppUpdater;
return Math.min(minBalance, mMaxSatiatedBalance);
}
@Override
long getMaxSatiatedBalance(int userId, @NonNull String pkgName) {
if (mIrs.isPackageRestricted(userId, pkgName)) {
return 0;
}
final InstalledPackageInfo ipo = mIrs.getInstalledPackageInfo(userId, pkgName);
if (ipo == null) {
Slog.wtfStack(TAG,
"Tried to get max balance of invalid app: " + appToString(userId, pkgName));
} else {
// A system installer's max balance is elevated for some time after first boot so
// they can use jobs to download and install apps.
if (ipo.isSystemInstaller) {
final long timeSinceFirstSetupMs = mIrs.getRealtimeSinceFirstSetupMs();
final boolean stillExempted = timeSinceFirstSetupMs
< InternalResourceService.INSTALLER_FIRST_SETUP_GRACE_PERIOD_MS;
if (stillExempted) {
return mMaxSatiatedConsumptionLimit;
}
}
}
return mMaxSatiatedBalance;
}
@Override
long getInitialSatiatedConsumptionLimit() {
return mInitialSatiatedConsumptionLimit;
}
@Override
long getMinSatiatedConsumptionLimit() {
return mMinSatiatedConsumptionLimit;
}
@Override
long getMaxSatiatedConsumptionLimit() {
return mMaxSatiatedConsumptionLimit;
}
@NonNull
@Override
int[] getCostModifiers() {
return COST_MODIFIERS;
}
@Nullable
@Override
Action getAction(@AppAction int actionId) {
return mActions.get(actionId);
}
@Nullable
@Override
Reward getReward(@UtilityReward int rewardId) {
return mRewards.get(rewardId);
}
private void loadConstants(String policyValuesString,
@Nullable DeviceConfig.Properties properties) {
mActions.clear();
mRewards.clear();
try {
mParser.setString(policyValuesString);
} catch (IllegalArgumentException e) {
Slog.e(TAG, "Global setting key incorrect: ", e);
}
mMinSatiatedBalanceOther = getConstantAsCake(mParser, properties,
KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP, DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES);
mMinSatiatedBalanceHeadlessSystemApp = getConstantAsCake(mParser, properties,
KEY_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
DEFAULT_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES,
mMinSatiatedBalanceOther);
mMinSatiatedBalanceExempted = getConstantAsCake(mParser, properties,
KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED,
DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED_CAKES,
mMinSatiatedBalanceHeadlessSystemApp);
mMinSatiatedBalanceIncrementalAppUpdater = getConstantAsCake(mParser, properties,
KEY_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER,
DEFAULT_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER_CAKES);
mMaxSatiatedBalance = getConstantAsCake(mParser, properties,
KEY_JS_MAX_SATIATED_BALANCE, DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES,
Math.max(arcToCake(1), mMinSatiatedBalanceExempted));
mMinSatiatedConsumptionLimit = getConstantAsCake(mParser, properties,
KEY_JS_MIN_CONSUMPTION_LIMIT, DEFAULT_JS_MIN_CONSUMPTION_LIMIT_CAKES,
arcToCake(1));
mInitialSatiatedConsumptionLimit = getConstantAsCake(mParser, properties,
KEY_JS_INITIAL_CONSUMPTION_LIMIT, DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT_CAKES,
mMinSatiatedConsumptionLimit);
mMaxSatiatedConsumptionLimit = getConstantAsCake(mParser, properties,
KEY_JS_MAX_CONSUMPTION_LIMIT, DEFAULT_JS_MAX_CONSUMPTION_LIMIT_CAKES,
mInitialSatiatedConsumptionLimit);
mActions.put(ACTION_JOB_MAX_START, new Action(ACTION_JOB_MAX_START,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
getConstantAsCake(mParser, properties,
KEY_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT,
DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES),
getConstantAsCake(mParser, properties,
KEY_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING,
DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES),
getConstantAsCake(mParser, properties,
KEY_JS_REWARD_NOTIFICATION_INTERACTION_MAX,
DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES)));
mRewards.put(REWARD_WIDGET_INTERACTION, new Reward(REWARD_WIDGET_INTERACTION,
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,
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_CAKES),
getConstantAsCake(mParser, properties,
KEY_JS_REWARD_OTHER_USER_INTERACTION_MAX,
DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX_CAKES)));
mRewards.put(REWARD_APP_INSTALL,
new Reward(REWARD_APP_INSTALL,
getConstantAsCake(mParser, properties,
KEY_JS_REWARD_APP_INSTALL_INSTANT,
DEFAULT_JS_REWARD_APP_INSTALL_INSTANT_CAKES),
getConstantAsCake(mParser, properties,
KEY_JS_REWARD_APP_INSTALL_ONGOING,
DEFAULT_JS_REWARD_APP_INSTALL_ONGOING_CAKES),
getConstantAsCake(mParser, properties,
KEY_JS_REWARD_APP_INSTALL_MAX,
DEFAULT_JS_REWARD_APP_INSTALL_MAX_CAKES)));
}
@Override
void dump(IndentingPrintWriter pw) {
pw.println("Min satiated balance:");
pw.increaseIndent();
pw.print("Exempted", cakeToString(mMinSatiatedBalanceExempted)).println();
pw.print("Other", cakeToString(mMinSatiatedBalanceOther)).println();
pw.print("+App Updater", cakeToString(mMinSatiatedBalanceIncrementalAppUpdater)).println();
pw.decreaseIndent();
pw.print("Max satiated balance", cakeToString(mMaxSatiatedBalance)).println();
pw.print("Consumption limits: [");
pw.print(cakeToString(mMinSatiatedConsumptionLimit));
pw.print(", ");
pw.print(cakeToString(mInitialSatiatedConsumptionLimit));
pw.print(", ");
pw.print(cakeToString(mMaxSatiatedConsumptionLimit));
pw.println("]");
pw.println();
pw.println("Actions:");
pw.increaseIndent();
for (int i = 0; i < mActions.size(); ++i) {
dumpAction(pw, mActions.valueAt(i));
}
pw.decreaseIndent();
pw.println();
pw.println("Rewards:");
pw.increaseIndent();
for (int i = 0; i < mRewards.size(); ++i) {
dumpReward(pw, mRewards.valueAt(i));
}
pw.decreaseIndent();
}
}