diff --git a/res/values/strings.xml b/res/values/strings.xml index 9d868cbe4ea..917c666b41f 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -13731,18 +13731,26 @@ translate "maximum balance when device is fully charged" instead. Balance is the same meaning as having money in a bank account. Balance in our feature is the amount of Android Resource Credits an app can have. Android Resource Credits are a form of payment used by apps to be able to - perform tasks. [CHAR LIMIT=40]--> + perform tasks. [CHAR LIMIT=80]--> Maximum Satiated Balance - - Maximum Circulation - - Minimum Satiated Balance + + Balances + + Consumption Limits + + Initial Consumption Limit + + Maximum Consumption Limit + + + @string/tare_initial_consumption_limit + @string/tare_hard_consumption_limit + Modifiers @@ -13778,14 +13786,6 @@ Inexact NonWakeup Alarm AlarmClock - - Exempted - - Headless System App - - Other App Top Activity @@ -13842,12 +13842,29 @@ Job Timeout Penalty + + Minimum Satiated Balance (Exempted) + + Minimum Satiated Balance (Headless System App) + + Minimum Satiated Balance (Remaining Apps) - - @string/tare_exempted - @string/tare_headless_app - @string/tare_other_app + + @string/tare_max_satiated_balance + @string/tare_min_balance_exempted + @string/tare_min_balance_headless_app + @string/tare_min_balance_other_app diff --git a/src/com/android/settings/development/tare/AlarmManagerFragment.java b/src/com/android/settings/development/tare/AlarmManagerFragment.java index dbc4e588c8d..fe76b1287b3 100644 --- a/src/com/android/settings/development/tare/AlarmManagerFragment.java +++ b/src/com/android/settings/development/tare/AlarmManagerFragment.java @@ -15,17 +15,16 @@ */ package com.android.settings.development.tare; +import android.annotation.Nullable; import android.app.Fragment; +import android.app.tare.EconomyManager; import android.content.res.Resources; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.BaseExpandableListAdapter; import android.widget.ExpandableListView; import android.widget.ExpandableListView.OnChildClickListener; -import android.widget.TextView; -import android.widget.Toast; import com.android.settings.R; @@ -33,130 +32,96 @@ import com.android.settings.R; * Creates the AlarmManager fragment to display all the AlarmManager factors * when the AlarmManager policy is chosen in the dropdown TARE menu. */ -public class AlarmManagerFragment extends Fragment { +public class AlarmManagerFragment extends Fragment implements + TareFactorController.DataChangeListener { + + private TareFactorController mFactorController; + + private TareFactorExpandableListAdapter mExpandableListAdapter; + + private String[] mGroups; + private String[][] mChildren; + private String[][] mKeys; + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mFactorController = TareFactorController.getInstance(getContext()); + populateArrays(); + } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.tare_policy_fragment, null); ExpandableListView elv = (ExpandableListView) v.findViewById(R.id.factor_list); - final SavedTabsListAdapter expListAdapter = new SavedTabsListAdapter(); + mExpandableListAdapter = new TareFactorExpandableListAdapter( + mFactorController, LayoutInflater.from(getActivity()), mGroups, mChildren, mKeys); elv.setGroupIndicator(null); - elv.setAdapter(expListAdapter); + elv.setAdapter(mExpandableListAdapter); elv.setOnChildClickListener(new OnChildClickListener() { public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { - final String selected = - (String) expListAdapter.getChild(groupPosition, childPosition); - Toast.makeText(getActivity(), selected, Toast.LENGTH_SHORT).show(); + final String key = mExpandableListAdapter.getKey(groupPosition, childPosition); + mFactorController.createDialog(key).show(getFragmentManager(), key); return true; } }); return v; } - /** - * Creates the expandable list containing all AlarmManager factors within the - * AlarmManager fragment. - */ - public class SavedTabsListAdapter extends BaseExpandableListAdapter { + @Override + public void onStart() { + super.onStart(); + mFactorController.registerListener(this); + } - private final LayoutInflater mInflater; - private Resources mResources = getActivity().getResources(); + @Override + public void onStop() { + mFactorController.unregisterListener(this); + super.onStop(); + } - private String[] mGroups = { - mResources.getString(R.string.tare_max_circulation), - mResources.getString(R.string.tare_max_satiated_balance), - mResources.getString(R.string.tare_min_satiated_balance), - mResources.getString(R.string.tare_modifiers), - mResources.getString(R.string.tare_actions), - mResources.getString(R.string.tare_rewards) + @Override + public void onDataChanged() { + mExpandableListAdapter.notifyDataSetChanged(); + } + + private void populateArrays() { + final Resources resources = getResources(); + + mGroups = new String[]{ + resources.getString(R.string.tare_consumption_limits), + resources.getString(R.string.tare_balances), + // resources.getString(R.string.tare_modifiers), + // resources.getString(R.string.tare_actions), + // resources.getString(R.string.tare_rewards) }; - /* - * First two are empty arrays because the first two factors have no subfactors (no - * children). - */ - private String[][] mChildren = { - {}, - {}, - mResources.getStringArray(R.array.tare_min_satiated_balance_subfactors), - mResources.getStringArray(R.array.tare_modifiers_subfactors), - mResources.getStringArray(R.array.tare_alarm_manager_actions), - mResources.getStringArray(R.array.tare_rewards_subfactors) + mChildren = new String[][]{ + resources.getStringArray(R.array.tare_consumption_limit_subfactors), + resources.getStringArray(R.array.tare_app_balance_subfactors), + // TODO: support + // resources.getStringArray(R.array.tare_modifiers_subfactors), + // resources.getStringArray(R.array.tare_alarm_manager_actions), + // resources.getStringArray(R.array.tare_rewards_subfactors) }; - public SavedTabsListAdapter() { - mInflater = LayoutInflater.from(getActivity()); - } - - @Override - public int getGroupCount() { - return mGroups.length; - } - - @Override - public int getChildrenCount(int groupPosition) { - return mChildren[groupPosition].length; - } - - @Override - public Object getGroup(int groupPosition) { - return mGroups[groupPosition]; - } - - @Override - public Object getChild(int groupPosition, int childPosition) { - return mChildren[groupPosition][childPosition]; - } - - @Override - public long getGroupId(int groupPosition) { - return groupPosition; - } - - @Override - public long getChildId(int groupPosition, int childPosition) { - return childPosition; - } - - @Override - public boolean hasStableIds() { - return true; - } - - @Override - public View getGroupView(int groupPosition, boolean isExpanded, View convertView, - ViewGroup parent) { - if (convertView == null) { - convertView = mInflater.inflate(android.R.layout.simple_list_item_1, parent, false); - } - TextView factor = (TextView) convertView.findViewById(android.R.id.text1); - factor.setText(getGroup(groupPosition).toString()); - return convertView; - } - - @Override - public View getChildView(int groupPosition, int childPosition, boolean isLastChild, - View convertView, ViewGroup parent) { - // Here a custom child item is used instead of android.R.simple_list_item_2 because it - // is more customizable for this specific UI - if (convertView == null) { - convertView = mInflater.inflate(R.layout.tare_child_item, null); - } - TextView factor = (TextView) convertView.findViewById(R.id.factor); - TextView value = (TextView) convertView.findViewById(R.id.factor_number); - - // TODO: Replace these hardcoded values with either default or user inputted TARE values - factor.setText(getChild(groupPosition, childPosition).toString()); - value.setText("500"); - - return convertView; - } - - @Override - public boolean isChildSelectable(int groupPosition, int childPosition) { - return true; - } + mKeys = new String[][]{ + { + EconomyManager.KEY_AM_INITIAL_CONSUMPTION_LIMIT, + EconomyManager.KEY_AM_HARD_CONSUMPTION_LIMIT + }, + { + EconomyManager.KEY_AM_MAX_SATIATED_BALANCE, + EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED, + EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP, + EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP + }, + // {}, + // {}, + // {}, + }; } } diff --git a/src/com/android/settings/development/tare/DropdownActivity.java b/src/com/android/settings/development/tare/DropdownActivity.java index 55f1fec0585..66b57dd383f 100644 --- a/src/com/android/settings/development/tare/DropdownActivity.java +++ b/src/com/android/settings/development/tare/DropdownActivity.java @@ -43,7 +43,6 @@ public class DropdownActivity extends Activity { static final int POLICY_JOB_SCHEDULER = 1; private static final int DEFAULT_POLICY = POLICY_ALARM_MANAGER; - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); diff --git a/src/com/android/settings/development/tare/JobSchedulerFragment.java b/src/com/android/settings/development/tare/JobSchedulerFragment.java index 5a7f4a9e5fc..1c6598c9a47 100644 --- a/src/com/android/settings/development/tare/JobSchedulerFragment.java +++ b/src/com/android/settings/development/tare/JobSchedulerFragment.java @@ -15,17 +15,16 @@ */ package com.android.settings.development.tare; +import android.annotation.Nullable; import android.app.Fragment; +import android.app.tare.EconomyManager; import android.content.res.Resources; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.BaseExpandableListAdapter; import android.widget.ExpandableListView; import android.widget.ExpandableListView.OnChildClickListener; -import android.widget.TextView; -import android.widget.Toast; import com.android.settings.R; @@ -33,131 +32,97 @@ import com.android.settings.R; * Creates the JobScheduler fragment to display all the JobScheduler factors * when the JobScheduler policy is chosen in the dropdown TARE menu. */ -public class JobSchedulerFragment extends Fragment { +public class JobSchedulerFragment extends Fragment implements + TareFactorController.DataChangeListener { + + private TareFactorController mFactorController; + + private TareFactorExpandableListAdapter mExpandableListAdapter; + + private String[] mGroups; + private String[][] mChildren; + private String[][] mKeys; + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mFactorController = TareFactorController.getInstance(getContext()); + populateArrays(); + } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.tare_policy_fragment, null); ExpandableListView elv = (ExpandableListView) v.findViewById(R.id.factor_list); - final SavedTabsListAdapter expListAdapter = new SavedTabsListAdapter(); + mExpandableListAdapter = new TareFactorExpandableListAdapter( + mFactorController, LayoutInflater.from(getActivity()), mGroups, mChildren, mKeys); elv.setGroupIndicator(null); - elv.setAdapter(expListAdapter); + elv.setAdapter(mExpandableListAdapter); elv.setOnChildClickListener(new OnChildClickListener() { public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { - final String selected = - (String) expListAdapter.getChild(groupPosition, childPosition); - Toast.makeText(getActivity(), selected, Toast.LENGTH_SHORT) - .show(); + final String key = mExpandableListAdapter.getKey(groupPosition, childPosition); + mFactorController.createDialog(key).show(getFragmentManager(), key); return true; } }); + return v; } - /** - * Creates the expandable list containing all JobScheduler factors within the - * JobScheduler fragment. - */ - public class SavedTabsListAdapter extends BaseExpandableListAdapter { + @Override + public void onStart() { + super.onStart(); + mFactorController.registerListener(this); + } - private final LayoutInflater mInflater; - private Resources mResources = getActivity().getResources(); + @Override + public void onStop() { + mFactorController.unregisterListener(this); + super.onStop(); + } - private String[] mGroups = { - mResources.getString(R.string.tare_max_circulation), - mResources.getString(R.string.tare_max_satiated_balance), - mResources.getString(R.string.tare_min_satiated_balance), - mResources.getString(R.string.tare_modifiers), - mResources.getString(R.string.tare_actions), - mResources.getString(R.string.tare_rewards) + @Override + public void onDataChanged() { + mExpandableListAdapter.notifyDataSetChanged(); + } + + private void populateArrays() { + final Resources resources = getResources(); + + mGroups = new String[]{ + resources.getString(R.string.tare_consumption_limits), + resources.getString(R.string.tare_balances), + // mResources.getString(R.string.tare_modifiers), + // mResources.getString(R.string.tare_actions), + // mResources.getString(R.string.tare_rewards) }; - /* - * First two are empty arrays because the first two factors have no subfactors (no - * children). - */ - private String[][] mChildren = { - {}, - {}, - mResources.getStringArray(R.array.tare_min_satiated_balance_subfactors), - mResources.getStringArray(R.array.tare_modifiers_subfactors), - mResources.getStringArray(R.array.tare_job_scheduler_actions), - mResources.getStringArray(R.array.tare_rewards_subfactors) + mChildren = new String[][]{ + resources.getStringArray(R.array.tare_consumption_limit_subfactors), + resources.getStringArray(R.array.tare_app_balance_subfactors), + // TODO: support + // mResources.getStringArray(R.array.tare_modifiers_subfactors), + // mResources.getStringArray(R.array.tare_job_scheduler_actions), + // mResources.getStringArray(R.array.tare_rewards_subfactors) }; - public SavedTabsListAdapter() { - mInflater = LayoutInflater.from(getActivity()); - } - - @Override - public int getGroupCount() { - return mGroups.length; - } - - @Override - public int getChildrenCount(int groupPosition) { - return mChildren[groupPosition].length; - } - - @Override - public Object getGroup(int groupPosition) { - return mGroups[groupPosition]; - } - - @Override - public Object getChild(int groupPosition, int childPosition) { - return mChildren[groupPosition][childPosition]; - } - - @Override - public long getGroupId(int groupPosition) { - return groupPosition; - } - - @Override - public long getChildId(int groupPosition, int childPosition) { - return childPosition; - } - - @Override - public boolean hasStableIds() { - return true; - } - - @Override - public View getGroupView(int groupPosition, boolean isExpanded, View convertView, - ViewGroup parent) { - if (convertView == null) { - convertView = mInflater.inflate(android.R.layout.simple_list_item_1, parent, false); - } - TextView factor = (TextView) convertView.findViewById(android.R.id.text1); - factor.setText(getGroup(groupPosition).toString()); - return convertView; - } - - @Override - public View getChildView(int groupPosition, int childPosition, boolean isLastChild, - View convertView, ViewGroup parent) { - // Here a custom child item is used instead of android.R.simple_list_item_2 because it - // is more customizable for this specific UI - if (convertView == null) { - convertView = mInflater.inflate(R.layout.tare_child_item, null); - } - TextView factor = (TextView) convertView.findViewById(R.id.factor); - TextView value = (TextView) convertView.findViewById(R.id.factor_number); - - // TODO: Replace these hardcoded values with either default or user inputted TARE values - factor.setText(getChild(groupPosition, childPosition).toString()); - value.setText("500"); - - return convertView; - } - - @Override - public boolean isChildSelectable(int groupPosition, int childPosition) { - return true; - } + mKeys = new String[][]{ + { + EconomyManager.KEY_JS_INITIAL_CONSUMPTION_LIMIT, + EconomyManager.KEY_JS_HARD_CONSUMPTION_LIMIT + }, + { + EconomyManager.KEY_JS_MAX_SATIATED_BALANCE, + EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED, + EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP, + EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP + }, + // {}, + // {}, + // {}, + }; } } diff --git a/src/com/android/settings/development/tare/TareFactorController.java b/src/com/android/settings/development/tare/TareFactorController.java index 3cabd8d05a4..b9f813d3ef3 100644 --- a/src/com/android/settings/development/tare/TareFactorController.java +++ b/src/com/android/settings/development/tare/TareFactorController.java @@ -24,8 +24,13 @@ import android.app.tare.EconomyManager; import android.content.ContentResolver; import android.content.Context; import android.content.res.Resources; +import android.database.ContentObserver; +import android.net.Uri; +import android.os.Handler; +import android.os.Looper; import android.provider.Settings; import android.util.ArrayMap; +import android.util.ArraySet; import android.util.KeyValueListParser; import android.util.Slog; @@ -38,6 +43,8 @@ import com.android.settings.R; public class TareFactorController { private static final String TAG = "TareFactorController"; + private static TareFactorController sInstance; + private static final int POLICY_ALARM_MANAGER = 0; private static final int POLICY_JOB_SCHEDULER = 1; @@ -49,10 +56,15 @@ public class TareFactorController { private String mAlarmManagerConstants; private String mJobSchedulerConstants; - public TareFactorController(Context context) { + private final ArraySet mDataChangeListeners = new ArraySet<>(); + + private TareFactorController(Context context) { mContentResolver = context.getContentResolver(); mResources = context.getResources(); + ConfigObserver configObserver = new ConfigObserver(new Handler(Looper.getMainLooper())); + configObserver.start(); + mAlarmManagerConstants = Settings.Global.getString(mContentResolver, TARE_ALARM_MANAGER_CONSTANTS); mJobSchedulerConstants = @@ -65,21 +77,30 @@ public class TareFactorController { parseJobSchedulerGlobalSettings(); } + static TareFactorController getInstance(Context context) { + synchronized (TareFactorController.class) { + if (sInstance == null) { + sInstance = new TareFactorController(context.getApplicationContext()); + } + } + return sInstance; + } + /** * Initialization for AlarmManager Map that sets a AM factor key to a title, default value, and * policy type in a data object. */ private void initAlarmManagerMap() { mAlarmManagerMap.put(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED, - new TareFactorData(mResources.getString(R.string.tare_min_satiated_balance), + new TareFactorData(mResources.getString(R.string.tare_min_balance_exempted), EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED, POLICY_ALARM_MANAGER)); mAlarmManagerMap.put(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP, - new TareFactorData(mResources.getString(R.string.tare_headless_app), + new TareFactorData(mResources.getString(R.string.tare_min_balance_headless_app), EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP, POLICY_ALARM_MANAGER)); mAlarmManagerMap.put(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP, - new TareFactorData(mResources.getString(R.string.tare_other_app), + new TareFactorData(mResources.getString(R.string.tare_min_balance_other_app), EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP, POLICY_ALARM_MANAGER)); mAlarmManagerMap.put(EconomyManager.KEY_AM_MAX_SATIATED_BALANCE, @@ -87,9 +108,13 @@ public class TareFactorController { EconomyManager.DEFAULT_AM_MAX_SATIATED_BALANCE, POLICY_ALARM_MANAGER)); mAlarmManagerMap.put(EconomyManager.KEY_AM_INITIAL_CONSUMPTION_LIMIT, - new TareFactorData(mResources.getString(R.string.tare_max_circulation), + new TareFactorData(mResources.getString(R.string.tare_initial_consumption_limit), EconomyManager.DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT, POLICY_ALARM_MANAGER)); + mAlarmManagerMap.put(EconomyManager.KEY_AM_HARD_CONSUMPTION_LIMIT, + new TareFactorData(mResources.getString(R.string.tare_hard_consumption_limit), + EconomyManager.DEFAULT_AM_HARD_CONSUMPTION_LIMIT, + POLICY_ALARM_MANAGER)); mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_TOP_ACTIVITY_INSTANT, new TareFactorData(mResources.getString(R.string.tare_top_activity), EconomyManager.DEFAULT_AM_REWARD_TOP_ACTIVITY_INSTANT, @@ -253,15 +278,15 @@ public class TareFactorController { */ private void initJobSchedulerMap() { mJobSchedulerMap.put(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED, - new TareFactorData(mResources.getString(R.string.tare_min_satiated_balance), + new TareFactorData(mResources.getString(R.string.tare_min_balance_exempted), EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED, POLICY_JOB_SCHEDULER)); mJobSchedulerMap.put(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP, - new TareFactorData(mResources.getString(R.string.tare_headless_app), + new TareFactorData(mResources.getString(R.string.tare_min_balance_headless_app), EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP, POLICY_JOB_SCHEDULER)); mJobSchedulerMap.put(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP, - new TareFactorData(mResources.getString(R.string.tare_other_app), + new TareFactorData(mResources.getString(R.string.tare_min_balance_other_app), EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP, POLICY_JOB_SCHEDULER)); mJobSchedulerMap.put(EconomyManager.KEY_JS_MAX_SATIATED_BALANCE, @@ -269,9 +294,13 @@ public class TareFactorController { EconomyManager.DEFAULT_JS_MAX_SATIATED_BALANCE, POLICY_JOB_SCHEDULER)); mJobSchedulerMap.put(EconomyManager.KEY_JS_INITIAL_CONSUMPTION_LIMIT, - new TareFactorData(mResources.getString(R.string.tare_max_circulation), + new TareFactorData(mResources.getString(R.string.tare_initial_consumption_limit), EconomyManager.DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT, POLICY_JOB_SCHEDULER)); + mJobSchedulerMap.put(EconomyManager.KEY_JS_HARD_CONSUMPTION_LIMIT, + new TareFactorData(mResources.getString(R.string.tare_hard_consumption_limit), + EconomyManager.DEFAULT_JS_HARD_CONSUMPTION_LIMIT, + POLICY_JOB_SCHEDULER)); mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_TOP_ACTIVITY_INSTANT, new TareFactorData(mResources.getString(R.string.tare_top_activity), EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_INSTANT, @@ -474,17 +503,7 @@ public class TareFactorController { * @param factorPolicy the policy you want the title of */ private String getTitle(String key, int factorPolicy) { - ArrayMap currentMap; - switch (factorPolicy) { - case POLICY_ALARM_MANAGER: - currentMap = mAlarmManagerMap; - break; - case POLICY_JOB_SCHEDULER: - currentMap = mJobSchedulerMap; - break; - default: - throw new IllegalArgumentException("Invalid factor policy given"); - } + final ArrayMap currentMap = getMap(factorPolicy); return currentMap.get(key).title; } @@ -516,6 +535,11 @@ public class TareFactorController { return currentMap.get(key).factorPolicy; } + int getValue(String key) { + final int policy = getFactorType(key); + return getCurrentValue(key, policy); + } + /** * Takes a key,edited value, and factor policy as input and assigns the new edited value to * be the new current value for that factors key. @@ -545,17 +569,9 @@ public class TareFactorController { switch (factorPolicy) { case POLICY_ALARM_MANAGER: writeConstantsToSettings(mAlarmManagerMap, TARE_ALARM_MANAGER_CONSTANTS); - - mAlarmManagerConstants = Settings.Global - .getString(mContentResolver, Settings.Global - .TARE_ALARM_MANAGER_CONSTANTS); break; case POLICY_JOB_SCHEDULER: writeConstantsToSettings(mJobSchedulerMap, TARE_JOB_SCHEDULER_CONSTANTS); - - mJobSchedulerConstants = Settings.Global - .getString(mContentResolver, Settings.Global - .TARE_JOB_SCHEDULER_CONSTANTS); break; } } @@ -610,4 +626,51 @@ public class TareFactorController { this.currentValue = defaultValue; } } -} \ No newline at end of file + + interface DataChangeListener { + void onDataChanged(); + } + + void registerListener(DataChangeListener listener) { + mDataChangeListeners.add(listener); + } + + void unregisterListener(DataChangeListener listener) { + mDataChangeListeners.remove(listener); + } + + void notifyListeners() { + for (int i = mDataChangeListeners.size() - 1; i >= 0; --i) { + mDataChangeListeners.valueAt(i).onDataChanged(); + } + } + + private class ConfigObserver extends ContentObserver { + + ConfigObserver(Handler handler) { + super(handler); + } + + public void start() { + mContentResolver.registerContentObserver( + Settings.Global.getUriFor(TARE_ALARM_MANAGER_CONSTANTS), false, this); + mContentResolver.registerContentObserver( + Settings.Global.getUriFor(TARE_JOB_SCHEDULER_CONSTANTS), false, this); + } + + @Override + public void onChange(boolean selfChange, Uri uri) { + if (uri.equals(Settings.Global.getUriFor(TARE_ALARM_MANAGER_CONSTANTS))) { + mAlarmManagerConstants = + Settings.Global.getString(mContentResolver, TARE_ALARM_MANAGER_CONSTANTS); + parseAlarmManagerGlobalSettings(); + notifyListeners(); + } else if (uri.equals(Settings.Global.getUriFor(TARE_JOB_SCHEDULER_CONSTANTS))) { + mJobSchedulerConstants = + Settings.Global.getString(mContentResolver, TARE_JOB_SCHEDULER_CONSTANTS); + parseJobSchedulerGlobalSettings(); + notifyListeners(); + } + } + } +} diff --git a/src/com/android/settings/development/tare/TareFactorExpandableListAdapter.java b/src/com/android/settings/development/tare/TareFactorExpandableListAdapter.java new file mode 100644 index 00000000000..8fe4c058207 --- /dev/null +++ b/src/com/android/settings/development/tare/TareFactorExpandableListAdapter.java @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.development.tare; + +import android.annotation.NonNull; +import android.annotation.SuppressLint; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseExpandableListAdapter; +import android.widget.TextView; + +import com.android.settings.R; + +/** + * Creates the expandable list that will allow modifying individual factors. + */ +public class TareFactorExpandableListAdapter extends BaseExpandableListAdapter { + + private final LayoutInflater mLayoutInflater; + private final TareFactorController mFactorController; + + private final String[] mGroups; + private final String[][] mChildren; + private final String[][] mKeys; + + TareFactorExpandableListAdapter(TareFactorController factorController, + LayoutInflater layoutInflater, String[] groups, String[][] children, String[][] keys) { + mLayoutInflater = layoutInflater; + mFactorController = factorController; + + mGroups = groups; + mChildren = children; + mKeys = keys; + + validateMappings(); + } + + private void validateMappings() { + if (mGroups.length != mChildren.length) { + throw new IllegalStateException("groups and children don't have the same length"); + } + if (mChildren.length != mKeys.length) { + throw new IllegalStateException("children and keys don't have the same length"); + } + for (int i = 0; i < mChildren.length; ++i) { + if (mChildren[i].length != mKeys[i].length) { + throw new IllegalStateException( + "children and keys don't have the same length in row " + i); + } + } + } + + @Override + public int getGroupCount() { + return mGroups.length; + } + + @Override + public int getChildrenCount(int groupPosition) { + return mChildren[groupPosition].length; + } + + @Override + public Object getGroup(int groupPosition) { + return mGroups[groupPosition]; + } + + @Override + public Object getChild(int groupPosition, int childPosition) { + return mChildren[groupPosition][childPosition]; + } + + @Override + public long getGroupId(int groupPosition) { + return groupPosition; + } + + @Override + public long getChildId(int groupPosition, int childPosition) { + return childPosition; + } + + @NonNull + String getKey(int groupPosition, int childPosition) { + return mKeys[groupPosition][childPosition]; + } + + @Override + public boolean hasStableIds() { + return true; + } + + @Override + public View getGroupView(int groupPosition, boolean isExpanded, View convertView, + ViewGroup parent) { + if (convertView == null) { + convertView = mLayoutInflater.inflate(android.R.layout.simple_list_item_1, parent, + false); + } + TextView factor = convertView.findViewById(android.R.id.text1); + factor.setText(getGroup(groupPosition).toString()); + return convertView; + } + + @Override + @SuppressLint("InflateParams") // AdapterView doesn't support addView + public View getChildView(int groupPosition, int childPosition, boolean isLastChild, + View convertView, ViewGroup parent) { + // Here a custom child item is used instead of android.R.simple_list_item_2 because it + // is more customizable for this specific UI + if (convertView == null) { + convertView = mLayoutInflater.inflate(R.layout.tare_child_item, null); + } + TextView factor = convertView.findViewById(R.id.factor); + TextView value = convertView.findViewById(R.id.factor_number); + + factor.setText(getChild(groupPosition, childPosition).toString()); + value.setText(String.valueOf( + mFactorController.getValue(getKey(groupPosition, childPosition)))); + + return convertView; + } + + @Override + public boolean isChildSelectable(int groupPosition, int childPosition) { + return true; + } +}