1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.tare; 18 19 import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE_CAKES; 20 import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_CTP_CAKES; 21 import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE_CAKES; 22 import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_START_CTP_CAKES; 23 import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE_CAKES; 24 import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_CTP_CAKES; 25 import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_START_BASE_PRICE_CAKES; 26 import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_START_CTP_CAKES; 27 import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE_CAKES; 28 import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_RUNNING_CTP_CAKES; 29 import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_START_BASE_PRICE_CAKES; 30 import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_START_CTP_CAKES; 31 import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE_CAKES; 32 import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_RUNNING_CTP_CAKES; 33 import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_START_BASE_PRICE_CAKES; 34 import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_START_CTP_CAKES; 35 import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE_CAKES; 36 import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_RUNNING_CTP_CAKES; 37 import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_START_BASE_PRICE_CAKES; 38 import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_START_CTP_CAKES; 39 import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE_CAKES; 40 import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP_CAKES; 41 import static android.app.tare.EconomyManager.DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT_CAKES; 42 import static android.app.tare.EconomyManager.DEFAULT_JS_MAX_CONSUMPTION_LIMIT_CAKES; 43 import static android.app.tare.EconomyManager.DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES; 44 import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_CONSUMPTION_LIMIT_CAKES; 45 import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED_CAKES; 46 import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES; 47 import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER_CAKES; 48 import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES; 49 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_APP_INSTALL_INSTANT_CAKES; 50 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_APP_INSTALL_MAX_CAKES; 51 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_APP_INSTALL_ONGOING_CAKES; 52 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES; 53 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES; 54 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES; 55 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES; 56 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_MAX_CAKES; 57 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES; 58 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES; 59 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX_CAKES; 60 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES; 61 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_INSTANT_CAKES; 62 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_MAX_CAKES; 63 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_ONGOING_CAKES; 64 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_INSTANT_CAKES; 65 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_MAX_CAKES; 66 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_ONGOING_CAKES; 67 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE; 68 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_RUNNING_CTP; 69 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE; 70 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_START_CTP; 71 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE; 72 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_HIGH_RUNNING_CTP; 73 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_HIGH_START_BASE_PRICE; 74 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_HIGH_START_CTP; 75 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE; 76 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_LOW_RUNNING_CTP; 77 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_LOW_START_BASE_PRICE; 78 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_LOW_START_CTP; 79 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE; 80 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MAX_RUNNING_CTP; 81 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MAX_START_BASE_PRICE; 82 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MAX_START_CTP; 83 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE; 84 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MIN_RUNNING_CTP; 85 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MIN_START_BASE_PRICE; 86 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MIN_START_CTP; 87 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE; 88 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP; 89 import static android.app.tare.EconomyManager.KEY_JS_INITIAL_CONSUMPTION_LIMIT; 90 import static android.app.tare.EconomyManager.KEY_JS_MAX_CONSUMPTION_LIMIT; 91 import static android.app.tare.EconomyManager.KEY_JS_MAX_SATIATED_BALANCE; 92 import static android.app.tare.EconomyManager.KEY_JS_MIN_CONSUMPTION_LIMIT; 93 import static android.app.tare.EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED; 94 import static android.app.tare.EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP; 95 import static android.app.tare.EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER; 96 import static android.app.tare.EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP; 97 import static android.app.tare.EconomyManager.KEY_JS_REWARD_APP_INSTALL_INSTANT; 98 import static android.app.tare.EconomyManager.KEY_JS_REWARD_APP_INSTALL_MAX; 99 import static android.app.tare.EconomyManager.KEY_JS_REWARD_APP_INSTALL_ONGOING; 100 import static android.app.tare.EconomyManager.KEY_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT; 101 import static android.app.tare.EconomyManager.KEY_JS_REWARD_NOTIFICATION_INTERACTION_MAX; 102 import static android.app.tare.EconomyManager.KEY_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING; 103 import static android.app.tare.EconomyManager.KEY_JS_REWARD_NOTIFICATION_SEEN_INSTANT; 104 import static android.app.tare.EconomyManager.KEY_JS_REWARD_NOTIFICATION_SEEN_MAX; 105 import static android.app.tare.EconomyManager.KEY_JS_REWARD_NOTIFICATION_SEEN_ONGOING; 106 import static android.app.tare.EconomyManager.KEY_JS_REWARD_OTHER_USER_INTERACTION_INSTANT; 107 import static android.app.tare.EconomyManager.KEY_JS_REWARD_OTHER_USER_INTERACTION_MAX; 108 import static android.app.tare.EconomyManager.KEY_JS_REWARD_OTHER_USER_INTERACTION_ONGOING; 109 import static android.app.tare.EconomyManager.KEY_JS_REWARD_TOP_ACTIVITY_INSTANT; 110 import static android.app.tare.EconomyManager.KEY_JS_REWARD_TOP_ACTIVITY_MAX; 111 import static android.app.tare.EconomyManager.KEY_JS_REWARD_TOP_ACTIVITY_ONGOING; 112 import static android.app.tare.EconomyManager.KEY_JS_REWARD_WIDGET_INTERACTION_INSTANT; 113 import static android.app.tare.EconomyManager.KEY_JS_REWARD_WIDGET_INTERACTION_MAX; 114 import static android.app.tare.EconomyManager.KEY_JS_REWARD_WIDGET_INTERACTION_ONGOING; 115 import static android.app.tare.EconomyManager.arcToCake; 116 import static android.provider.Settings.Global.TARE_JOB_SCHEDULER_CONSTANTS; 117 118 import static com.android.server.tare.Modifier.COST_MODIFIER_CHARGING; 119 import static com.android.server.tare.Modifier.COST_MODIFIER_DEVICE_IDLE; 120 import static com.android.server.tare.Modifier.COST_MODIFIER_POWER_SAVE_MODE; 121 import static com.android.server.tare.Modifier.COST_MODIFIER_PROCESS_STATE; 122 import static com.android.server.tare.TareUtils.appToString; 123 import static com.android.server.tare.TareUtils.cakeToString; 124 125 import android.annotation.NonNull; 126 import android.annotation.Nullable; 127 import android.content.ContentResolver; 128 import android.provider.DeviceConfig; 129 import android.util.IndentingPrintWriter; 130 import android.util.KeyValueListParser; 131 import android.util.Slog; 132 import android.util.SparseArray; 133 134 /** 135 * Policy defining pricing information and daily ARC requirements and suggestions for 136 * JobScheduler. 137 */ 138 public class JobSchedulerEconomicPolicy extends EconomicPolicy { 139 private static final String TAG = "TARE- " + JobSchedulerEconomicPolicy.class.getSimpleName(); 140 141 public static final int ACTION_JOB_MAX_START = TYPE_ACTION | POLICY_JOB | 0; 142 public static final int ACTION_JOB_MAX_RUNNING = TYPE_ACTION | POLICY_JOB | 1; 143 public static final int ACTION_JOB_HIGH_START = TYPE_ACTION | POLICY_JOB | 2; 144 public static final int ACTION_JOB_HIGH_RUNNING = TYPE_ACTION | POLICY_JOB | 3; 145 public static final int ACTION_JOB_DEFAULT_START = TYPE_ACTION | POLICY_JOB | 4; 146 public static final int ACTION_JOB_DEFAULT_RUNNING = TYPE_ACTION | POLICY_JOB | 5; 147 public static final int ACTION_JOB_LOW_START = TYPE_ACTION | POLICY_JOB | 6; 148 public static final int ACTION_JOB_LOW_RUNNING = TYPE_ACTION | POLICY_JOB | 7; 149 public static final int ACTION_JOB_MIN_START = TYPE_ACTION | POLICY_JOB | 8; 150 public static final int ACTION_JOB_MIN_RUNNING = TYPE_ACTION | POLICY_JOB | 9; 151 public static final int ACTION_JOB_TIMEOUT = TYPE_ACTION | POLICY_JOB | 10; 152 153 public static final int REWARD_APP_INSTALL = TYPE_REWARD | POLICY_JOB | 0; 154 155 private static final int[] COST_MODIFIERS = new int[]{ 156 COST_MODIFIER_CHARGING, 157 COST_MODIFIER_DEVICE_IDLE, 158 COST_MODIFIER_POWER_SAVE_MODE, 159 COST_MODIFIER_PROCESS_STATE 160 }; 161 162 private long mMinSatiatedBalanceExempted; 163 private long mMinSatiatedBalanceHeadlessSystemApp; 164 private long mMinSatiatedBalanceOther; 165 private long mMinSatiatedBalanceIncrementalAppUpdater; 166 private long mMaxSatiatedBalance; 167 private long mInitialSatiatedConsumptionLimit; 168 private long mMinSatiatedConsumptionLimit; 169 private long mMaxSatiatedConsumptionLimit; 170 171 private final KeyValueListParser mParser = new KeyValueListParser(','); 172 private final Injector mInjector; 173 174 private final SparseArray<Action> mActions = new SparseArray<>(); 175 private final SparseArray<Reward> mRewards = new SparseArray<>(); 176 JobSchedulerEconomicPolicy(InternalResourceService irs, Injector injector)177 JobSchedulerEconomicPolicy(InternalResourceService irs, Injector injector) { 178 super(irs); 179 mInjector = injector; 180 loadConstants("", null); 181 } 182 183 @Override setup(@onNull DeviceConfig.Properties properties)184 void setup(@NonNull DeviceConfig.Properties properties) { 185 super.setup(properties); 186 final ContentResolver resolver = mIrs.getContext().getContentResolver(); 187 loadConstants(mInjector.getSettingsGlobalString(resolver, TARE_JOB_SCHEDULER_CONSTANTS), 188 properties); 189 } 190 191 @Override getMinSatiatedBalance(final int userId, @NonNull final String pkgName)192 long getMinSatiatedBalance(final int userId, @NonNull final String pkgName) { 193 if (mIrs.isPackageRestricted(userId, pkgName)) { 194 return 0; 195 } 196 197 final long baseBalance; 198 if (mIrs.isPackageExempted(userId, pkgName)) { 199 baseBalance = mMinSatiatedBalanceExempted; 200 } else if (mIrs.isHeadlessSystemApp(userId, pkgName)) { 201 baseBalance = mMinSatiatedBalanceHeadlessSystemApp; 202 } else { 203 baseBalance = mMinSatiatedBalanceOther; 204 } 205 206 long minBalance = baseBalance; 207 208 final int updateResponsibilityCount = mIrs.getAppUpdateResponsibilityCount(userId, pkgName); 209 minBalance += updateResponsibilityCount * mMinSatiatedBalanceIncrementalAppUpdater; 210 211 return Math.min(minBalance, mMaxSatiatedBalance); 212 } 213 214 @Override getMaxSatiatedBalance(int userId, @NonNull String pkgName)215 long getMaxSatiatedBalance(int userId, @NonNull String pkgName) { 216 if (mIrs.isPackageRestricted(userId, pkgName)) { 217 return 0; 218 } 219 final InstalledPackageInfo ipo = mIrs.getInstalledPackageInfo(userId, pkgName); 220 if (ipo == null) { 221 Slog.wtfStack(TAG, 222 "Tried to get max balance of invalid app: " + appToString(userId, pkgName)); 223 } else { 224 // A system installer's max balance is elevated for some time after first boot so 225 // they can use jobs to download and install apps. 226 if (ipo.isSystemInstaller) { 227 final long timeSinceFirstSetupMs = mIrs.getRealtimeSinceFirstSetupMs(); 228 final boolean stillExempted = timeSinceFirstSetupMs 229 < InternalResourceService.INSTALLER_FIRST_SETUP_GRACE_PERIOD_MS; 230 if (stillExempted) { 231 return mMaxSatiatedConsumptionLimit; 232 } 233 } 234 } 235 return mMaxSatiatedBalance; 236 } 237 238 @Override 239 long getInitialSatiatedConsumptionLimit() { 240 return mInitialSatiatedConsumptionLimit; 241 } 242 243 @Override 244 long getMinSatiatedConsumptionLimit() { 245 return mMinSatiatedConsumptionLimit; 246 } 247 248 @Override 249 long getMaxSatiatedConsumptionLimit() { 250 return mMaxSatiatedConsumptionLimit; 251 } 252 253 @NonNull 254 @Override 255 int[] getCostModifiers() { 256 return COST_MODIFIERS; 257 } 258 259 @Nullable 260 @Override 261 Action getAction(@AppAction int actionId) { 262 return mActions.get(actionId); 263 } 264 265 @Nullable 266 @Override 267 Reward getReward(@UtilityReward int rewardId) { 268 return mRewards.get(rewardId); 269 } 270 271 private void loadConstants(String policyValuesString, 272 @Nullable DeviceConfig.Properties properties) { 273 mActions.clear(); 274 mRewards.clear(); 275 276 try { 277 mParser.setString(policyValuesString); 278 } catch (IllegalArgumentException e) { 279 Slog.e(TAG, "Global setting key incorrect: ", e); 280 } 281 282 mMinSatiatedBalanceOther = getConstantAsCake(mParser, properties, 283 KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP, DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES); 284 mMinSatiatedBalanceHeadlessSystemApp = getConstantAsCake(mParser, properties, 285 KEY_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP, 286 DEFAULT_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES, 287 mMinSatiatedBalanceOther); 288 mMinSatiatedBalanceExempted = getConstantAsCake(mParser, properties, 289 KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED, 290 DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED_CAKES, 291 mMinSatiatedBalanceHeadlessSystemApp); 292 mMinSatiatedBalanceIncrementalAppUpdater = getConstantAsCake(mParser, properties, 293 KEY_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER, 294 DEFAULT_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER_CAKES); 295 mMaxSatiatedBalance = getConstantAsCake(mParser, properties, 296 KEY_JS_MAX_SATIATED_BALANCE, DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES, 297 Math.max(arcToCake(1), mMinSatiatedBalanceExempted)); 298 mMinSatiatedConsumptionLimit = getConstantAsCake(mParser, properties, 299 KEY_JS_MIN_CONSUMPTION_LIMIT, DEFAULT_JS_MIN_CONSUMPTION_LIMIT_CAKES, 300 arcToCake(1)); 301 mInitialSatiatedConsumptionLimit = getConstantAsCake(mParser, properties, 302 KEY_JS_INITIAL_CONSUMPTION_LIMIT, DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT_CAKES, 303 mMinSatiatedConsumptionLimit); 304 mMaxSatiatedConsumptionLimit = getConstantAsCake(mParser, properties, 305 KEY_JS_MAX_CONSUMPTION_LIMIT, DEFAULT_JS_MAX_CONSUMPTION_LIMIT_CAKES, 306 mInitialSatiatedConsumptionLimit); 307 308 mActions.put(ACTION_JOB_MAX_START, new Action(ACTION_JOB_MAX_START, 309 getConstantAsCake(mParser, properties, 310 KEY_JS_ACTION_JOB_MAX_START_CTP, 311 DEFAULT_JS_ACTION_JOB_MAX_START_CTP_CAKES), 312 getConstantAsCake(mParser, properties, 313 KEY_JS_ACTION_JOB_MAX_START_BASE_PRICE, 314 DEFAULT_JS_ACTION_JOB_MAX_START_BASE_PRICE_CAKES))); 315 mActions.put(ACTION_JOB_MAX_RUNNING, new Action(ACTION_JOB_MAX_RUNNING, 316 getConstantAsCake(mParser, properties, 317 KEY_JS_ACTION_JOB_MAX_RUNNING_CTP, 318 DEFAULT_JS_ACTION_JOB_MAX_RUNNING_CTP_CAKES), 319 getConstantAsCake(mParser, properties, 320 KEY_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE, 321 DEFAULT_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE_CAKES))); 322 mActions.put(ACTION_JOB_HIGH_START, new Action(ACTION_JOB_HIGH_START, 323 getConstantAsCake(mParser, properties, 324 KEY_JS_ACTION_JOB_HIGH_START_CTP, 325 DEFAULT_JS_ACTION_JOB_HIGH_START_CTP_CAKES), 326 getConstantAsCake(mParser, properties, 327 KEY_JS_ACTION_JOB_HIGH_START_BASE_PRICE, 328 DEFAULT_JS_ACTION_JOB_HIGH_START_BASE_PRICE_CAKES))); 329 mActions.put(ACTION_JOB_HIGH_RUNNING, new Action(ACTION_JOB_HIGH_RUNNING, 330 getConstantAsCake(mParser, properties, 331 KEY_JS_ACTION_JOB_HIGH_RUNNING_CTP, 332 DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_CTP_CAKES), 333 getConstantAsCake(mParser, properties, 334 KEY_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE, 335 DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE_CAKES))); 336 mActions.put(ACTION_JOB_DEFAULT_START, new Action(ACTION_JOB_DEFAULT_START, 337 getConstantAsCake(mParser, properties, 338 KEY_JS_ACTION_JOB_DEFAULT_START_CTP, 339 DEFAULT_JS_ACTION_JOB_DEFAULT_START_CTP_CAKES), 340 getConstantAsCake(mParser, properties, 341 KEY_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE, 342 DEFAULT_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE_CAKES))); 343 mActions.put(ACTION_JOB_DEFAULT_RUNNING, new Action(ACTION_JOB_DEFAULT_RUNNING, 344 getConstantAsCake(mParser, properties, 345 KEY_JS_ACTION_JOB_DEFAULT_RUNNING_CTP, 346 DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_CTP_CAKES), 347 getConstantAsCake(mParser, properties, 348 KEY_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE, 349 DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE_CAKES))); 350 mActions.put(ACTION_JOB_LOW_START, new Action(ACTION_JOB_LOW_START, 351 getConstantAsCake(mParser, properties, 352 KEY_JS_ACTION_JOB_LOW_START_CTP, 353 DEFAULT_JS_ACTION_JOB_LOW_START_CTP_CAKES), 354 getConstantAsCake(mParser, properties, 355 KEY_JS_ACTION_JOB_LOW_START_BASE_PRICE, 356 DEFAULT_JS_ACTION_JOB_LOW_START_BASE_PRICE_CAKES))); 357 mActions.put(ACTION_JOB_LOW_RUNNING, new Action(ACTION_JOB_LOW_RUNNING, 358 getConstantAsCake(mParser, properties, 359 KEY_JS_ACTION_JOB_LOW_RUNNING_CTP, 360 DEFAULT_JS_ACTION_JOB_LOW_RUNNING_CTP_CAKES), 361 getConstantAsCake(mParser, properties, 362 KEY_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE, 363 DEFAULT_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE_CAKES))); 364 mActions.put(ACTION_JOB_MIN_START, new Action(ACTION_JOB_MIN_START, 365 getConstantAsCake(mParser, properties, 366 KEY_JS_ACTION_JOB_MIN_START_CTP, 367 DEFAULT_JS_ACTION_JOB_MIN_START_CTP_CAKES), 368 getConstantAsCake(mParser, properties, 369 KEY_JS_ACTION_JOB_MIN_START_BASE_PRICE, 370 DEFAULT_JS_ACTION_JOB_MIN_START_BASE_PRICE_CAKES))); 371 mActions.put(ACTION_JOB_MIN_RUNNING, new Action(ACTION_JOB_MIN_RUNNING, 372 getConstantAsCake(mParser, properties, 373 KEY_JS_ACTION_JOB_MIN_RUNNING_CTP, 374 DEFAULT_JS_ACTION_JOB_MIN_RUNNING_CTP_CAKES), 375 getConstantAsCake(mParser, properties, 376 KEY_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE, 377 DEFAULT_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE_CAKES))); 378 mActions.put(ACTION_JOB_TIMEOUT, new Action(ACTION_JOB_TIMEOUT, 379 getConstantAsCake(mParser, properties, 380 KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP, 381 DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP_CAKES), 382 getConstantAsCake(mParser, properties, 383 KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE, 384 DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE_CAKES))); 385 386 mRewards.put(REWARD_TOP_ACTIVITY, new Reward(REWARD_TOP_ACTIVITY, 387 getConstantAsCake(mParser, properties, 388 KEY_JS_REWARD_TOP_ACTIVITY_INSTANT, 389 DEFAULT_JS_REWARD_TOP_ACTIVITY_INSTANT_CAKES), 390 getConstantAsCake(mParser, properties, 391 KEY_JS_REWARD_TOP_ACTIVITY_ONGOING, 392 DEFAULT_JS_REWARD_TOP_ACTIVITY_ONGOING_CAKES), 393 getConstantAsCake(mParser, properties, 394 KEY_JS_REWARD_TOP_ACTIVITY_MAX, 395 DEFAULT_JS_REWARD_TOP_ACTIVITY_MAX_CAKES))); 396 mRewards.put(REWARD_NOTIFICATION_SEEN, new Reward(REWARD_NOTIFICATION_SEEN, 397 getConstantAsCake(mParser, properties, 398 KEY_JS_REWARD_NOTIFICATION_SEEN_INSTANT, 399 DEFAULT_JS_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES), 400 getConstantAsCake(mParser, properties, 401 KEY_JS_REWARD_NOTIFICATION_SEEN_ONGOING, 402 DEFAULT_JS_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES), 403 getConstantAsCake(mParser, properties, 404 KEY_JS_REWARD_NOTIFICATION_SEEN_MAX, 405 DEFAULT_JS_REWARD_NOTIFICATION_SEEN_MAX_CAKES))); 406 mRewards.put(REWARD_NOTIFICATION_INTERACTION, 407 new Reward(REWARD_NOTIFICATION_INTERACTION, 408 getConstantAsCake(mParser, properties, 409 KEY_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT, 410 DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES), 411 getConstantAsCake(mParser, properties, 412 KEY_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING, 413 DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES), 414 getConstantAsCake(mParser, properties, 415 KEY_JS_REWARD_NOTIFICATION_INTERACTION_MAX, 416 DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES))); 417 mRewards.put(REWARD_WIDGET_INTERACTION, new Reward(REWARD_WIDGET_INTERACTION, 418 getConstantAsCake(mParser, properties, 419 KEY_JS_REWARD_WIDGET_INTERACTION_INSTANT, 420 DEFAULT_JS_REWARD_WIDGET_INTERACTION_INSTANT_CAKES), 421 getConstantAsCake(mParser, properties, 422 KEY_JS_REWARD_WIDGET_INTERACTION_ONGOING, 423 DEFAULT_JS_REWARD_WIDGET_INTERACTION_ONGOING_CAKES), 424 getConstantAsCake(mParser, properties, 425 KEY_JS_REWARD_WIDGET_INTERACTION_MAX, 426 DEFAULT_JS_REWARD_WIDGET_INTERACTION_MAX_CAKES))); 427 mRewards.put(REWARD_OTHER_USER_INTERACTION, 428 new Reward(REWARD_OTHER_USER_INTERACTION, 429 getConstantAsCake(mParser, properties, 430 KEY_JS_REWARD_OTHER_USER_INTERACTION_INSTANT, 431 DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES), 432 getConstantAsCake(mParser, properties, 433 KEY_JS_REWARD_OTHER_USER_INTERACTION_ONGOING, 434 DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES), 435 getConstantAsCake(mParser, properties, 436 KEY_JS_REWARD_OTHER_USER_INTERACTION_MAX, 437 DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX_CAKES))); 438 mRewards.put(REWARD_APP_INSTALL, 439 new Reward(REWARD_APP_INSTALL, 440 getConstantAsCake(mParser, properties, 441 KEY_JS_REWARD_APP_INSTALL_INSTANT, 442 DEFAULT_JS_REWARD_APP_INSTALL_INSTANT_CAKES), 443 getConstantAsCake(mParser, properties, 444 KEY_JS_REWARD_APP_INSTALL_ONGOING, 445 DEFAULT_JS_REWARD_APP_INSTALL_ONGOING_CAKES), 446 getConstantAsCake(mParser, properties, 447 KEY_JS_REWARD_APP_INSTALL_MAX, 448 DEFAULT_JS_REWARD_APP_INSTALL_MAX_CAKES))); 449 } 450 451 @Override 452 void dump(IndentingPrintWriter pw) { 453 pw.println("Min satiated balance:"); 454 pw.increaseIndent(); 455 pw.print("Exempted", cakeToString(mMinSatiatedBalanceExempted)).println(); 456 pw.print("Other", cakeToString(mMinSatiatedBalanceOther)).println(); 457 pw.print("+App Updater", cakeToString(mMinSatiatedBalanceIncrementalAppUpdater)).println(); 458 pw.decreaseIndent(); 459 pw.print("Max satiated balance", cakeToString(mMaxSatiatedBalance)).println(); 460 pw.print("Consumption limits: ["); 461 pw.print(cakeToString(mMinSatiatedConsumptionLimit)); 462 pw.print(", "); 463 pw.print(cakeToString(mInitialSatiatedConsumptionLimit)); 464 pw.print(", "); 465 pw.print(cakeToString(mMaxSatiatedConsumptionLimit)); 466 pw.println("]"); 467 468 pw.println(); 469 pw.println("Actions:"); 470 pw.increaseIndent(); 471 for (int i = 0; i < mActions.size(); ++i) { 472 dumpAction(pw, mActions.valueAt(i)); 473 } 474 pw.decreaseIndent(); 475 476 pw.println(); 477 pw.println("Rewards:"); 478 pw.increaseIndent(); 479 for (int i = 0; i < mRewards.size(); ++i) { 480 dumpReward(pw, mRewards.valueAt(i)); 481 } 482 pw.decreaseIndent(); 483 } 484 } 485