JobScheduler: remove TARE

Test: atest
Bug: 331617295

Change-Id: Ib5f363d6bbd5e1c9f817cc1987c1711c8135f70b
This commit is contained in:
Tim Murray
2024-03-22 13:33:18 -07:00
parent 0c85e4bca9
commit 431e86009e
10 changed files with 0 additions and 1760 deletions

View File

@@ -740,7 +740,6 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
controllers.add(new DefaultLaunchPreferenceController(context, "density")); controllers.add(new DefaultLaunchPreferenceController(context, "density"));
controllers.add(new DefaultLaunchPreferenceController(context, "background_check")); controllers.add(new DefaultLaunchPreferenceController(context, "background_check"));
controllers.add(new DefaultLaunchPreferenceController(context, "inactive_apps")); controllers.add(new DefaultLaunchPreferenceController(context, "inactive_apps"));
controllers.add(new TarePreferenceController(context));
controllers.add(new AutofillCategoryController(context, lifecycle)); controllers.add(new AutofillCategoryController(context, lifecycle));
controllers.add(new AutofillLoggingLevelPreferenceController(context, lifecycle)); controllers.add(new AutofillLoggingLevelPreferenceController(context, lifecycle));
controllers.add(new AutofillResetOptionsPreferenceController(context)); controllers.add(new AutofillResetOptionsPreferenceController(context));

View File

@@ -1,70 +0,0 @@
/*
* Copyright (C) 2023 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;
import android.app.tare.EconomyManager;
import android.content.Context;
import android.content.Intent;
import android.os.UserManager;
import android.provider.Settings;
import androidx.preference.Preference;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.development.tare.TareHomePage;
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
/** PreferenceController that serves as an entry point to the TARE configuration screen. */
public class TarePreferenceController extends
DeveloperOptionsPreferenceController implements PreferenceControllerMixin {
private static final String KEY_TARE = "tare";
private final EconomyManager mEconomyManager;
private final UserManager mUserManager;
public TarePreferenceController(Context context) {
super(context);
mEconomyManager = context.getSystemService(EconomyManager.class);
mUserManager = context.getSystemService(UserManager.class);
}
@Override
public boolean isAvailable() {
// Enable the UI if the dedicated flag enables it or if TARE itself is on.
final boolean settingEnabled = Settings.Global.getInt(
mContext.getContentResolver(), Settings.Global.SHOW_TARE_DEVELOPER_OPTIONS, 0) == 1;
final boolean isTareUiEnabled = settingEnabled
|| mEconomyManager.getEnabledMode() != EconomyManager.ENABLED_MODE_OFF;
return isTareUiEnabled
&& !mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES);
}
@Override
public String getPreferenceKey() {
return KEY_TARE;
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (!KEY_TARE.equals(preference.getKey())) {
return false;
}
mContext.startActivity(new Intent(mContext, TareHomePage.class));
return false;
}
}

View File

@@ -1,173 +0,0 @@
/*
* Copyright (C) 2021 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.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.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import androidx.annotation.Nullable;
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 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);
mExpandableListAdapter = new TareFactorExpandableListAdapter(
mFactorController, LayoutInflater.from(getActivity()), mGroups, mChildren, mKeys);
elv.setGroupIndicator(null);
elv.setAdapter(mExpandableListAdapter);
elv.setOnChildClickListener(new OnChildClickListener() {
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
final String key = mExpandableListAdapter.getKey(groupPosition, childPosition);
mFactorController.createDialog(key).show(getFragmentManager(), key);
return true;
}
});
return v;
}
@Override
public void onStart() {
super.onStart();
mFactorController.registerListener(this);
}
@Override
public void onStop() {
mFactorController.unregisterListener(this);
super.onStop();
}
@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_ctp),
resources.getString(R.string.tare_actions_base_price),
resources.getString(R.string.tare_rewards_instantaneous),
resources.getString(R.string.tare_rewards_ongoing),
resources.getString(R.string.tare_rewards_max)
};
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_alarm_manager_actions),
resources.getStringArray(R.array.tare_rewards_subfactors),
{resources.getString(R.string.tare_top_activity)},
resources.getStringArray(R.array.tare_rewards_subfactors)
};
mKeys = new String[][]{
{
EconomyManager.KEY_AM_INITIAL_CONSUMPTION_LIMIT,
EconomyManager.KEY_AM_MIN_CONSUMPTION_LIMIT,
EconomyManager.KEY_AM_MAX_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
},
// {},
{
EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP,
EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP,
EconomyManager.KEY_AM_ACTION_ALARM_EXACT_WAKEUP_CTP,
EconomyManager.KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP,
EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP,
EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP,
EconomyManager.KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP,
EconomyManager.KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP,
EconomyManager.KEY_AM_ACTION_ALARM_ALARMCLOCK_CTP
},
{
EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE,
EconomyManager
.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE,
EconomyManager.KEY_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE,
EconomyManager.KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE,
EconomyManager
.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_BASE_PRICE,
EconomyManager
.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE,
EconomyManager.KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE,
EconomyManager.KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE,
EconomyManager.KEY_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE
},
{
EconomyManager.KEY_AM_REWARD_TOP_ACTIVITY_INSTANT,
EconomyManager.KEY_AM_REWARD_NOTIFICATION_SEEN_INSTANT,
EconomyManager.KEY_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT,
EconomyManager.KEY_AM_REWARD_WIDGET_INTERACTION_INSTANT,
EconomyManager.KEY_AM_REWARD_OTHER_USER_INTERACTION_INSTANT,
},
{EconomyManager.KEY_AM_REWARD_TOP_ACTIVITY_ONGOING},
{
EconomyManager.KEY_AM_REWARD_TOP_ACTIVITY_MAX,
EconomyManager.KEY_AM_REWARD_NOTIFICATION_SEEN_MAX,
EconomyManager.KEY_AM_REWARD_NOTIFICATION_INTERACTION_MAX,
EconomyManager.KEY_AM_REWARD_WIDGET_INTERACTION_MAX,
EconomyManager.KEY_AM_REWARD_OTHER_USER_INTERACTION_MAX,
}
};
}
}

View File

@@ -1,101 +0,0 @@
/*
* Copyright (C) 2021 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.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import com.android.settings.R;
import com.android.settingslib.widget.SettingsSpinnerAdapter;
/**
* Dropdown activity to allow for the user to easily switch between the different TARE
* policies in the developer options of settings. Depending on what is chosen, the fragment
* containing that specific policies' factors will be generated.
*/
public class DropdownActivity extends Activity {
private Fragment mAlarmManagerFragment;
private Fragment mJobSchedulerFragment;
private Spinner mSpinner;
static final String EXTRA_POLICY = "policy";
static final int POLICY_ALARM_MANAGER = 0;
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);
setContentView(R.layout.tare_dropdown_page);
// Determines what policy fragment to open up to
Intent intent = getIntent();
int policy = intent.getIntExtra(EXTRA_POLICY, DEFAULT_POLICY);
mSpinner = findViewById(R.id.spinner);
mAlarmManagerFragment = new AlarmManagerFragment();
mJobSchedulerFragment = new JobSchedulerFragment();
String[] policies = getResources().getStringArray(R.array.tare_policies);
ArrayAdapter<String> arrayAdapter = new SettingsSpinnerAdapter<String>(this);
arrayAdapter.addAll(policies);
mSpinner.setAdapter(arrayAdapter);
mSpinner.setSelection(policy);
selectFragment(policy);
mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position,
long id) {
selectFragment(position);
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
/** Selects the correct policy fragment to display based on user selection */
private void selectFragment(int policy) {
switch (policy) {
case POLICY_ALARM_MANAGER:
openFragment(mAlarmManagerFragment);
break;
case POLICY_JOB_SCHEDULER:
openFragment(mJobSchedulerFragment);
break;
default:
openFragment(mAlarmManagerFragment);
}
}
/** Opens the correct policy fragment */
private void openFragment(Fragment fragment) {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame_layout, fragment);
fragmentTransaction.commit();
}
}

View File

@@ -1,178 +0,0 @@
/*
* Copyright (C) 2021 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.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.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import androidx.annotation.Nullable;
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 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);
mExpandableListAdapter = new TareFactorExpandableListAdapter(
mFactorController, LayoutInflater.from(getActivity()), mGroups, mChildren, mKeys);
elv.setGroupIndicator(null);
elv.setAdapter(mExpandableListAdapter);
elv.setOnChildClickListener(new OnChildClickListener() {
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
final String key = mExpandableListAdapter.getKey(groupPosition, childPosition);
mFactorController.createDialog(key).show(getFragmentManager(), key);
return true;
}
});
return v;
}
@Override
public void onStart() {
super.onStart();
mFactorController.registerListener(this);
}
@Override
public void onStop() {
mFactorController.unregisterListener(this);
super.onStop();
}
@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),
resources.getString(R.string.tare_actions_ctp),
resources.getString(R.string.tare_actions_base_price),
resources.getString(R.string.tare_rewards_instantaneous),
resources.getString(R.string.tare_rewards_ongoing),
resources.getString(R.string.tare_rewards_max)
};
mChildren = new String[][]{
resources.getStringArray(R.array.tare_consumption_limit_subfactors),
resources.getStringArray(R.array.tare_job_scheduler_app_balance_subfactors),
// TODO: support
// mResources.getStringArray(R.array.tare_modifiers_subfactors),
resources.getStringArray(R.array.tare_job_scheduler_actions),
resources.getStringArray(R.array.tare_job_scheduler_actions),
resources.getStringArray(R.array.tare_job_scheduler_rewards_subfactors),
{resources.getString(R.string.tare_top_activity)},
resources.getStringArray(R.array.tare_job_scheduler_rewards_subfactors)
};
mKeys = new String[][]{
{
EconomyManager.KEY_JS_INITIAL_CONSUMPTION_LIMIT,
EconomyManager.KEY_JS_MIN_CONSUMPTION_LIMIT,
EconomyManager.KEY_JS_MAX_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,
EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER,
},
// {},
{
EconomyManager.KEY_JS_ACTION_JOB_MAX_START_CTP,
EconomyManager.KEY_JS_ACTION_JOB_MAX_RUNNING_CTP,
EconomyManager.KEY_JS_ACTION_JOB_HIGH_START_CTP,
EconomyManager.KEY_JS_ACTION_JOB_HIGH_RUNNING_CTP,
EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_START_CTP,
EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_RUNNING_CTP,
EconomyManager.KEY_JS_ACTION_JOB_LOW_START_CTP,
EconomyManager.KEY_JS_ACTION_JOB_LOW_RUNNING_CTP,
EconomyManager.KEY_JS_ACTION_JOB_MIN_START_CTP,
EconomyManager.KEY_JS_ACTION_JOB_MIN_RUNNING_CTP,
EconomyManager.KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP
},
{
EconomyManager.KEY_JS_ACTION_JOB_MAX_START_BASE_PRICE,
EconomyManager.KEY_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE,
EconomyManager.KEY_JS_ACTION_JOB_HIGH_START_BASE_PRICE,
EconomyManager.KEY_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE,
EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE,
EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE,
EconomyManager.KEY_JS_ACTION_JOB_LOW_START_BASE_PRICE,
EconomyManager.KEY_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE,
EconomyManager.KEY_JS_ACTION_JOB_MIN_START_BASE_PRICE,
EconomyManager.KEY_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE,
EconomyManager.KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE
},
{
EconomyManager.KEY_JS_REWARD_TOP_ACTIVITY_INSTANT,
EconomyManager.KEY_JS_REWARD_NOTIFICATION_SEEN_INSTANT,
EconomyManager.KEY_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT,
EconomyManager.KEY_JS_REWARD_WIDGET_INTERACTION_INSTANT,
EconomyManager.KEY_JS_REWARD_OTHER_USER_INTERACTION_INSTANT,
EconomyManager.KEY_JS_REWARD_APP_INSTALL_INSTANT,
},
{EconomyManager.KEY_JS_REWARD_TOP_ACTIVITY_ONGOING},
{
EconomyManager.KEY_JS_REWARD_TOP_ACTIVITY_MAX,
EconomyManager.KEY_JS_REWARD_NOTIFICATION_SEEN_MAX,
EconomyManager.KEY_JS_REWARD_NOTIFICATION_INTERACTION_MAX,
EconomyManager.KEY_JS_REWARD_WIDGET_INTERACTION_MAX,
EconomyManager.KEY_JS_REWARD_OTHER_USER_INTERACTION_MAX,
EconomyManager.KEY_JS_REWARD_APP_INSTALL_MAX,
}
};
}
}

View File

@@ -1,3 +0,0 @@
# Bug component: 330055
include platform/frameworks/base:/apex/jobscheduler/service/java/com/android/server/tare/OWNERS

View File

@@ -1,715 +0,0 @@
/*
* Copyright (C) 2021 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 static android.app.tare.EconomyManager.CAKE_IN_ARC;
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE_CAKES;
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE_CAKES;
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP_CAKES;
import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE_CAKES;
import static android.app.tare.EconomyManager.parseCreditValue;
import static android.provider.Settings.Global.TARE_ALARM_MANAGER_CONSTANTS;
import static android.provider.Settings.Global.TARE_JOB_SCHEDULER_CONSTANTS;
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;
import androidx.annotation.NonNull;
import com.android.settings.R;
/**
* Takes an AlarmManager or JobScheduler csv string and parses it to get key:value pairs.
* This allows us to populate a dialog with the correct information.
*/
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;
private final ContentResolver mContentResolver;
private final KeyValueListParser mParser = new KeyValueListParser(',');
private final Resources mResources;
private final ArrayMap<String, TareFactorData> mAlarmManagerMap = new ArrayMap<>();
private final ArrayMap<String, TareFactorData> mJobSchedulerMap = new ArrayMap<>();
private String mAlarmManagerConstants;
private String mJobSchedulerConstants;
private final ArraySet<DataChangeListener> 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 =
Settings.Global.getString(mContentResolver, TARE_JOB_SCHEDULER_CONSTANTS);
initAlarmManagerMap();
parseAlarmManagerGlobalSettings();
initJobSchedulerMap();
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_balance_exempted),
EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
new TareFactorData(mResources.getString(R.string.tare_min_balance_headless_app),
EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP,
new TareFactorData(mResources.getString(R.string.tare_min_balance_other_app),
EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_MAX_SATIATED_BALANCE,
new TareFactorData(mResources.getString(R.string.tare_max_satiated_balance),
EconomyManager.DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_INITIAL_CONSUMPTION_LIMIT,
new TareFactorData(mResources.getString(R.string.tare_initial_consumption_limit),
EconomyManager.DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_MIN_CONSUMPTION_LIMIT,
new TareFactorData(mResources.getString(R.string.tare_min_consumption_limit),
EconomyManager.DEFAULT_AM_MIN_CONSUMPTION_LIMIT_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_MAX_CONSUMPTION_LIMIT,
new TareFactorData(mResources.getString(R.string.tare_max_consumption_limit),
EconomyManager.DEFAULT_AM_MAX_CONSUMPTION_LIMIT_CAKES,
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_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_TOP_ACTIVITY_ONGOING,
new TareFactorData(mResources.getString(R.string.tare_top_activity),
EconomyManager.DEFAULT_AM_REWARD_TOP_ACTIVITY_ONGOING_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_TOP_ACTIVITY_MAX,
new TareFactorData(mResources.getString(R.string.tare_top_activity),
EconomyManager.DEFAULT_AM_REWARD_TOP_ACTIVITY_MAX_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_NOTIFICATION_SEEN_INSTANT,
new TareFactorData(mResources.getString(R.string.tare_notification_seen),
EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_NOTIFICATION_SEEN_ONGOING,
new TareFactorData(mResources.getString(R.string.tare_notification_seen),
EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_NOTIFICATION_SEEN_MAX,
new TareFactorData(mResources.getString(R.string.tare_notification_seen),
EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_MAX_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_INSTANT,
new TareFactorData(mResources.getString(R.string.tare_notification_seen_15_min),
EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_INSTANT_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_ONGOING,
new TareFactorData(mResources.getString(R.string.tare_notification_seen_15_min),
EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_ONGOING_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_MAX,
new TareFactorData(mResources.getString(R.string.tare_notification_seen_15_min),
EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_MAX_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT,
new TareFactorData(mResources.getString(R.string.tare_notification_interaction),
EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING,
new TareFactorData(mResources.getString(R.string.tare_notification_interaction),
EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_NOTIFICATION_INTERACTION_MAX,
new TareFactorData(mResources.getString(R.string.tare_notification_interaction),
EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_WIDGET_INTERACTION_INSTANT,
new TareFactorData(mResources.getString(R.string.tare_widget_interaction),
EconomyManager.DEFAULT_AM_REWARD_WIDGET_INTERACTION_INSTANT_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_WIDGET_INTERACTION_ONGOING,
new TareFactorData(mResources.getString(R.string.tare_widget_interaction),
EconomyManager.DEFAULT_AM_REWARD_WIDGET_INTERACTION_ONGOING_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_WIDGET_INTERACTION_MAX,
new TareFactorData(mResources.getString(R.string.tare_widget_interaction),
EconomyManager.DEFAULT_AM_REWARD_WIDGET_INTERACTION_MAX_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_OTHER_USER_INTERACTION_INSTANT,
new TareFactorData(mResources.getString(R.string.tare_other_interaction),
EconomyManager.DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_OTHER_USER_INTERACTION_ONGOING,
new TareFactorData(mResources.getString(R.string.tare_other_interaction),
EconomyManager.DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_REWARD_OTHER_USER_INTERACTION_MAX,
new TareFactorData(mResources.getString(R.string.tare_other_interaction),
EconomyManager.DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_MAX_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP,
new TareFactorData(mResources.getString(R.string.tare_wakeup_exact_idle),
EconomyManager
.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP,
new TareFactorData(mResources.getString(R.string.tare_wakeup_inexact_idle),
EconomyManager
.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_ACTION_ALARM_EXACT_WAKEUP_CTP,
new TareFactorData(mResources.getString(R.string.tare_wakeup_exact),
EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_CTP_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP,
new TareFactorData(mResources.getString(R.string.tare_wakeup_inexact),
EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(
EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP,
new TareFactorData(mResources.getString(R.string.tare_nonwakeup_exact_idle),
EconomyManager
.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP,
new TareFactorData(mResources.getString(R.string.tare_nonwakeup_exact),
EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(
EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP,
new TareFactorData(mResources.getString(R.string.tare_nonwakeup_inexact_idle),
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP,
new TareFactorData(mResources.getString(R.string.tare_nonwakeup_inexact),
EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_ACTION_ALARM_ALARMCLOCK_CTP,
new TareFactorData(mResources.getString(R.string.tare_alarm_clock),
EconomyManager.DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_CTP_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(
EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE,
new TareFactorData(mResources.getString(R.string.tare_alarm_clock),
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(
EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE,
new TareFactorData(mResources.getString(R.string.tare_alarm_clock),
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE,
new TareFactorData(mResources.getString(R.string.tare_alarm_clock),
EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE,
new TareFactorData(mResources.getString(R.string.tare_alarm_clock),
EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(
EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_BASE_PRICE,
new TareFactorData(mResources.getString(R.string.tare_alarm_clock),
EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE,
new TareFactorData(mResources.getString(R.string.tare_alarm_clock),
EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(
EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE,
new TareFactorData(mResources.getString(R.string.tare_alarm_clock),
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE,
new TareFactorData(mResources.getString(R.string.tare_alarm_clock),
EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE_CAKES,
POLICY_ALARM_MANAGER));
mAlarmManagerMap.put(EconomyManager.KEY_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE,
new TareFactorData(mResources.getString(R.string.tare_alarm_clock),
EconomyManager.DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE_CAKES,
POLICY_ALARM_MANAGER));
}
/**
* Initialization for JobScheduler Map that sets a JS factor key to a title, default value, and
* policy type in a data object.
*/
private void initJobSchedulerMap() {
mJobSchedulerMap.put(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED,
new TareFactorData(mResources.getString(R.string.tare_min_balance_exempted),
EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
new TareFactorData(mResources.getString(R.string.tare_min_balance_headless_app),
EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP,
new TareFactorData(mResources.getString(R.string.tare_min_balance_other_app),
EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER,
new TareFactorData(
mResources.getString(R.string.tare_min_balance_addition_app_updater),
EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_MAX_SATIATED_BALANCE,
new TareFactorData(mResources.getString(R.string.tare_max_satiated_balance),
EconomyManager.DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_INITIAL_CONSUMPTION_LIMIT,
new TareFactorData(mResources.getString(R.string.tare_initial_consumption_limit),
EconomyManager.DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_MIN_CONSUMPTION_LIMIT,
new TareFactorData(mResources.getString(R.string.tare_min_consumption_limit),
EconomyManager.DEFAULT_JS_MIN_CONSUMPTION_LIMIT_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_MAX_CONSUMPTION_LIMIT,
new TareFactorData(mResources.getString(R.string.tare_max_consumption_limit),
EconomyManager.DEFAULT_JS_MAX_CONSUMPTION_LIMIT_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_APP_INSTALL_INSTANT,
new TareFactorData(mResources.getString(R.string.tare_app_install),
EconomyManager.DEFAULT_JS_REWARD_APP_INSTALL_INSTANT_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_APP_INSTALL_ONGOING,
new TareFactorData(mResources.getString(R.string.tare_app_install),
EconomyManager.DEFAULT_JS_REWARD_APP_INSTALL_ONGOING_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_APP_INSTALL_MAX,
new TareFactorData(mResources.getString(R.string.tare_app_install),
EconomyManager.DEFAULT_JS_REWARD_APP_INSTALL_MAX_CAKES,
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_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_TOP_ACTIVITY_ONGOING,
new TareFactorData(mResources.getString(R.string.tare_top_activity),
EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_ONGOING_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_TOP_ACTIVITY_MAX,
new TareFactorData(mResources.getString(R.string.tare_top_activity),
EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_MAX_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_NOTIFICATION_SEEN_INSTANT,
new TareFactorData(mResources.getString(R.string.tare_notification_seen),
EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_NOTIFICATION_SEEN_ONGOING,
new TareFactorData(mResources.getString(R.string.tare_notification_seen),
EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_NOTIFICATION_SEEN_MAX,
new TareFactorData(mResources.getString(R.string.tare_notification_seen),
EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_MAX_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT,
new TareFactorData(mResources.getString(R.string.tare_notification_interaction),
EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING,
new TareFactorData(mResources.getString(R.string.tare_notification_interaction),
EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_NOTIFICATION_INTERACTION_MAX,
new TareFactorData(mResources.getString(R.string.tare_notification_interaction),
EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_WIDGET_INTERACTION_INSTANT,
new TareFactorData(mResources.getString(R.string.tare_widget_interaction),
EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_INSTANT_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_WIDGET_INTERACTION_ONGOING,
new TareFactorData(mResources.getString(R.string.tare_widget_interaction),
EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_ONGOING_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_WIDGET_INTERACTION_MAX,
new TareFactorData(mResources.getString(R.string.tare_widget_interaction),
EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_MAX_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_OTHER_USER_INTERACTION_INSTANT,
new TareFactorData(mResources.getString(R.string.tare_other_interaction),
EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_OTHER_USER_INTERACTION_ONGOING,
new TareFactorData(mResources.getString(R.string.tare_other_interaction),
EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_REWARD_OTHER_USER_INTERACTION_MAX,
new TareFactorData(mResources.getString(R.string.tare_other_interaction),
EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_MAX_START_CTP,
new TareFactorData(mResources.getString(R.string.tare_job_max_start),
EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_START_CTP_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_MAX_RUNNING_CTP,
new TareFactorData(mResources.getString(R.string.tare_job_max_running),
EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_RUNNING_CTP_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_HIGH_START_CTP,
new TareFactorData(mResources.getString(R.string.tare_job_high_start),
EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_START_CTP_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_HIGH_RUNNING_CTP,
new TareFactorData(mResources.getString(R.string.tare_job_high_running),
EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_CTP_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_START_CTP,
new TareFactorData(mResources.getString(R.string.tare_job_default_start),
EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_START_CTP_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_RUNNING_CTP,
new TareFactorData(mResources.getString(R.string.tare_job_default_running),
EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_CTP_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_LOW_START_CTP,
new TareFactorData(mResources.getString(R.string.tare_job_low_start),
EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_START_CTP_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(
EconomyManager.KEY_JS_ACTION_JOB_LOW_RUNNING_CTP,
new TareFactorData(mResources.getString(R.string.tare_job_low_running),
EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_RUNNING_CTP_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_MIN_START_CTP,
new TareFactorData(mResources.getString(R.string.tare_job_min_start),
EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_START_CTP_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(
EconomyManager.KEY_JS_ACTION_JOB_MIN_RUNNING_CTP,
new TareFactorData(mResources.getString(R.string.tare_job_min_running),
EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_RUNNING_CTP_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP,
new TareFactorData(mResources.getString(R.string.tare_job_timeout_penalty),
EconomyManager.DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_MAX_START_BASE_PRICE,
new TareFactorData(mResources.getString(R.string.tare_job_max_start),
EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_START_BASE_PRICE_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(
EconomyManager.KEY_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE,
new TareFactorData(mResources.getString(R.string.tare_job_max_running),
EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(
EconomyManager.KEY_JS_ACTION_JOB_HIGH_START_BASE_PRICE,
new TareFactorData(mResources.getString(R.string.tare_job_high_start),
EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_START_BASE_PRICE_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE,
new TareFactorData(mResources.getString(R.string.tare_job_high_running),
EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE,
new TareFactorData(mResources.getString(R.string.tare_job_default_start),
EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(
EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE,
new TareFactorData(mResources.getString(R.string.tare_job_default_running),
EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_LOW_START_BASE_PRICE,
new TareFactorData(mResources.getString(R.string.tare_job_low_start),
EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_START_BASE_PRICE_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(
EconomyManager.KEY_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE,
new TareFactorData(mResources.getString(R.string.tare_job_low_running),
EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_MIN_START_BASE_PRICE,
new TareFactorData(mResources.getString(R.string.tare_job_min_start),
EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_START_BASE_PRICE_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE,
new TareFactorData(mResources.getString(R.string.tare_job_min_running),
EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE_CAKES,
POLICY_JOB_SCHEDULER));
mJobSchedulerMap.put(EconomyManager.KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE,
new TareFactorData(mResources.getString(R.string.tare_job_timeout_penalty),
EconomyManager.DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE_CAKES,
POLICY_JOB_SCHEDULER));
}
/**
* Parses the AM constant from Settings.Global to get to the current value.
*/
private void parseAlarmManagerGlobalSettings() {
parseSettingsIntoMap(mAlarmManagerConstants, mAlarmManagerMap);
}
/**
* Parses the JS constant from Settings.Global to get to the current value.
*/
private void parseJobSchedulerGlobalSettings() {
parseSettingsIntoMap(mJobSchedulerConstants, mJobSchedulerMap);
}
private void parseSettingsIntoMap(String constants, ArrayMap<String, TareFactorData> map) {
try {
mParser.setString(constants);
} catch (Exception e) {
Slog.e(TAG, "Bad string constants value", e);
}
for (int i = map.size() - 1; i >= 0; --i) {
final String key = map.keyAt(i);
final TareFactorData data = map.valueAt(i);
data.currentValue = parseCreditValue(mParser.getString(key, null), data.defaultValue);
}
}
@NonNull
private ArrayMap<String, TareFactorData> getMap(int factorPolicy) {
switch (factorPolicy) {
case POLICY_ALARM_MANAGER:
return mAlarmManagerMap;
case POLICY_JOB_SCHEDULER:
return mJobSchedulerMap;
default:
throw new IllegalArgumentException("Invalid factor policy given");
}
}
/**
* Takes a key and factor policy as input and grabs the title linked to it.
*
* @param key the key of the factor you want to get the title of
* @param factorPolicy the policy you want the title of
*/
private String getTitle(String key, int factorPolicy) {
final ArrayMap<String, TareFactorData> currentMap = getMap(factorPolicy);
return currentMap.get(key).title;
}
/**
* Takes a key and factor policy as input and grabs the current value linked to it.
*
* @param key the key of the factor you want to get the default value of
* @param factorPolicy the policy you want the current value of
*/
private long getCurrentValue(String key, int factorPolicy) {
final ArrayMap<String, TareFactorData> currentMap = getMap(factorPolicy);
return currentMap.get(key).currentValue;
}
/**
* Takes a key as input and grabs the factor type linked to it.
*
* @param key the key of the factor you want to get the factor type of
*/
private int getFactorType(String key) {
ArrayMap<String, TareFactorData> currentMap;
if (mAlarmManagerMap.containsKey(key)) {
currentMap = mAlarmManagerMap;
} else if (mJobSchedulerMap.containsKey(key)) {
currentMap = mJobSchedulerMap;
} else {
throw new IllegalArgumentException("Couldn't link key '" + key + "' to a policy");
}
return currentMap.get(key).factorPolicy;
}
long 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.
*
* @param key the key of the factor you want to get the default value of
* @param editedValue the value entered by the user in the dialog
* @param factorPolicy policy being updated
*/
public void updateValue(String key, long editedValue, int factorPolicy) {
final ArrayMap<String, TareFactorData> map = getMap(factorPolicy);
final TareFactorData data = map.get(key);
if (data.currentValue == editedValue) {
return;
}
data.currentValue = editedValue;
rebuildPolicyConstants(factorPolicy);
}
/**
* Iterates through the factor policy map for keys and current values to
* rebuild a current string that is then assigned to be the new global settings string.
*
* @param factorPolicy policy being updated
*/
private void rebuildPolicyConstants(int factorPolicy) {
switch (factorPolicy) {
case POLICY_ALARM_MANAGER:
writeConstantsToSettings(mAlarmManagerMap, TARE_ALARM_MANAGER_CONSTANTS);
break;
case POLICY_JOB_SCHEDULER:
writeConstantsToSettings(mJobSchedulerMap, TARE_JOB_SCHEDULER_CONSTANTS);
break;
}
}
private void writeConstantsToSettings(ArrayMap<String, TareFactorData> factorMap,
String settingsKey) {
final StringBuilder constantsStringBuilder = new StringBuilder();
for (int i = 0, size = factorMap.size(); i < size; ++i) {
final TareFactorData factor = factorMap.valueAt(i);
if (factor.currentValue == factor.defaultValue) {
continue;
}
if (constantsStringBuilder.length() > 0) {
constantsStringBuilder.append(",");
}
constantsStringBuilder
.append(factorMap.keyAt(i))
.append("=");
if (factor.currentValue % CAKE_IN_ARC == 0) {
constantsStringBuilder
.append(factor.currentValue / CAKE_IN_ARC)
.append("A");
} else {
constantsStringBuilder
.append(factor.currentValue)
.append("ck");
}
}
Settings.Global.putString(mContentResolver, settingsKey, constantsStringBuilder.toString());
}
/**
* Creates a dialog with the values linked to the key.
*
* @param key the key of the factor you want to get the default value of
*/
public TareFactorDialogFragment createDialog(String key) {
int policy = getFactorType(key);
return new TareFactorDialogFragment(getTitle(key, policy), key,
getCurrentValue(key, policy), policy, this);
}
/**
* Data object that holds a title,default value,and current value for a key.
*/
private static class TareFactorData {
public final String title;
public final long defaultValue;
public final int factorPolicy;
public long currentValue;
TareFactorData(String title, long defaultValue, int factorPolicy) {
this.title = title;
this.defaultValue = defaultValue;
this.factorPolicy = factorPolicy;
this.currentValue = defaultValue;
}
}
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();
}
}
}
}

View File

@@ -1,164 +0,0 @@
/*
* Copyright (C) 2021 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 static android.app.tare.EconomyManager.CAKE_IN_ARC;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.os.Bundle;
import android.text.InputType;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import androidx.annotation.NonNull;
import com.android.settings.R;
import com.android.settings.Utils;
/**
* Dialog Fragment for changing tare factor values
*/
public class TareFactorDialogFragment extends DialogFragment {
private static final String TAG = "TareDialogFragment";
// This follows the order in strings.xml:tare_units array.
private static final int UNIT_IDX_ARC = 0;
private static final int UNIT_IDX_CAKE = 1;
private final String mFactorKey;
private final String mFactorTitle;
private final long mFactorValue;
private final int mFactorPolicy;
private final TareFactorController mTareFactorController;
private EditText mFactorValueView;
private Spinner mUnitSpinner;
/**
* @param title the title that will show at the top of the Dialog for the Factor
* @param key the key of the Factor being initialized.
* @param currentValue the current value set for the Factor
*/
public TareFactorDialogFragment(@NonNull String title, @NonNull String key, long currentValue,
int factorPolicy, TareFactorController tareFactorController) {
mFactorTitle = title;
mFactorKey = key;
mFactorValue = currentValue;
mFactorPolicy = factorPolicy;
mTareFactorController = tareFactorController;
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(
getActivity())
.setTitle(mFactorTitle)
.setView(createDialogView())
.setPositiveButton(R.string.tare_dialog_confirm_button_title, (dialog, which) -> {
final String stringValue = mFactorValueView.getText().toString();
long newVal = mFactorValue;
try {
newVal = Long.parseLong(stringValue);
if (mUnitSpinner.getSelectedItemPosition() == UNIT_IDX_ARC) {
// Convert ARC to cake
newVal *= CAKE_IN_ARC;
}
} catch (NumberFormatException e) {
Log.e(TAG, "Error parsing '" + stringValue + "'. Using "
+ mFactorValue + " instead", e);
}
mTareFactorController.updateValue(mFactorKey, newVal, mFactorPolicy);
})
.setNegativeButton(android.R.string.cancel, (dialog, which) -> {
// When the negative button is clicked do nothing
});
return builder.create();
}
/**
* Creates a view for the factor Dialog that currently
* is linked to the basic dialog_edittext.xml layout.
*/
private View createDialogView() {
final LayoutInflater layoutInflater = (LayoutInflater) getActivity()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = layoutInflater.inflate(R.layout.dialog_edittext_dropdown, null);
mFactorValueView = layout.findViewById(R.id.edittext);
mFactorValueView.setInputType(InputType.TYPE_CLASS_NUMBER);
mUnitSpinner = layout.findViewById(R.id.spinner);
final String[] units = getResources().getStringArray(R.array.tare_units);
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(
getActivity(), android.R.layout.simple_spinner_item, units);
mUnitSpinner.setAdapter(spinnerArrayAdapter);
final int unitIdx;
if (mFactorValue % CAKE_IN_ARC == 0) {
mFactorValueView.setText(String.format("%d", mFactorValue / CAKE_IN_ARC));
unitIdx = UNIT_IDX_ARC;
} else {
mFactorValueView.setText(String.format("%d", mFactorValue));
unitIdx = UNIT_IDX_CAKE;
}
mUnitSpinner.setSelection(unitIdx);
mUnitSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
private int mSelectedPosition = unitIdx;
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (mSelectedPosition == position) {
return;
}
mSelectedPosition = position;
final String stringValue = mFactorValueView.getText().toString();
try {
long newVal = Long.parseLong(stringValue);
if (mUnitSpinner.getSelectedItemPosition() == UNIT_IDX_ARC) {
// Convert cake to ARC
newVal /= CAKE_IN_ARC;
} else {
// Convert ARC to cake
newVal *= CAKE_IN_ARC;
}
mFactorValueView.setText(String.format("%d", newVal));
} catch (NumberFormatException e) {
Log.e(TAG, "Error parsing '" + stringValue + "'", e);
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
Utils.setEditTextCursorPosition(mFactorValueView);
return layout;
}
}

View File

@@ -1,166 +0,0 @@
/*
* 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 static android.app.tare.EconomyManager.CAKE_IN_ARC;
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 androidx.annotation.NonNull;
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(cakeToString(
mFactorController.getValue(getKey(groupPosition, childPosition))));
return convertView;
}
@NonNull
private static String cakeToString(long cakes) {
// Resources.getQuantityString doesn't handle floating point numbers, so doing this manually
if (cakes == 0) {
return "0";
}
final long sub = cakes % CAKE_IN_ARC;
final long arcs = (int) (cakes / CAKE_IN_ARC);
if (arcs == 0) {
return sub + " c";
}
StringBuilder sb = new StringBuilder();
sb.append(arcs);
if (sub > 0) {
sb.append(".").append(String.format("%03d", sub / (CAKE_IN_ARC / 1000)));
}
sb.append(" A");
return sb.toString();
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}

View File

@@ -1,189 +0,0 @@
/*
* Copyright (C) 2021 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 static com.android.settings.development.tare.DropdownActivity.EXTRA_POLICY;
import static com.android.settings.development.tare.DropdownActivity.POLICY_ALARM_MANAGER;
import static com.android.settings.development.tare.DropdownActivity.POLICY_JOB_SCHEDULER;
import android.app.Activity;
import android.app.tare.EconomyManager;
import android.content.Intent;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.TextView;
import android.widget.Toast;
import com.android.settings.R;
/** Class for creating the TARE homepage in settings */
public class TareHomePage extends Activity {
private static final String TAG = "TareHomePage";
private CompoundButton mOnSwitch;
private Button mRevButton;
private TextView mAlarmManagerView;
private TextView mJobSchedulerView;
private ConfigObserver mConfigObserver;
private static final int SETTING_VALUE_DEFAULT = -1;
private static final int SETTING_VALUE_OFF = 0;
private static final int SETTING_VALUE_ON = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tare_homepage);
mOnSwitch = findViewById(R.id.on_switch);
mRevButton = findViewById(R.id.revert_button);
mAlarmManagerView = findViewById(R.id.alarmmanager);
mJobSchedulerView = findViewById(R.id.jobscheduler);
mConfigObserver = new ConfigObserver(new Handler(Looper.getMainLooper()));
mOnSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (mConfigObserver.mEnableTareSetting == SETTING_VALUE_DEFAULT
&& isChecked == mConfigObserver.getDefaultEnabledStatus()) {
// Don't bother writing something that's not new information. It would make
// it hard to use DeviceConfig if we did.
return;
}
Settings.Global.putInt(getContentResolver(),
Settings.Global.ENABLE_TARE,
isChecked ? SETTING_VALUE_ON : SETTING_VALUE_OFF);
}
});
}
@Override
protected void onResume() {
super.onResume();
mConfigObserver.start();
}
@Override
protected void onPause() {
mConfigObserver.stop();
super.onPause();
}
/** Reverts the TARE settings to the original default settings */
public void revertSettings(View v) {
Toast.makeText(this, R.string.tare_settings_reverted_toast, Toast.LENGTH_LONG).show();
final boolean wasSettingsDefault =
mConfigObserver.mEnableTareSetting == SETTING_VALUE_DEFAULT;
Settings.Global.putString(getApplicationContext().getContentResolver(),
Settings.Global.ENABLE_TARE, null);
Settings.Global.putString(getApplicationContext().getContentResolver(),
Settings.Global.TARE_ALARM_MANAGER_CONSTANTS, null);
Settings.Global.putString(getApplicationContext().getContentResolver(),
Settings.Global.TARE_JOB_SCHEDULER_CONSTANTS, null);
if (wasSettingsDefault) {
// Only do this manually here to force a DeviceConfig check if the settings value isn't
// actually changing.
setEnabled(mConfigObserver.getDefaultEnabledStatus());
}
}
/** Opens up the AlarmManager TARE policy page with its factors to view and edit */
public void launchAlarmManagerPage(View v) {
Intent i = new Intent(getApplicationContext(), DropdownActivity.class);
i.putExtra(EXTRA_POLICY, POLICY_ALARM_MANAGER);
startActivity(i);
}
/** Opens up the JobScheduler TARE policy page with its factors to view and edit */
public void launchJobSchedulerPage(View v) {
Intent i = new Intent(getApplicationContext(), DropdownActivity.class);
i.putExtra(EXTRA_POLICY, POLICY_JOB_SCHEDULER);
startActivity(i);
}
/** Changes the enabled state of the TARE homepage buttons based on global toggle */
private void setEnabled(boolean tareStatus) {
mAlarmManagerView.setEnabled(tareStatus);
mJobSchedulerView.setEnabled(tareStatus);
mOnSwitch.setChecked(tareStatus);
}
private class ConfigObserver extends ContentObserver {
private int mEnableTareSetting;
ConfigObserver(Handler handler) {
super(handler);
}
public void start() {
getContentResolver().registerContentObserver(
Settings.Global.getUriFor(Settings.Global.ENABLE_TARE), false, this);
processEnableTareChange();
}
public void stop() {
getContentResolver().unregisterContentObserver(this);
}
@Override
public void onChange(boolean selfChange, Uri uri) {
processEnableTareChange();
}
private void processEnableTareChange() {
final String setting =
Settings.Global.getString(getContentResolver(), Settings.Global.ENABLE_TARE);
if (setting == null) {
mEnableTareSetting = SETTING_VALUE_DEFAULT;
} else {
try {
mEnableTareSetting = Integer.parseInt(setting);
} catch (NumberFormatException e) {
Log.e(TAG, "Invalid setting value", e);
mEnableTareSetting = EconomyManager.DEFAULT_ENABLE_TARE_MODE;
}
}
final boolean enabled;
if (mEnableTareSetting == SETTING_VALUE_ON) {
enabled = true;
} else if (mEnableTareSetting == SETTING_VALUE_OFF) {
enabled = false;
} else {
enabled = getDefaultEnabledStatus();
}
setEnabled(enabled);
}
private boolean getDefaultEnabledStatus() {
// Show Shadow Mode as "off" in the UI since it won't be affecting device behavior.
return DeviceConfig.getInt(DeviceConfig.NAMESPACE_TARE,
EconomyManager.KEY_ENABLE_TARE_MODE,
EconomyManager.DEFAULT_ENABLE_TARE_MODE) == EconomyManager.ENABLED_MODE_ON;
}
}
}