• 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.settings.development.tare;
18 
19 import static android.app.tare.EconomyManager.CAKE_IN_ARC;
20 import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE_CAKES;
21 import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE_CAKES;
22 import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP_CAKES;
23 import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE_CAKES;
24 import static android.app.tare.EconomyManager.parseCreditValue;
25 import static android.provider.Settings.Global.TARE_ALARM_MANAGER_CONSTANTS;
26 import static android.provider.Settings.Global.TARE_JOB_SCHEDULER_CONSTANTS;
27 
28 import android.annotation.NonNull;
29 import android.app.tare.EconomyManager;
30 import android.content.ContentResolver;
31 import android.content.Context;
32 import android.content.res.Resources;
33 import android.database.ContentObserver;
34 import android.net.Uri;
35 import android.os.Handler;
36 import android.os.Looper;
37 import android.provider.Settings;
38 import android.util.ArrayMap;
39 import android.util.ArraySet;
40 import android.util.KeyValueListParser;
41 import android.util.Slog;
42 
43 import com.android.settings.R;
44 
45 /**
46  * Takes an AlarmManager or JobScheduler csv string and parses it to get key:value pairs.
47  * This allows us to populate a dialog with the correct information.
48  */
49 public class TareFactorController {
50     private static final String TAG = "TareFactorController";
51 
52     private static TareFactorController sInstance;
53 
54     private static final int POLICY_ALARM_MANAGER = 0;
55     private static final int POLICY_JOB_SCHEDULER = 1;
56 
57     private final ContentResolver mContentResolver;
58     private final KeyValueListParser mParser = new KeyValueListParser(',');
59     private final Resources mResources;
60     private final ArrayMap<String, TareFactorData> mAlarmManagerMap = new ArrayMap<>();
61     private final ArrayMap<String, TareFactorData> mJobSchedulerMap = new ArrayMap<>();
62     private String mAlarmManagerConstants;
63     private String mJobSchedulerConstants;
64 
65     private final ArraySet<DataChangeListener> mDataChangeListeners = new ArraySet<>();
66 
TareFactorController(Context context)67     private TareFactorController(Context context) {
68         mContentResolver = context.getContentResolver();
69         mResources = context.getResources();
70 
71         ConfigObserver configObserver = new ConfigObserver(new Handler(Looper.getMainLooper()));
72         configObserver.start();
73 
74         mAlarmManagerConstants =
75                 Settings.Global.getString(mContentResolver, TARE_ALARM_MANAGER_CONSTANTS);
76         mJobSchedulerConstants =
77                 Settings.Global.getString(mContentResolver, TARE_JOB_SCHEDULER_CONSTANTS);
78 
79         initAlarmManagerMap();
80         parseAlarmManagerGlobalSettings();
81 
82         initJobSchedulerMap();
83         parseJobSchedulerGlobalSettings();
84     }
85 
getInstance(Context context)86     static TareFactorController getInstance(Context context) {
87         synchronized (TareFactorController.class) {
88             if (sInstance == null) {
89                 sInstance = new TareFactorController(context.getApplicationContext());
90             }
91         }
92         return sInstance;
93     }
94 
95     /**
96      * Initialization for AlarmManager Map that sets a AM factor key to a title, default value, and
97      * policy type in a data object.
98      */
initAlarmManagerMap()99     private void initAlarmManagerMap() {
100         mAlarmManagerMap.put(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED,
101                 new TareFactorData(mResources.getString(R.string.tare_min_balance_exempted),
102                         EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED_CAKES,
103                         POLICY_ALARM_MANAGER));
104         mAlarmManagerMap.put(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
105                 new TareFactorData(mResources.getString(R.string.tare_min_balance_headless_app),
106                         EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES,
107                         POLICY_ALARM_MANAGER));
108         mAlarmManagerMap.put(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP,
109                 new TareFactorData(mResources.getString(R.string.tare_min_balance_other_app),
110                         EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP_CAKES,
111                         POLICY_ALARM_MANAGER));
112         mAlarmManagerMap.put(EconomyManager.KEY_AM_MAX_SATIATED_BALANCE,
113                 new TareFactorData(mResources.getString(R.string.tare_max_satiated_balance),
114                         EconomyManager.DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES,
115                         POLICY_ALARM_MANAGER));
116         mAlarmManagerMap.put(EconomyManager.KEY_AM_INITIAL_CONSUMPTION_LIMIT,
117                 new TareFactorData(mResources.getString(R.string.tare_initial_consumption_limit),
118                         EconomyManager.DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT_CAKES,
119                         POLICY_ALARM_MANAGER));
120         mAlarmManagerMap.put(EconomyManager.KEY_AM_MIN_CONSUMPTION_LIMIT,
121                 new TareFactorData(mResources.getString(R.string.tare_min_consumption_limit),
122                         EconomyManager.DEFAULT_AM_MIN_CONSUMPTION_LIMIT_CAKES,
123                         POLICY_ALARM_MANAGER));
124         mAlarmManagerMap.put(EconomyManager.KEY_AM_MAX_CONSUMPTION_LIMIT,
125                 new TareFactorData(mResources.getString(R.string.tare_max_consumption_limit),
126                         EconomyManager.DEFAULT_AM_MAX_CONSUMPTION_LIMIT_CAKES,
127                         POLICY_ALARM_MANAGER));
128         mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_TOP_ACTIVITY_INSTANT,
129                 new TareFactorData(mResources.getString(R.string.tare_top_activity),
130                         EconomyManager.DEFAULT_AM_REWARD_TOP_ACTIVITY_INSTANT_CAKES,
131                         POLICY_ALARM_MANAGER));
132         mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_TOP_ACTIVITY_ONGOING,
133                 new TareFactorData(mResources.getString(R.string.tare_top_activity),
134                         EconomyManager.DEFAULT_AM_REWARD_TOP_ACTIVITY_ONGOING_CAKES,
135                         POLICY_ALARM_MANAGER));
136         mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_TOP_ACTIVITY_MAX,
137                 new TareFactorData(mResources.getString(R.string.tare_top_activity),
138                         EconomyManager.DEFAULT_AM_REWARD_TOP_ACTIVITY_MAX_CAKES,
139                         POLICY_ALARM_MANAGER));
140         mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_NOTIFICATION_SEEN_INSTANT,
141                 new TareFactorData(mResources.getString(R.string.tare_notification_seen),
142                         EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES,
143                         POLICY_ALARM_MANAGER));
144         mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_NOTIFICATION_SEEN_ONGOING,
145                 new TareFactorData(mResources.getString(R.string.tare_notification_seen),
146                         EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES,
147                         POLICY_ALARM_MANAGER));
148         mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_NOTIFICATION_SEEN_MAX,
149                 new TareFactorData(mResources.getString(R.string.tare_notification_seen),
150                         EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_MAX_CAKES,
151                         POLICY_ALARM_MANAGER));
152         mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_INSTANT,
153                 new TareFactorData(mResources.getString(R.string.tare_notification_seen_15_min),
154                         EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_INSTANT_CAKES,
155                         POLICY_ALARM_MANAGER));
156         mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_ONGOING,
157                 new TareFactorData(mResources.getString(R.string.tare_notification_seen_15_min),
158                         EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_ONGOING_CAKES,
159                         POLICY_ALARM_MANAGER));
160         mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_MAX,
161                 new TareFactorData(mResources.getString(R.string.tare_notification_seen_15_min),
162                         EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_MAX_CAKES,
163                         POLICY_ALARM_MANAGER));
164         mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT,
165                 new TareFactorData(mResources.getString(R.string.tare_notification_interaction),
166                         EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES,
167                         POLICY_ALARM_MANAGER));
168         mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING,
169                 new TareFactorData(mResources.getString(R.string.tare_notification_interaction),
170                         EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES,
171                         POLICY_ALARM_MANAGER));
172         mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_NOTIFICATION_INTERACTION_MAX,
173                 new TareFactorData(mResources.getString(R.string.tare_notification_interaction),
174                         EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES,
175                         POLICY_ALARM_MANAGER));
176         mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_WIDGET_INTERACTION_INSTANT,
177                 new TareFactorData(mResources.getString(R.string.tare_widget_interaction),
178                         EconomyManager.DEFAULT_AM_REWARD_WIDGET_INTERACTION_INSTANT_CAKES,
179                         POLICY_ALARM_MANAGER));
180         mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_WIDGET_INTERACTION_ONGOING,
181                 new TareFactorData(mResources.getString(R.string.tare_widget_interaction),
182                         EconomyManager.DEFAULT_AM_REWARD_WIDGET_INTERACTION_ONGOING_CAKES,
183                         POLICY_ALARM_MANAGER));
184         mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_WIDGET_INTERACTION_MAX,
185                 new TareFactorData(mResources.getString(R.string.tare_widget_interaction),
186                         EconomyManager.DEFAULT_AM_REWARD_WIDGET_INTERACTION_MAX_CAKES,
187                         POLICY_ALARM_MANAGER));
188         mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_OTHER_USER_INTERACTION_INSTANT,
189                 new TareFactorData(mResources.getString(R.string.tare_other_interaction),
190                         EconomyManager.DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES,
191                         POLICY_ALARM_MANAGER));
192         mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_OTHER_USER_INTERACTION_ONGOING,
193                 new TareFactorData(mResources.getString(R.string.tare_other_interaction),
194                         EconomyManager.DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES,
195                         POLICY_ALARM_MANAGER));
196         mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_OTHER_USER_INTERACTION_MAX,
197                 new TareFactorData(mResources.getString(R.string.tare_other_interaction),
198                         EconomyManager.DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_MAX_CAKES,
199                         POLICY_ALARM_MANAGER));
200         mAlarmManagerMap.put(EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP,
201                 new TareFactorData(mResources.getString(R.string.tare_wakeup_exact_idle),
202                         EconomyManager
203                                 .DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP_CAKES,
204                         POLICY_ALARM_MANAGER));
205         mAlarmManagerMap.put(EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP,
206                 new TareFactorData(mResources.getString(R.string.tare_wakeup_inexact_idle),
207                         EconomyManager
208                                 .DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP_CAKES,
209                         POLICY_ALARM_MANAGER));
210         mAlarmManagerMap.put(EconomyManager.KEY_AM_ACTION_ALARM_EXACT_WAKEUP_CTP,
211                 new TareFactorData(mResources.getString(R.string.tare_wakeup_exact),
212                         EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_CTP_CAKES,
213                         POLICY_ALARM_MANAGER));
214         mAlarmManagerMap.put(EconomyManager.KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP,
215                 new TareFactorData(mResources.getString(R.string.tare_wakeup_inexact),
216                         EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP_CAKES,
217                         POLICY_ALARM_MANAGER));
218         mAlarmManagerMap.put(
219                 EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP,
220                 new TareFactorData(mResources.getString(R.string.tare_nonwakeup_exact_idle),
221                         EconomyManager
222                                 .DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP_CAKES,
223                         POLICY_ALARM_MANAGER));
224         mAlarmManagerMap.put(EconomyManager.KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP,
225                 new TareFactorData(mResources.getString(R.string.tare_nonwakeup_exact),
226                         EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP_CAKES,
227                         POLICY_ALARM_MANAGER));
228         mAlarmManagerMap.put(
229                 EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP,
230                 new TareFactorData(mResources.getString(R.string.tare_nonwakeup_inexact_idle),
231                         DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP_CAKES,
232                         POLICY_ALARM_MANAGER));
233         mAlarmManagerMap.put(EconomyManager.KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP,
234                 new TareFactorData(mResources.getString(R.string.tare_nonwakeup_inexact),
235                         EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP_CAKES,
236                         POLICY_ALARM_MANAGER));
237         mAlarmManagerMap.put(EconomyManager.KEY_AM_ACTION_ALARM_ALARMCLOCK_CTP,
238                 new TareFactorData(mResources.getString(R.string.tare_alarm_clock),
239                         EconomyManager.DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_CTP_CAKES,
240                         POLICY_ALARM_MANAGER));
241         mAlarmManagerMap.put(
242                 EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE,
243                 new TareFactorData(mResources.getString(R.string.tare_alarm_clock),
244                         DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE_CAKES,
245                         POLICY_ALARM_MANAGER));
246         mAlarmManagerMap.put(
247                 EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE,
248                 new TareFactorData(mResources.getString(R.string.tare_alarm_clock),
249                         DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE_CAKES,
250                         POLICY_ALARM_MANAGER));
251         mAlarmManagerMap.put(EconomyManager.KEY_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE,
252                 new TareFactorData(mResources.getString(R.string.tare_alarm_clock),
253                         EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE_CAKES,
254                         POLICY_ALARM_MANAGER));
255         mAlarmManagerMap.put(EconomyManager.KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE,
256                 new TareFactorData(mResources.getString(R.string.tare_alarm_clock),
257                         EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE_CAKES,
258                         POLICY_ALARM_MANAGER));
259         mAlarmManagerMap.put(
260                 EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_BASE_PRICE,
261                 new TareFactorData(mResources.getString(R.string.tare_alarm_clock),
262                         EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE_CAKES,
263                         POLICY_ALARM_MANAGER));
264         mAlarmManagerMap.put(EconomyManager.KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE,
265                 new TareFactorData(mResources.getString(R.string.tare_alarm_clock),
266                         EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE_CAKES,
267                         POLICY_ALARM_MANAGER));
268         mAlarmManagerMap.put(
269                 EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE,
270                 new TareFactorData(mResources.getString(R.string.tare_alarm_clock),
271                         DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE_CAKES,
272                         POLICY_ALARM_MANAGER));
273         mAlarmManagerMap.put(EconomyManager.KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE,
274                 new TareFactorData(mResources.getString(R.string.tare_alarm_clock),
275                         EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE_CAKES,
276                         POLICY_ALARM_MANAGER));
277         mAlarmManagerMap.put(EconomyManager.KEY_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE,
278                 new TareFactorData(mResources.getString(R.string.tare_alarm_clock),
279                         EconomyManager.DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE_CAKES,
280                         POLICY_ALARM_MANAGER));
281     }
282 
283     /**
284      * Initialization for JobScheduler Map that sets a JS factor key to a title, default value, and
285      * policy type in a data object.
286      */
initJobSchedulerMap()287     private void initJobSchedulerMap() {
288         mJobSchedulerMap.put(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED,
289                 new TareFactorData(mResources.getString(R.string.tare_min_balance_exempted),
290                         EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED_CAKES,
291                         POLICY_JOB_SCHEDULER));
292         mJobSchedulerMap.put(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
293                 new TareFactorData(mResources.getString(R.string.tare_min_balance_headless_app),
294                         EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES,
295                         POLICY_JOB_SCHEDULER));
296         mJobSchedulerMap.put(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP,
297                 new TareFactorData(mResources.getString(R.string.tare_min_balance_other_app),
298                         EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES,
299                         POLICY_JOB_SCHEDULER));
300         mJobSchedulerMap.put(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER,
301                 new TareFactorData(
302                         mResources.getString(R.string.tare_min_balance_addition_app_updater),
303                         EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER_CAKES,
304                         POLICY_JOB_SCHEDULER));
305         mJobSchedulerMap.put(EconomyManager.KEY_JS_MAX_SATIATED_BALANCE,
306                 new TareFactorData(mResources.getString(R.string.tare_max_satiated_balance),
307                         EconomyManager.DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES,
308                         POLICY_JOB_SCHEDULER));
309         mJobSchedulerMap.put(EconomyManager.KEY_JS_INITIAL_CONSUMPTION_LIMIT,
310                 new TareFactorData(mResources.getString(R.string.tare_initial_consumption_limit),
311                         EconomyManager.DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT_CAKES,
312                         POLICY_JOB_SCHEDULER));
313         mJobSchedulerMap.put(EconomyManager.KEY_JS_MIN_CONSUMPTION_LIMIT,
314                 new TareFactorData(mResources.getString(R.string.tare_min_consumption_limit),
315                         EconomyManager.DEFAULT_JS_MIN_CONSUMPTION_LIMIT_CAKES,
316                         POLICY_JOB_SCHEDULER));
317         mJobSchedulerMap.put(EconomyManager.KEY_JS_MAX_CONSUMPTION_LIMIT,
318                 new TareFactorData(mResources.getString(R.string.tare_max_consumption_limit),
319                         EconomyManager.DEFAULT_JS_MAX_CONSUMPTION_LIMIT_CAKES,
320                         POLICY_JOB_SCHEDULER));
321         mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_APP_INSTALL_INSTANT,
322                 new TareFactorData(mResources.getString(R.string.tare_app_install),
323                         EconomyManager.DEFAULT_JS_REWARD_APP_INSTALL_INSTANT_CAKES,
324                         POLICY_JOB_SCHEDULER));
325         mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_APP_INSTALL_ONGOING,
326                 new TareFactorData(mResources.getString(R.string.tare_app_install),
327                         EconomyManager.DEFAULT_JS_REWARD_APP_INSTALL_ONGOING_CAKES,
328                         POLICY_JOB_SCHEDULER));
329         mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_APP_INSTALL_MAX,
330                 new TareFactorData(mResources.getString(R.string.tare_app_install),
331                         EconomyManager.DEFAULT_JS_REWARD_APP_INSTALL_MAX_CAKES,
332                         POLICY_JOB_SCHEDULER));
333         mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_TOP_ACTIVITY_INSTANT,
334                 new TareFactorData(mResources.getString(R.string.tare_top_activity),
335                         EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_INSTANT_CAKES,
336                         POLICY_JOB_SCHEDULER));
337         mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_TOP_ACTIVITY_ONGOING,
338                 new TareFactorData(mResources.getString(R.string.tare_top_activity),
339                         EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_ONGOING_CAKES,
340                         POLICY_JOB_SCHEDULER));
341         mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_TOP_ACTIVITY_MAX,
342                 new TareFactorData(mResources.getString(R.string.tare_top_activity),
343                         EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_MAX_CAKES,
344                         POLICY_JOB_SCHEDULER));
345         mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_NOTIFICATION_SEEN_INSTANT,
346                 new TareFactorData(mResources.getString(R.string.tare_notification_seen),
347                         EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES,
348                         POLICY_JOB_SCHEDULER));
349         mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_NOTIFICATION_SEEN_ONGOING,
350                 new TareFactorData(mResources.getString(R.string.tare_notification_seen),
351                         EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES,
352                         POLICY_JOB_SCHEDULER));
353         mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_NOTIFICATION_SEEN_MAX,
354                 new TareFactorData(mResources.getString(R.string.tare_notification_seen),
355                         EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_MAX_CAKES,
356                         POLICY_JOB_SCHEDULER));
357         mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT,
358                 new TareFactorData(mResources.getString(R.string.tare_notification_interaction),
359                         EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES,
360                         POLICY_JOB_SCHEDULER));
361         mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING,
362                 new TareFactorData(mResources.getString(R.string.tare_notification_interaction),
363                         EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES,
364                         POLICY_JOB_SCHEDULER));
365         mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_NOTIFICATION_INTERACTION_MAX,
366                 new TareFactorData(mResources.getString(R.string.tare_notification_interaction),
367                         EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES,
368                         POLICY_JOB_SCHEDULER));
369         mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_WIDGET_INTERACTION_INSTANT,
370                 new TareFactorData(mResources.getString(R.string.tare_widget_interaction),
371                         EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_INSTANT_CAKES,
372                         POLICY_JOB_SCHEDULER));
373         mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_WIDGET_INTERACTION_ONGOING,
374                 new TareFactorData(mResources.getString(R.string.tare_widget_interaction),
375                         EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_ONGOING_CAKES,
376                         POLICY_JOB_SCHEDULER));
377         mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_WIDGET_INTERACTION_MAX,
378                 new TareFactorData(mResources.getString(R.string.tare_widget_interaction),
379                         EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_MAX_CAKES,
380                         POLICY_JOB_SCHEDULER));
381         mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_OTHER_USER_INTERACTION_INSTANT,
382                 new TareFactorData(mResources.getString(R.string.tare_other_interaction),
383                         EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES,
384                         POLICY_JOB_SCHEDULER));
385         mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_OTHER_USER_INTERACTION_ONGOING,
386                 new TareFactorData(mResources.getString(R.string.tare_other_interaction),
387                         EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES,
388                         POLICY_JOB_SCHEDULER));
389         mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_OTHER_USER_INTERACTION_MAX,
390                 new TareFactorData(mResources.getString(R.string.tare_other_interaction),
391                         EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX_CAKES,
392                         POLICY_JOB_SCHEDULER));
393         mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_MAX_START_CTP,
394                 new TareFactorData(mResources.getString(R.string.tare_job_max_start),
395                         EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_START_CTP_CAKES,
396                         POLICY_JOB_SCHEDULER));
397         mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_MAX_RUNNING_CTP,
398                 new TareFactorData(mResources.getString(R.string.tare_job_max_running),
399                         EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_RUNNING_CTP_CAKES,
400                         POLICY_JOB_SCHEDULER));
401         mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_HIGH_START_CTP,
402                 new TareFactorData(mResources.getString(R.string.tare_job_high_start),
403                         EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_START_CTP_CAKES,
404                         POLICY_JOB_SCHEDULER));
405         mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_HIGH_RUNNING_CTP,
406                 new TareFactorData(mResources.getString(R.string.tare_job_high_running),
407                         EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_CTP_CAKES,
408                         POLICY_JOB_SCHEDULER));
409         mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_START_CTP,
410                 new TareFactorData(mResources.getString(R.string.tare_job_default_start),
411                         EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_START_CTP_CAKES,
412                         POLICY_JOB_SCHEDULER));
413         mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_RUNNING_CTP,
414                 new TareFactorData(mResources.getString(R.string.tare_job_default_running),
415                         EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_CTP_CAKES,
416                         POLICY_JOB_SCHEDULER));
417         mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_LOW_START_CTP,
418                 new TareFactorData(mResources.getString(R.string.tare_job_low_start),
419                         EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_START_CTP_CAKES,
420                         POLICY_JOB_SCHEDULER));
421         mJobSchedulerMap.put(
422                 EconomyManager.KEY_JS_ACTION_JOB_LOW_RUNNING_CTP,
423                 new TareFactorData(mResources.getString(R.string.tare_job_low_running),
424                         EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_RUNNING_CTP_CAKES,
425                         POLICY_JOB_SCHEDULER));
426         mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_MIN_START_CTP,
427                 new TareFactorData(mResources.getString(R.string.tare_job_min_start),
428                         EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_START_CTP_CAKES,
429                         POLICY_JOB_SCHEDULER));
430         mJobSchedulerMap.put(
431                 EconomyManager.KEY_JS_ACTION_JOB_MIN_RUNNING_CTP,
432                 new TareFactorData(mResources.getString(R.string.tare_job_min_running),
433                         EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_RUNNING_CTP_CAKES,
434                         POLICY_JOB_SCHEDULER));
435         mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP,
436                 new TareFactorData(mResources.getString(R.string.tare_job_timeout_penalty),
437                         EconomyManager.DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP_CAKES,
438                         POLICY_JOB_SCHEDULER));
439         mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_MAX_START_BASE_PRICE,
440                 new TareFactorData(mResources.getString(R.string.tare_job_max_start),
441                         EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_START_BASE_PRICE_CAKES,
442                         POLICY_JOB_SCHEDULER));
443         mJobSchedulerMap.put(
444                 EconomyManager.KEY_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE,
445                 new TareFactorData(mResources.getString(R.string.tare_job_max_running),
446                         EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE_CAKES,
447                         POLICY_JOB_SCHEDULER));
448         mJobSchedulerMap.put(
449                 EconomyManager.KEY_JS_ACTION_JOB_HIGH_START_BASE_PRICE,
450                 new TareFactorData(mResources.getString(R.string.tare_job_high_start),
451                         EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_START_BASE_PRICE_CAKES,
452                         POLICY_JOB_SCHEDULER));
453         mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE,
454                 new TareFactorData(mResources.getString(R.string.tare_job_high_running),
455                         EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE_CAKES,
456                         POLICY_JOB_SCHEDULER));
457         mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE,
458                 new TareFactorData(mResources.getString(R.string.tare_job_default_start),
459                         EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE_CAKES,
460                         POLICY_JOB_SCHEDULER));
461         mJobSchedulerMap.put(
462                 EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE,
463                 new TareFactorData(mResources.getString(R.string.tare_job_default_running),
464                         EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE_CAKES,
465                         POLICY_JOB_SCHEDULER));
466         mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_LOW_START_BASE_PRICE,
467                 new TareFactorData(mResources.getString(R.string.tare_job_low_start),
468                         EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_START_BASE_PRICE_CAKES,
469                         POLICY_JOB_SCHEDULER));
470         mJobSchedulerMap.put(
471                 EconomyManager.KEY_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE,
472                 new TareFactorData(mResources.getString(R.string.tare_job_low_running),
473                         EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE_CAKES,
474                         POLICY_JOB_SCHEDULER));
475         mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_MIN_START_BASE_PRICE,
476                 new TareFactorData(mResources.getString(R.string.tare_job_min_start),
477                         EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_START_BASE_PRICE_CAKES,
478                         POLICY_JOB_SCHEDULER));
479         mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE,
480                 new TareFactorData(mResources.getString(R.string.tare_job_min_running),
481                         EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE_CAKES,
482                         POLICY_JOB_SCHEDULER));
483         mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE,
484                 new TareFactorData(mResources.getString(R.string.tare_job_timeout_penalty),
485                         EconomyManager.DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE_CAKES,
486                         POLICY_JOB_SCHEDULER));
487     }
488 
489     /**
490      * Parses the AM constant from Settings.Global to get to the current value.
491      */
parseAlarmManagerGlobalSettings()492     private void parseAlarmManagerGlobalSettings() {
493         parseSettingsIntoMap(mAlarmManagerConstants, mAlarmManagerMap);
494     }
495 
496     /**
497      * Parses the JS constant from Settings.Global to get to the current value.
498      */
parseJobSchedulerGlobalSettings()499     private void parseJobSchedulerGlobalSettings() {
500         parseSettingsIntoMap(mJobSchedulerConstants, mJobSchedulerMap);
501     }
502 
parseSettingsIntoMap(String constants, ArrayMap<String, TareFactorData> map)503     private void parseSettingsIntoMap(String constants, ArrayMap<String, TareFactorData> map) {
504         try {
505             mParser.setString(constants);
506         } catch (Exception e) {
507             Slog.e(TAG, "Bad string constants value", e);
508         }
509 
510         for (int i = map.size() - 1; i >= 0; --i) {
511             final String key = map.keyAt(i);
512             final TareFactorData data = map.valueAt(i);
513             data.currentValue = parseCreditValue(mParser.getString(key, null), data.defaultValue);
514         }
515     }
516 
517     @NonNull
getMap(int factorPolicy)518     private ArrayMap<String, TareFactorData> getMap(int factorPolicy) {
519         switch (factorPolicy) {
520             case POLICY_ALARM_MANAGER:
521                 return mAlarmManagerMap;
522             case POLICY_JOB_SCHEDULER:
523                 return mJobSchedulerMap;
524             default:
525                 throw new IllegalArgumentException("Invalid factor policy given");
526         }
527     }
528 
529     /**
530      * Takes a key and factor policy as input and grabs the title linked to it.
531      *
532      * @param key          the key of the factor you want to get the title of
533      * @param factorPolicy the policy you want the title of
534      */
getTitle(String key, int factorPolicy)535     private String getTitle(String key, int factorPolicy) {
536         final ArrayMap<String, TareFactorData> currentMap = getMap(factorPolicy);
537         return currentMap.get(key).title;
538     }
539 
540     /**
541      * Takes a key and factor policy as input and grabs the current value linked to it.
542      *
543      * @param key          the key of the factor you want to get the default value of
544      * @param factorPolicy the policy you want the current value of
545      */
getCurrentValue(String key, int factorPolicy)546     private long getCurrentValue(String key, int factorPolicy) {
547         final ArrayMap<String, TareFactorData> currentMap = getMap(factorPolicy);
548         return currentMap.get(key).currentValue;
549     }
550 
551     /**
552      * Takes a key as input and grabs the factor type linked to it.
553      *
554      * @param key the key of the factor you want to get the factor type of
555      */
getFactorType(String key)556     private int getFactorType(String key) {
557         ArrayMap<String, TareFactorData> currentMap;
558         if (mAlarmManagerMap.containsKey(key)) {
559             currentMap = mAlarmManagerMap;
560         } else if (mJobSchedulerMap.containsKey(key)) {
561             currentMap = mJobSchedulerMap;
562         } else {
563             throw new IllegalArgumentException("Couldn't link key '" + key + "' to a policy");
564         }
565         return currentMap.get(key).factorPolicy;
566     }
567 
getValue(String key)568     long getValue(String key) {
569         final int policy = getFactorType(key);
570         return getCurrentValue(key, policy);
571     }
572 
573     /**
574      * Takes a key,edited value, and factor policy as input and assigns the new edited value to
575      * be the new current value for that factors key.
576      *
577      * @param key          the key of the factor you want to get the default value of
578      * @param editedValue  the value entered by the user in the dialog
579      * @param factorPolicy policy being updated
580      */
updateValue(String key, long editedValue, int factorPolicy)581     public void updateValue(String key, long editedValue, int factorPolicy) {
582         final ArrayMap<String, TareFactorData> map = getMap(factorPolicy);
583 
584         final TareFactorData data = map.get(key);
585         if (data.currentValue == editedValue) {
586             return;
587         }
588         data.currentValue = editedValue;
589         rebuildPolicyConstants(factorPolicy);
590     }
591 
592     /**
593      * Iterates through the factor policy map for keys and current values to
594      * rebuild a current string that is then assigned to be the new global settings string.
595      *
596      * @param factorPolicy policy being updated
597      */
rebuildPolicyConstants(int factorPolicy)598     private void rebuildPolicyConstants(int factorPolicy) {
599         switch (factorPolicy) {
600             case POLICY_ALARM_MANAGER:
601                 writeConstantsToSettings(mAlarmManagerMap, TARE_ALARM_MANAGER_CONSTANTS);
602                 break;
603             case POLICY_JOB_SCHEDULER:
604                 writeConstantsToSettings(mJobSchedulerMap, TARE_JOB_SCHEDULER_CONSTANTS);
605                 break;
606         }
607     }
608 
writeConstantsToSettings(ArrayMap<String, TareFactorData> factorMap, String settingsKey)609     private void writeConstantsToSettings(ArrayMap<String, TareFactorData> factorMap,
610             String settingsKey) {
611         final StringBuilder constantsStringBuilder = new StringBuilder();
612 
613         for (int i = 0, size = factorMap.size(); i < size; ++i) {
614             final TareFactorData factor = factorMap.valueAt(i);
615             if (factor.currentValue == factor.defaultValue) {
616                 continue;
617             }
618 
619             if (constantsStringBuilder.length() > 0) {
620                 constantsStringBuilder.append(",");
621             }
622 
623             constantsStringBuilder
624                     .append(factorMap.keyAt(i))
625                     .append("=");
626             if (factor.currentValue % CAKE_IN_ARC == 0) {
627                 constantsStringBuilder
628                         .append(factor.currentValue / CAKE_IN_ARC)
629                         .append("A");
630             } else {
631                 constantsStringBuilder
632                         .append(factor.currentValue)
633                         .append("ck");
634             }
635         }
636 
637         Settings.Global.putString(mContentResolver, settingsKey, constantsStringBuilder.toString());
638     }
639 
640     /**
641      * Creates a dialog with the values linked to the key.
642      *
643      * @param key the key of the factor you want to get the default value of
644      */
createDialog(String key)645     public TareFactorDialogFragment createDialog(String key) {
646         int policy = getFactorType(key);
647         return new TareFactorDialogFragment(getTitle(key, policy), key,
648                 getCurrentValue(key, policy), policy, this);
649     }
650 
651     /**
652      * Data object that holds a title,default value,and current value for a key.
653      */
654     private static class TareFactorData {
655         public final String title;
656         public final long defaultValue;
657         public final int factorPolicy;
658         public long currentValue;
659 
TareFactorData(String title, long defaultValue, int factorPolicy)660         TareFactorData(String title, long defaultValue, int factorPolicy) {
661             this.title = title;
662             this.defaultValue = defaultValue;
663             this.factorPolicy = factorPolicy;
664             this.currentValue = defaultValue;
665         }
666     }
667 
668     interface DataChangeListener {
onDataChanged()669         void onDataChanged();
670     }
671 
registerListener(DataChangeListener listener)672     void registerListener(DataChangeListener listener) {
673         mDataChangeListeners.add(listener);
674     }
675 
unregisterListener(DataChangeListener listener)676     void unregisterListener(DataChangeListener listener) {
677         mDataChangeListeners.remove(listener);
678     }
679 
notifyListeners()680     void notifyListeners() {
681         for (int i = mDataChangeListeners.size() - 1; i >= 0; --i) {
682             mDataChangeListeners.valueAt(i).onDataChanged();
683         }
684     }
685 
686     private class ConfigObserver extends ContentObserver {
687 
ConfigObserver(Handler handler)688         ConfigObserver(Handler handler) {
689             super(handler);
690         }
691 
start()692         public void start() {
693             mContentResolver.registerContentObserver(
694                     Settings.Global.getUriFor(TARE_ALARM_MANAGER_CONSTANTS), false, this);
695             mContentResolver.registerContentObserver(
696                     Settings.Global.getUriFor(TARE_JOB_SCHEDULER_CONSTANTS), false, this);
697         }
698 
699         @Override
onChange(boolean selfChange, Uri uri)700         public void onChange(boolean selfChange, Uri uri) {
701             if (uri.equals(Settings.Global.getUriFor(TARE_ALARM_MANAGER_CONSTANTS))) {
702                 mAlarmManagerConstants =
703                         Settings.Global.getString(mContentResolver, TARE_ALARM_MANAGER_CONSTANTS);
704                 parseAlarmManagerGlobalSettings();
705                 notifyListeners();
706             } else if (uri.equals(Settings.Global.getUriFor(TARE_JOB_SCHEDULER_CONSTANTS))) {
707                 mJobSchedulerConstants =
708                         Settings.Global.getString(mContentResolver, TARE_JOB_SCHEDULER_CONSTANTS);
709                 parseJobSchedulerGlobalSettings();
710                 notifyListeners();
711             }
712         }
713     }
714 }
715