• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_HARD_CONSUMPTION_LIMIT_CAKES;
42 import static android.app.tare.EconomyManager.DEFAULT_JS_INITIAL_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_SATIATED_BALANCE_EXEMPTED_CAKES;
45 import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES;
46 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES;
47 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES;
48 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES;
49 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES;
50 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_MAX_CAKES;
51 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES;
52 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES;
53 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX_CAKES;
54 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES;
55 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_INSTANT_CAKES;
56 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_MAX_CAKES;
57 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_ONGOING_CAKES;
58 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_INSTANT_CAKES;
59 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_MAX_CAKES;
60 import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_ONGOING_CAKES;
61 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE;
62 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_RUNNING_CTP;
63 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE;
64 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_START_CTP;
65 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE;
66 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_HIGH_RUNNING_CTP;
67 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_HIGH_START_BASE_PRICE;
68 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_HIGH_START_CTP;
69 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE;
70 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_LOW_RUNNING_CTP;
71 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_LOW_START_BASE_PRICE;
72 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_LOW_START_CTP;
73 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE;
74 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MAX_RUNNING_CTP;
75 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MAX_START_BASE_PRICE;
76 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MAX_START_CTP;
77 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE;
78 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MIN_RUNNING_CTP;
79 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MIN_START_BASE_PRICE;
80 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MIN_START_CTP;
81 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE;
82 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP;
83 import static android.app.tare.EconomyManager.KEY_JS_HARD_CONSUMPTION_LIMIT;
84 import static android.app.tare.EconomyManager.KEY_JS_INITIAL_CONSUMPTION_LIMIT;
85 import static android.app.tare.EconomyManager.KEY_JS_MAX_SATIATED_BALANCE;
86 import static android.app.tare.EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED;
87 import static android.app.tare.EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP;
88 import static android.app.tare.EconomyManager.KEY_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT;
89 import static android.app.tare.EconomyManager.KEY_JS_REWARD_NOTIFICATION_INTERACTION_MAX;
90 import static android.app.tare.EconomyManager.KEY_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING;
91 import static android.app.tare.EconomyManager.KEY_JS_REWARD_NOTIFICATION_SEEN_INSTANT;
92 import static android.app.tare.EconomyManager.KEY_JS_REWARD_NOTIFICATION_SEEN_MAX;
93 import static android.app.tare.EconomyManager.KEY_JS_REWARD_NOTIFICATION_SEEN_ONGOING;
94 import static android.app.tare.EconomyManager.KEY_JS_REWARD_OTHER_USER_INTERACTION_INSTANT;
95 import static android.app.tare.EconomyManager.KEY_JS_REWARD_OTHER_USER_INTERACTION_MAX;
96 import static android.app.tare.EconomyManager.KEY_JS_REWARD_OTHER_USER_INTERACTION_ONGOING;
97 import static android.app.tare.EconomyManager.KEY_JS_REWARD_TOP_ACTIVITY_INSTANT;
98 import static android.app.tare.EconomyManager.KEY_JS_REWARD_TOP_ACTIVITY_MAX;
99 import static android.app.tare.EconomyManager.KEY_JS_REWARD_TOP_ACTIVITY_ONGOING;
100 import static android.app.tare.EconomyManager.KEY_JS_REWARD_WIDGET_INTERACTION_INSTANT;
101 import static android.app.tare.EconomyManager.KEY_JS_REWARD_WIDGET_INTERACTION_MAX;
102 import static android.app.tare.EconomyManager.KEY_JS_REWARD_WIDGET_INTERACTION_ONGOING;
103 import static android.provider.Settings.Global.TARE_JOB_SCHEDULER_CONSTANTS;
104 
105 import static com.android.server.tare.Modifier.COST_MODIFIER_CHARGING;
106 import static com.android.server.tare.Modifier.COST_MODIFIER_DEVICE_IDLE;
107 import static com.android.server.tare.Modifier.COST_MODIFIER_POWER_SAVE_MODE;
108 import static com.android.server.tare.Modifier.COST_MODIFIER_PROCESS_STATE;
109 import static com.android.server.tare.TareUtils.cakeToString;
110 
111 import android.annotation.NonNull;
112 import android.annotation.Nullable;
113 import android.content.ContentResolver;
114 import android.provider.DeviceConfig;
115 import android.provider.Settings;
116 import android.util.IndentingPrintWriter;
117 import android.util.KeyValueListParser;
118 import android.util.Slog;
119 import android.util.SparseArray;
120 
121 /**
122  * Policy defining pricing information and daily ARC requirements and suggestions for
123  * JobScheduler.
124  */
125 public class JobSchedulerEconomicPolicy extends EconomicPolicy {
126     private static final String TAG = "TARE- " + JobSchedulerEconomicPolicy.class.getSimpleName();
127 
128     public static final int ACTION_JOB_MAX_START = TYPE_ACTION | POLICY_JS | 0;
129     public static final int ACTION_JOB_MAX_RUNNING = TYPE_ACTION | POLICY_JS | 1;
130     public static final int ACTION_JOB_HIGH_START = TYPE_ACTION | POLICY_JS | 2;
131     public static final int ACTION_JOB_HIGH_RUNNING = TYPE_ACTION | POLICY_JS | 3;
132     public static final int ACTION_JOB_DEFAULT_START = TYPE_ACTION | POLICY_JS | 4;
133     public static final int ACTION_JOB_DEFAULT_RUNNING = TYPE_ACTION | POLICY_JS | 5;
134     public static final int ACTION_JOB_LOW_START = TYPE_ACTION | POLICY_JS | 6;
135     public static final int ACTION_JOB_LOW_RUNNING = TYPE_ACTION | POLICY_JS | 7;
136     public static final int ACTION_JOB_MIN_START = TYPE_ACTION | POLICY_JS | 8;
137     public static final int ACTION_JOB_MIN_RUNNING = TYPE_ACTION | POLICY_JS | 9;
138     public static final int ACTION_JOB_TIMEOUT = TYPE_ACTION | POLICY_JS | 10;
139 
140     private static final int[] COST_MODIFIERS = new int[]{
141             COST_MODIFIER_CHARGING,
142             COST_MODIFIER_DEVICE_IDLE,
143             COST_MODIFIER_POWER_SAVE_MODE,
144             COST_MODIFIER_PROCESS_STATE
145     };
146 
147     private long mMinSatiatedBalanceExempted;
148     private long mMinSatiatedBalanceOther;
149     private long mMaxSatiatedBalance;
150     private long mInitialSatiatedConsumptionLimit;
151     private long mHardSatiatedConsumptionLimit;
152 
153     private final KeyValueListParser mParser = new KeyValueListParser(',');
154     private final InternalResourceService mInternalResourceService;
155 
156     private final SparseArray<Action> mActions = new SparseArray<>();
157     private final SparseArray<Reward> mRewards = new SparseArray<>();
158 
JobSchedulerEconomicPolicy(InternalResourceService irs)159     JobSchedulerEconomicPolicy(InternalResourceService irs) {
160         super(irs);
161         mInternalResourceService = irs;
162         loadConstants("", null);
163     }
164 
165     @Override
setup(@onNull DeviceConfig.Properties properties)166     void setup(@NonNull DeviceConfig.Properties properties) {
167         super.setup(properties);
168         ContentResolver resolver = mInternalResourceService.getContext().getContentResolver();
169         loadConstants(Settings.Global.getString(resolver, TARE_JOB_SCHEDULER_CONSTANTS),
170                 properties);
171     }
172 
173     @Override
getMinSatiatedBalance(final int userId, @NonNull final String pkgName)174     long getMinSatiatedBalance(final int userId, @NonNull final String pkgName) {
175         if (mInternalResourceService.isPackageExempted(userId, pkgName)) {
176             return mMinSatiatedBalanceExempted;
177         }
178         // TODO: take other exemptions into account
179         return mMinSatiatedBalanceOther;
180     }
181 
182     @Override
getMaxSatiatedBalance()183     long getMaxSatiatedBalance() {
184         return mMaxSatiatedBalance;
185     }
186 
187     @Override
getInitialSatiatedConsumptionLimit()188     long getInitialSatiatedConsumptionLimit() {
189         return mInitialSatiatedConsumptionLimit;
190     }
191 
192     @Override
getHardSatiatedConsumptionLimit()193     long getHardSatiatedConsumptionLimit() {
194         return mHardSatiatedConsumptionLimit;
195     }
196 
197     @NonNull
198     @Override
getCostModifiers()199     int[] getCostModifiers() {
200         return COST_MODIFIERS;
201     }
202 
203     @Nullable
204     @Override
getAction(@ppAction int actionId)205     Action getAction(@AppAction int actionId) {
206         return mActions.get(actionId);
207     }
208 
209     @Nullable
210     @Override
getReward(@tilityReward int rewardId)211     Reward getReward(@UtilityReward int rewardId) {
212         return mRewards.get(rewardId);
213     }
214 
loadConstants(String policyValuesString, @Nullable DeviceConfig.Properties properties)215     private void loadConstants(String policyValuesString,
216             @Nullable DeviceConfig.Properties properties) {
217         mActions.clear();
218         mRewards.clear();
219 
220         try {
221             mParser.setString(policyValuesString);
222         } catch (IllegalArgumentException e) {
223             Slog.e(TAG, "Global setting key incorrect: ", e);
224         }
225 
226         mMinSatiatedBalanceExempted = getConstantAsCake(mParser, properties,
227                 KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED,
228                 DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED_CAKES);
229         mMinSatiatedBalanceOther = getConstantAsCake(mParser, properties,
230                 KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP,
231                 DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES);
232         mMaxSatiatedBalance = getConstantAsCake(mParser, properties,
233                 KEY_JS_MAX_SATIATED_BALANCE,
234                 DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES);
235         mInitialSatiatedConsumptionLimit = getConstantAsCake(mParser, properties,
236                 KEY_JS_INITIAL_CONSUMPTION_LIMIT,
237                 DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT_CAKES);
238         mHardSatiatedConsumptionLimit = Math.max(mInitialSatiatedConsumptionLimit,
239                 getConstantAsCake(mParser, properties,
240                         KEY_JS_HARD_CONSUMPTION_LIMIT,
241                         DEFAULT_JS_HARD_CONSUMPTION_LIMIT_CAKES));
242 
243         mActions.put(ACTION_JOB_MAX_START, new Action(ACTION_JOB_MAX_START,
244                 getConstantAsCake(mParser, properties,
245                         KEY_JS_ACTION_JOB_MAX_START_CTP,
246                         DEFAULT_JS_ACTION_JOB_MAX_START_CTP_CAKES),
247                 getConstantAsCake(mParser, properties,
248                         KEY_JS_ACTION_JOB_MAX_START_BASE_PRICE,
249                         DEFAULT_JS_ACTION_JOB_MAX_START_BASE_PRICE_CAKES)));
250         mActions.put(ACTION_JOB_MAX_RUNNING, new Action(ACTION_JOB_MAX_RUNNING,
251                 getConstantAsCake(mParser, properties,
252                         KEY_JS_ACTION_JOB_MAX_RUNNING_CTP,
253                         DEFAULT_JS_ACTION_JOB_MAX_RUNNING_CTP_CAKES),
254                 getConstantAsCake(mParser, properties,
255                         KEY_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE,
256                         DEFAULT_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE_CAKES)));
257         mActions.put(ACTION_JOB_HIGH_START, new Action(ACTION_JOB_HIGH_START,
258                 getConstantAsCake(mParser, properties,
259                         KEY_JS_ACTION_JOB_HIGH_START_CTP,
260                         DEFAULT_JS_ACTION_JOB_HIGH_START_CTP_CAKES),
261                 getConstantAsCake(mParser, properties,
262                         KEY_JS_ACTION_JOB_HIGH_START_BASE_PRICE,
263                         DEFAULT_JS_ACTION_JOB_HIGH_START_BASE_PRICE_CAKES)));
264         mActions.put(ACTION_JOB_HIGH_RUNNING, new Action(ACTION_JOB_HIGH_RUNNING,
265                 getConstantAsCake(mParser, properties,
266                         KEY_JS_ACTION_JOB_HIGH_RUNNING_CTP,
267                         DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_CTP_CAKES),
268                 getConstantAsCake(mParser, properties,
269                         KEY_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE,
270                         DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE_CAKES)));
271         mActions.put(ACTION_JOB_DEFAULT_START, new Action(ACTION_JOB_DEFAULT_START,
272                 getConstantAsCake(mParser, properties,
273                         KEY_JS_ACTION_JOB_DEFAULT_START_CTP,
274                         DEFAULT_JS_ACTION_JOB_DEFAULT_START_CTP_CAKES),
275                 getConstantAsCake(mParser, properties,
276                         KEY_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE,
277                         DEFAULT_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE_CAKES)));
278         mActions.put(ACTION_JOB_DEFAULT_RUNNING, new Action(ACTION_JOB_DEFAULT_RUNNING,
279                 getConstantAsCake(mParser, properties,
280                         KEY_JS_ACTION_JOB_DEFAULT_RUNNING_CTP,
281                         DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_CTP_CAKES),
282                 getConstantAsCake(mParser, properties,
283                         KEY_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE,
284                         DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE_CAKES)));
285         mActions.put(ACTION_JOB_LOW_START, new Action(ACTION_JOB_LOW_START,
286                 getConstantAsCake(mParser, properties,
287                         KEY_JS_ACTION_JOB_LOW_START_CTP,
288                         DEFAULT_JS_ACTION_JOB_LOW_START_CTP_CAKES),
289                 getConstantAsCake(mParser, properties,
290                         KEY_JS_ACTION_JOB_LOW_START_BASE_PRICE,
291                         DEFAULT_JS_ACTION_JOB_LOW_START_BASE_PRICE_CAKES)));
292         mActions.put(ACTION_JOB_LOW_RUNNING, new Action(ACTION_JOB_LOW_RUNNING,
293                 getConstantAsCake(mParser, properties,
294                         KEY_JS_ACTION_JOB_LOW_RUNNING_CTP,
295                         DEFAULT_JS_ACTION_JOB_LOW_RUNNING_CTP_CAKES),
296                 getConstantAsCake(mParser, properties,
297                         KEY_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE,
298                         DEFAULT_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE_CAKES)));
299         mActions.put(ACTION_JOB_MIN_START, new Action(ACTION_JOB_MIN_START,
300                 getConstantAsCake(mParser, properties,
301                         KEY_JS_ACTION_JOB_MIN_START_CTP,
302                         DEFAULT_JS_ACTION_JOB_MIN_START_CTP_CAKES),
303                 getConstantAsCake(mParser, properties,
304                         KEY_JS_ACTION_JOB_MIN_START_BASE_PRICE,
305                         DEFAULT_JS_ACTION_JOB_MIN_START_BASE_PRICE_CAKES)));
306         mActions.put(ACTION_JOB_MIN_RUNNING, new Action(ACTION_JOB_MIN_RUNNING,
307                 getConstantAsCake(mParser, properties,
308                         KEY_JS_ACTION_JOB_MIN_RUNNING_CTP,
309                         DEFAULT_JS_ACTION_JOB_MIN_RUNNING_CTP_CAKES),
310                 getConstantAsCake(mParser, properties,
311                         KEY_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE,
312                         DEFAULT_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE_CAKES)));
313         mActions.put(ACTION_JOB_TIMEOUT, new Action(ACTION_JOB_TIMEOUT,
314                 getConstantAsCake(mParser, properties,
315                         KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP,
316                         DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP_CAKES),
317                 getConstantAsCake(mParser, properties,
318                         KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE,
319                         DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE_CAKES)));
320 
321         mRewards.put(REWARD_TOP_ACTIVITY, new Reward(REWARD_TOP_ACTIVITY,
322                 getConstantAsCake(mParser, properties,
323                         KEY_JS_REWARD_TOP_ACTIVITY_INSTANT,
324                         DEFAULT_JS_REWARD_TOP_ACTIVITY_INSTANT_CAKES),
325                 getConstantAsCake(mParser, properties,
326                         KEY_JS_REWARD_TOP_ACTIVITY_ONGOING,
327                         DEFAULT_JS_REWARD_TOP_ACTIVITY_ONGOING_CAKES),
328                 getConstantAsCake(mParser, properties,
329                         KEY_JS_REWARD_TOP_ACTIVITY_MAX,
330                         DEFAULT_JS_REWARD_TOP_ACTIVITY_MAX_CAKES)));
331         mRewards.put(REWARD_NOTIFICATION_SEEN, new Reward(REWARD_NOTIFICATION_SEEN,
332                 getConstantAsCake(mParser, properties,
333                         KEY_JS_REWARD_NOTIFICATION_SEEN_INSTANT,
334                         DEFAULT_JS_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES),
335                 getConstantAsCake(mParser, properties,
336                         KEY_JS_REWARD_NOTIFICATION_SEEN_ONGOING,
337                         DEFAULT_JS_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES),
338                 getConstantAsCake(mParser, properties,
339                         KEY_JS_REWARD_NOTIFICATION_SEEN_MAX,
340                         DEFAULT_JS_REWARD_NOTIFICATION_SEEN_MAX_CAKES)));
341         mRewards.put(REWARD_NOTIFICATION_INTERACTION,
342                 new Reward(REWARD_NOTIFICATION_INTERACTION,
343                         getConstantAsCake(mParser, properties,
344                                 KEY_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT,
345                                 DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES),
346                         getConstantAsCake(mParser, properties,
347                                 KEY_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING,
348                                 DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES),
349                         getConstantAsCake(mParser, properties,
350                                 KEY_JS_REWARD_NOTIFICATION_INTERACTION_MAX,
351                                 DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES)));
352         mRewards.put(REWARD_WIDGET_INTERACTION, new Reward(REWARD_WIDGET_INTERACTION,
353                 getConstantAsCake(mParser, properties,
354                         KEY_JS_REWARD_WIDGET_INTERACTION_INSTANT,
355                         DEFAULT_JS_REWARD_WIDGET_INTERACTION_INSTANT_CAKES),
356                 getConstantAsCake(mParser, properties,
357                         KEY_JS_REWARD_WIDGET_INTERACTION_ONGOING,
358                         DEFAULT_JS_REWARD_WIDGET_INTERACTION_ONGOING_CAKES),
359                 getConstantAsCake(mParser, properties,
360                         KEY_JS_REWARD_WIDGET_INTERACTION_MAX,
361                         DEFAULT_JS_REWARD_WIDGET_INTERACTION_MAX_CAKES)));
362         mRewards.put(REWARD_OTHER_USER_INTERACTION,
363                 new Reward(REWARD_OTHER_USER_INTERACTION,
364                         getConstantAsCake(mParser, properties,
365                                 KEY_JS_REWARD_OTHER_USER_INTERACTION_INSTANT,
366                                 DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES),
367                         getConstantAsCake(mParser, properties,
368                                 KEY_JS_REWARD_OTHER_USER_INTERACTION_ONGOING,
369                                 DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES),
370                         getConstantAsCake(mParser, properties,
371                                 KEY_JS_REWARD_OTHER_USER_INTERACTION_MAX,
372                                 DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX_CAKES)));
373     }
374 
375     @Override
dump(IndentingPrintWriter pw)376     void dump(IndentingPrintWriter pw) {
377         pw.println("Min satiated balances:");
378         pw.increaseIndent();
379         pw.print("Exempted", cakeToString(mMinSatiatedBalanceExempted)).println();
380         pw.print("Other", cakeToString(mMinSatiatedBalanceOther)).println();
381         pw.decreaseIndent();
382         pw.print("Max satiated balance", cakeToString(mMaxSatiatedBalance)).println();
383         pw.print("Consumption limits: [");
384         pw.print(cakeToString(mInitialSatiatedConsumptionLimit));
385         pw.print(", ");
386         pw.print(cakeToString(mHardSatiatedConsumptionLimit));
387         pw.println("]");
388 
389         pw.println();
390         pw.println("Actions:");
391         pw.increaseIndent();
392         for (int i = 0; i < mActions.size(); ++i) {
393             dumpAction(pw, mActions.valueAt(i));
394         }
395         pw.decreaseIndent();
396 
397         pw.println();
398         pw.println("Rewards:");
399         pw.increaseIndent();
400         for (int i = 0; i < mRewards.size(); ++i) {
401             dumpReward(pw, mRewards.valueAt(i));
402         }
403         pw.decreaseIndent();
404     }
405 }
406