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_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE_CAKES; 20 import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_CTP_CAKES; 21 import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP_CAKES; 22 import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE_CAKES; 23 import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP_CAKES; 24 import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE_CAKES; 25 import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP_CAKES; 26 import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE_CAKES; 27 import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP_CAKES; 28 import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE_CAKES; 29 import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP_CAKES; 30 import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE_CAKES; 31 import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_CTP_CAKES; 32 import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE_CAKES; 33 import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP_CAKES; 34 import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE_CAKES; 35 import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP_CAKES; 36 import static android.app.tare.EconomyManager.DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT_CAKES; 37 import static android.app.tare.EconomyManager.DEFAULT_AM_MAX_CONSUMPTION_LIMIT_CAKES; 38 import static android.app.tare.EconomyManager.DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES; 39 import static android.app.tare.EconomyManager.DEFAULT_AM_MIN_CONSUMPTION_LIMIT_CAKES; 40 import static android.app.tare.EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED_CAKES; 41 import static android.app.tare.EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES; 42 import static android.app.tare.EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP_CAKES; 43 import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES; 44 import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES; 45 import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES; 46 import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES; 47 import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_MAX_CAKES; 48 import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES; 49 import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES; 50 import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_MAX_CAKES; 51 import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES; 52 import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_TOP_ACTIVITY_INSTANT_CAKES; 53 import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_TOP_ACTIVITY_MAX_CAKES; 54 import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_TOP_ACTIVITY_ONGOING_CAKES; 55 import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_WIDGET_INTERACTION_INSTANT_CAKES; 56 import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_WIDGET_INTERACTION_MAX_CAKES; 57 import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_WIDGET_INTERACTION_ONGOING_CAKES; 58 import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE; 59 import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALARMCLOCK_CTP; 60 import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_BASE_PRICE; 61 import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP; 62 import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE; 63 import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP; 64 import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE; 65 import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP; 66 import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE; 67 import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP; 68 import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE; 69 import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP; 70 import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE; 71 import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_EXACT_WAKEUP_CTP; 72 import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE; 73 import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP; 74 import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE; 75 import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP; 76 import static android.app.tare.EconomyManager.KEY_AM_INITIAL_CONSUMPTION_LIMIT; 77 import static android.app.tare.EconomyManager.KEY_AM_MAX_CONSUMPTION_LIMIT; 78 import static android.app.tare.EconomyManager.KEY_AM_MAX_SATIATED_BALANCE; 79 import static android.app.tare.EconomyManager.KEY_AM_MIN_CONSUMPTION_LIMIT; 80 import static android.app.tare.EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED; 81 import static android.app.tare.EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP; 82 import static android.app.tare.EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP; 83 import static android.app.tare.EconomyManager.KEY_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT; 84 import static android.app.tare.EconomyManager.KEY_AM_REWARD_NOTIFICATION_INTERACTION_MAX; 85 import static android.app.tare.EconomyManager.KEY_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING; 86 import static android.app.tare.EconomyManager.KEY_AM_REWARD_NOTIFICATION_SEEN_INSTANT; 87 import static android.app.tare.EconomyManager.KEY_AM_REWARD_NOTIFICATION_SEEN_MAX; 88 import static android.app.tare.EconomyManager.KEY_AM_REWARD_NOTIFICATION_SEEN_ONGOING; 89 import static android.app.tare.EconomyManager.KEY_AM_REWARD_OTHER_USER_INTERACTION_INSTANT; 90 import static android.app.tare.EconomyManager.KEY_AM_REWARD_OTHER_USER_INTERACTION_MAX; 91 import static android.app.tare.EconomyManager.KEY_AM_REWARD_OTHER_USER_INTERACTION_ONGOING; 92 import static android.app.tare.EconomyManager.KEY_AM_REWARD_TOP_ACTIVITY_INSTANT; 93 import static android.app.tare.EconomyManager.KEY_AM_REWARD_TOP_ACTIVITY_MAX; 94 import static android.app.tare.EconomyManager.KEY_AM_REWARD_TOP_ACTIVITY_ONGOING; 95 import static android.app.tare.EconomyManager.KEY_AM_REWARD_WIDGET_INTERACTION_INSTANT; 96 import static android.app.tare.EconomyManager.KEY_AM_REWARD_WIDGET_INTERACTION_MAX; 97 import static android.app.tare.EconomyManager.KEY_AM_REWARD_WIDGET_INTERACTION_ONGOING; 98 import static android.app.tare.EconomyManager.arcToCake; 99 import static android.provider.Settings.Global.TARE_ALARM_MANAGER_CONSTANTS; 100 101 import static com.android.server.tare.Modifier.COST_MODIFIER_CHARGING; 102 import static com.android.server.tare.Modifier.COST_MODIFIER_DEVICE_IDLE; 103 import static com.android.server.tare.Modifier.COST_MODIFIER_POWER_SAVE_MODE; 104 import static com.android.server.tare.Modifier.COST_MODIFIER_PROCESS_STATE; 105 import static com.android.server.tare.TareUtils.cakeToString; 106 107 import android.annotation.NonNull; 108 import android.annotation.Nullable; 109 import android.content.ContentResolver; 110 import android.provider.DeviceConfig; 111 import android.util.IndentingPrintWriter; 112 import android.util.KeyValueListParser; 113 import android.util.Slog; 114 import android.util.SparseArray; 115 116 /** 117 * Policy defining pricing information and daily ARC requirements and suggestions for 118 * AlarmManager. 119 */ 120 public class AlarmManagerEconomicPolicy extends EconomicPolicy { 121 private static final String TAG = "TARE- " + AlarmManagerEconomicPolicy.class.getSimpleName(); 122 123 public static final int ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE = 124 TYPE_ACTION | POLICY_ALARM | 0; 125 public static final int ACTION_ALARM_WAKEUP_EXACT = 126 TYPE_ACTION | POLICY_ALARM | 1; 127 public static final int ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE = 128 TYPE_ACTION | POLICY_ALARM | 2; 129 public static final int ACTION_ALARM_WAKEUP_INEXACT = 130 TYPE_ACTION | POLICY_ALARM | 3; 131 public static final int ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE = 132 TYPE_ACTION | POLICY_ALARM | 4; 133 public static final int ACTION_ALARM_NONWAKEUP_EXACT = 134 TYPE_ACTION | POLICY_ALARM | 5; 135 public static final int ACTION_ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE = 136 TYPE_ACTION | POLICY_ALARM | 6; 137 public static final int ACTION_ALARM_NONWAKEUP_INEXACT = 138 TYPE_ACTION | POLICY_ALARM | 7; 139 public static final int ACTION_ALARM_CLOCK = 140 TYPE_ACTION | POLICY_ALARM | 8; 141 142 private static final int[] COST_MODIFIERS = new int[]{ 143 COST_MODIFIER_CHARGING, 144 COST_MODIFIER_DEVICE_IDLE, 145 COST_MODIFIER_POWER_SAVE_MODE, 146 COST_MODIFIER_PROCESS_STATE 147 }; 148 149 private long mMinSatiatedBalanceExempted; 150 private long mMinSatiatedBalanceHeadlessSystemApp; 151 private long mMinSatiatedBalanceOther; 152 private long mMaxSatiatedBalance; 153 private long mInitialSatiatedConsumptionLimit; 154 private long mMinSatiatedConsumptionLimit; 155 private long mMaxSatiatedConsumptionLimit; 156 157 private final KeyValueListParser mParser = new KeyValueListParser(','); 158 private final Injector mInjector; 159 160 private final SparseArray<Action> mActions = new SparseArray<>(); 161 private final SparseArray<Reward> mRewards = new SparseArray<>(); 162 AlarmManagerEconomicPolicy(InternalResourceService irs, Injector injector)163 AlarmManagerEconomicPolicy(InternalResourceService irs, Injector injector) { 164 super(irs); 165 mInjector = injector; 166 loadConstants("", null); 167 } 168 169 @Override setup(@onNull DeviceConfig.Properties properties)170 void setup(@NonNull DeviceConfig.Properties properties) { 171 super.setup(properties); 172 ContentResolver resolver = mIrs.getContext().getContentResolver(); 173 loadConstants(mInjector.getSettingsGlobalString(resolver, TARE_ALARM_MANAGER_CONSTANTS), 174 properties); 175 } 176 177 @Override getMinSatiatedBalance(final int userId, @NonNull final String pkgName)178 long getMinSatiatedBalance(final int userId, @NonNull final String pkgName) { 179 if (mIrs.isPackageRestricted(userId, pkgName)) { 180 return 0; 181 } 182 if (mIrs.isPackageExempted(userId, pkgName)) { 183 return mMinSatiatedBalanceExempted; 184 } 185 if (mIrs.isHeadlessSystemApp(userId, pkgName)) { 186 return mMinSatiatedBalanceHeadlessSystemApp; 187 } 188 // TODO: take other exemptions into account 189 return mMinSatiatedBalanceOther; 190 } 191 192 @Override getMaxSatiatedBalance(int userId, @NonNull String pkgName)193 long getMaxSatiatedBalance(int userId, @NonNull String pkgName) { 194 if (mIrs.isPackageRestricted(userId, pkgName)) { 195 return 0; 196 } 197 // TODO(230501287): adjust balance based on whether the app has the SCHEDULE_EXACT_ALARM 198 // permission granted. Apps without the permission granted shouldn't need a high balance 199 // since they won't be able to use exact alarms. Apps with the permission granted could 200 // have a higher balance, or perhaps just those with the USE_EXACT_ALARM permission since 201 // that is limited to specific use cases. 202 return mMaxSatiatedBalance; 203 } 204 205 @Override getInitialSatiatedConsumptionLimit()206 long getInitialSatiatedConsumptionLimit() { 207 return mInitialSatiatedConsumptionLimit; 208 } 209 210 @Override getMinSatiatedConsumptionLimit()211 long getMinSatiatedConsumptionLimit() { 212 return mMinSatiatedConsumptionLimit; 213 } 214 215 @Override getMaxSatiatedConsumptionLimit()216 long getMaxSatiatedConsumptionLimit() { 217 return mMaxSatiatedConsumptionLimit; 218 } 219 220 @NonNull 221 @Override getCostModifiers()222 int[] getCostModifiers() { 223 return COST_MODIFIERS; 224 } 225 226 @Nullable 227 @Override getAction(@ppAction int actionId)228 Action getAction(@AppAction int actionId) { 229 return mActions.get(actionId); 230 } 231 232 @Nullable 233 @Override getReward(@tilityReward int rewardId)234 Reward getReward(@UtilityReward int rewardId) { 235 return mRewards.get(rewardId); 236 } 237 loadConstants(String policyValuesString, @Nullable DeviceConfig.Properties properties)238 private void loadConstants(String policyValuesString, 239 @Nullable DeviceConfig.Properties properties) { 240 mActions.clear(); 241 mRewards.clear(); 242 243 try { 244 mParser.setString(policyValuesString); 245 } catch (IllegalArgumentException e) { 246 Slog.e(TAG, "Global setting key incorrect: ", e); 247 } 248 249 mMinSatiatedBalanceOther = getConstantAsCake(mParser, properties, 250 KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP, DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP_CAKES); 251 mMinSatiatedBalanceHeadlessSystemApp = getConstantAsCake(mParser, properties, 252 KEY_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP, 253 DEFAULT_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES, 254 mMinSatiatedBalanceOther); 255 mMinSatiatedBalanceExempted = getConstantAsCake(mParser, properties, 256 KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED, 257 DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED_CAKES, 258 mMinSatiatedBalanceHeadlessSystemApp); 259 mMaxSatiatedBalance = getConstantAsCake(mParser, properties, 260 KEY_AM_MAX_SATIATED_BALANCE, DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES, 261 Math.max(arcToCake(1), mMinSatiatedBalanceExempted)); 262 mMinSatiatedConsumptionLimit = getConstantAsCake(mParser, properties, 263 KEY_AM_MIN_CONSUMPTION_LIMIT, DEFAULT_AM_MIN_CONSUMPTION_LIMIT_CAKES, 264 arcToCake(1)); 265 mInitialSatiatedConsumptionLimit = getConstantAsCake(mParser, properties, 266 KEY_AM_INITIAL_CONSUMPTION_LIMIT, DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT_CAKES, 267 mMinSatiatedConsumptionLimit); 268 mMaxSatiatedConsumptionLimit = getConstantAsCake(mParser, properties, 269 KEY_AM_MAX_CONSUMPTION_LIMIT, DEFAULT_AM_MAX_CONSUMPTION_LIMIT_CAKES, 270 mInitialSatiatedConsumptionLimit); 271 272 final long exactAllowWhileIdleWakeupBasePrice = getConstantAsCake(mParser, properties, 273 KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE, 274 DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE_CAKES); 275 276 // Apps must hold the SCHEDULE_EXACT_ALARM or USE_EXACT_ALARMS permission in order to use 277 // exact alarms. Since the user has the option of granting/revoking the permission, we can 278 // be a little lenient on the action cost checks and only stop the action if the app has 279 // run out of credits, and not when the system has run out of stock. 280 mActions.put(ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE, 281 new Action(ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE, 282 getConstantAsCake(mParser, properties, 283 KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP, 284 DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP_CAKES), 285 exactAllowWhileIdleWakeupBasePrice, 286 /* respectsStockLimit */ false)); 287 mActions.put(ACTION_ALARM_WAKEUP_EXACT, 288 new Action(ACTION_ALARM_WAKEUP_EXACT, 289 getConstantAsCake(mParser, properties, 290 KEY_AM_ACTION_ALARM_EXACT_WAKEUP_CTP, 291 DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_CTP_CAKES), 292 getConstantAsCake(mParser, properties, 293 KEY_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE, 294 DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE_CAKES), 295 /* respectsStockLimit */ false)); 296 297 final long inexactAllowWhileIdleWakeupBasePrice = 298 getConstantAsCake(mParser, properties, 299 KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE, 300 DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE_CAKES); 301 302 mActions.put(ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE, 303 new Action(ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE, 304 getConstantAsCake(mParser, properties, 305 KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP, 306 DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP_CAKES), 307 inexactAllowWhileIdleWakeupBasePrice, 308 /* respectsStockLimit */ false)); 309 mActions.put(ACTION_ALARM_WAKEUP_INEXACT, 310 new Action(ACTION_ALARM_WAKEUP_INEXACT, 311 getConstantAsCake(mParser, properties, 312 KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP, 313 DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP_CAKES), 314 getConstantAsCake(mParser, properties, 315 KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE, 316 DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE_CAKES), 317 /* respectsStockLimit */ false)); 318 319 final long exactAllowWhileIdleNonWakeupBasePrice = getConstantAsCake(mParser, properties, 320 KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_BASE_PRICE, 321 DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE_CAKES); 322 mActions.put(ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE, 323 new Action(ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE, 324 getConstantAsCake(mParser, properties, 325 KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP, 326 DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP_CAKES), 327 exactAllowWhileIdleNonWakeupBasePrice, 328 /* respectsStockLimit */ false)); 329 330 mActions.put(ACTION_ALARM_NONWAKEUP_EXACT, 331 new Action(ACTION_ALARM_NONWAKEUP_EXACT, 332 getConstantAsCake(mParser, properties, 333 KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP, 334 DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP_CAKES), 335 getConstantAsCake(mParser, properties, 336 KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE, 337 DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE_CAKES), 338 /* respectsStockLimit */ false)); 339 340 final long inexactAllowWhileIdleNonWakeupBasePrice = getConstantAsCake(mParser, properties, 341 KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE, 342 DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE_CAKES); 343 final long inexactAllowWhileIdleNonWakeupCtp = getConstantAsCake(mParser, properties, 344 KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP, 345 DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP_CAKES); 346 mActions.put(ACTION_ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE, 347 new Action(ACTION_ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE, 348 inexactAllowWhileIdleNonWakeupCtp, 349 inexactAllowWhileIdleNonWakeupBasePrice)); 350 351 mActions.put(ACTION_ALARM_NONWAKEUP_INEXACT, 352 new Action(ACTION_ALARM_NONWAKEUP_INEXACT, 353 getConstantAsCake(mParser, properties, 354 KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP, 355 DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP_CAKES), 356 getConstantAsCake(mParser, properties, 357 KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE, 358 DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE_CAKES))); 359 mActions.put(ACTION_ALARM_CLOCK, 360 new Action(ACTION_ALARM_CLOCK, 361 getConstantAsCake(mParser, properties, 362 KEY_AM_ACTION_ALARM_ALARMCLOCK_CTP, 363 DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_CTP_CAKES), 364 getConstantAsCake(mParser, properties, 365 KEY_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE, 366 DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE_CAKES), 367 /* respectsStockLimit */ false)); 368 369 mRewards.put(REWARD_TOP_ACTIVITY, new Reward(REWARD_TOP_ACTIVITY, 370 getConstantAsCake(mParser, properties, 371 KEY_AM_REWARD_TOP_ACTIVITY_INSTANT, 372 DEFAULT_AM_REWARD_TOP_ACTIVITY_INSTANT_CAKES), 373 getConstantAsCake(mParser, properties, 374 KEY_AM_REWARD_TOP_ACTIVITY_ONGOING, 375 DEFAULT_AM_REWARD_TOP_ACTIVITY_ONGOING_CAKES), 376 getConstantAsCake(mParser, properties, 377 KEY_AM_REWARD_TOP_ACTIVITY_MAX, 378 DEFAULT_AM_REWARD_TOP_ACTIVITY_MAX_CAKES))); 379 mRewards.put(REWARD_NOTIFICATION_SEEN, new Reward(REWARD_NOTIFICATION_SEEN, 380 getConstantAsCake(mParser, properties, 381 KEY_AM_REWARD_NOTIFICATION_SEEN_INSTANT, 382 DEFAULT_AM_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES), 383 getConstantAsCake(mParser, properties, 384 KEY_AM_REWARD_NOTIFICATION_SEEN_ONGOING, 385 DEFAULT_AM_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES), 386 getConstantAsCake(mParser, properties, 387 KEY_AM_REWARD_NOTIFICATION_SEEN_MAX, 388 DEFAULT_AM_REWARD_NOTIFICATION_SEEN_MAX_CAKES))); 389 mRewards.put(REWARD_NOTIFICATION_INTERACTION, 390 new Reward(REWARD_NOTIFICATION_INTERACTION, 391 getConstantAsCake(mParser, properties, 392 KEY_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT, 393 DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES), 394 getConstantAsCake(mParser, properties, 395 KEY_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING, 396 DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES), 397 getConstantAsCake(mParser, properties, 398 KEY_AM_REWARD_NOTIFICATION_INTERACTION_MAX, 399 DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES))); 400 mRewards.put(REWARD_WIDGET_INTERACTION, new Reward(REWARD_WIDGET_INTERACTION, 401 getConstantAsCake(mParser, properties, 402 KEY_AM_REWARD_WIDGET_INTERACTION_INSTANT, 403 DEFAULT_AM_REWARD_WIDGET_INTERACTION_INSTANT_CAKES), 404 getConstantAsCake(mParser, properties, 405 KEY_AM_REWARD_WIDGET_INTERACTION_ONGOING, 406 DEFAULT_AM_REWARD_WIDGET_INTERACTION_ONGOING_CAKES), 407 getConstantAsCake(mParser, properties, 408 KEY_AM_REWARD_WIDGET_INTERACTION_MAX, 409 DEFAULT_AM_REWARD_WIDGET_INTERACTION_MAX_CAKES))); 410 mRewards.put(REWARD_OTHER_USER_INTERACTION, 411 new Reward(REWARD_OTHER_USER_INTERACTION, 412 getConstantAsCake(mParser, properties, 413 KEY_AM_REWARD_OTHER_USER_INTERACTION_INSTANT, 414 DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES), 415 getConstantAsCake(mParser, properties, 416 KEY_AM_REWARD_OTHER_USER_INTERACTION_ONGOING, 417 DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES), 418 getConstantAsCake(mParser, properties, 419 KEY_AM_REWARD_OTHER_USER_INTERACTION_MAX, 420 DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_MAX_CAKES))); 421 } 422 423 @Override dump(IndentingPrintWriter pw)424 void dump(IndentingPrintWriter pw) { 425 pw.println("Min satiated balances:"); 426 pw.increaseIndent(); 427 pw.print("Exempted", cakeToString(mMinSatiatedBalanceExempted)).println(); 428 pw.print("Other", cakeToString(mMinSatiatedBalanceOther)).println(); 429 pw.decreaseIndent(); 430 pw.print("Max satiated balance", cakeToString(mMaxSatiatedBalance)).println(); 431 pw.print("Consumption limits: ["); 432 pw.print(cakeToString(mMinSatiatedConsumptionLimit)); 433 pw.print(", "); 434 pw.print(cakeToString(mInitialSatiatedConsumptionLimit)); 435 pw.print(", "); 436 pw.print(cakeToString(mMaxSatiatedConsumptionLimit)); 437 pw.println("]"); 438 439 pw.println(); 440 pw.println("Actions:"); 441 pw.increaseIndent(); 442 for (int i = 0; i < mActions.size(); ++i) { 443 dumpAction(pw, mActions.valueAt(i)); 444 } 445 pw.decreaseIndent(); 446 447 pw.println(); 448 pw.println("Rewards:"); 449 pw.increaseIndent(); 450 for (int i = 0; i < mRewards.size(); ++i) { 451 dumpReward(pw, mRewards.valueAt(i)); 452 } 453 pw.decreaseIndent(); 454 } 455 } 456