1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.car.settings.datausage;
18 
19 import static android.net.NetworkPolicy.LIMIT_DISABLED;
20 import static android.net.NetworkPolicy.WARNING_DISABLED;
21 
22 import android.car.drivingstate.CarUxRestrictions;
23 import android.content.Context;
24 import android.os.Bundle;
25 
26 import androidx.annotation.Nullable;
27 import androidx.annotation.VisibleForTesting;
28 import androidx.preference.Preference;
29 import androidx.preference.PreferenceGroup;
30 import androidx.preference.TwoStatePreference;
31 
32 import com.android.car.settings.R;
33 import com.android.car.settings.common.ConfirmationDialogFragment;
34 import com.android.car.settings.common.FragmentController;
35 
36 /** Controls setting the data limit threshold. */
37 public class DataLimitPreferenceController extends
38         DataWarningAndLimitBasePreferenceController<PreferenceGroup> implements
39         Preference.OnPreferenceChangeListener, ConfirmationDialogFragment.ConfirmListener,
40         Preference.OnPreferenceClickListener {
41 
42     @VisibleForTesting
43     static final float LIMIT_BYTES_MULTIPLIER = 1.2f;
44     private static final long GIB_IN_BYTES = 1024 * 1024 * 1024;
45 
46     private TwoStatePreference mEnableDataLimitPreference;
47     private Preference mSetDataLimitPreference;
48 
DataLimitPreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions)49     public DataLimitPreferenceController(Context context, String preferenceKey,
50             FragmentController fragmentController, CarUxRestrictions uxRestrictions) {
51         super(context, preferenceKey, fragmentController, uxRestrictions);
52     }
53 
54     @Override
getPreferenceType()55     protected Class<PreferenceGroup> getPreferenceType() {
56         return PreferenceGroup.class;
57     }
58 
59     @Override
onCreateInternal()60     protected void onCreateInternal() {
61         mEnableDataLimitPreference = (TwoStatePreference) getPreference().findPreference(
62                 getContext().getString(R.string.pk_data_set_limit));
63         mEnableDataLimitPreference.setOnPreferenceChangeListener(this);
64         mSetDataLimitPreference = getPreference().findPreference(
65                 getContext().getString(R.string.pk_data_limit));
66         mSetDataLimitPreference.setOnPreferenceClickListener(this);
67 
68         ConfirmationDialogFragment.resetListeners(
69                 (ConfirmationDialogFragment) getFragmentController().findDialogByTag(
70                         ConfirmationDialogFragment.TAG),
71                 /* confirmListener= */ this,
72                 /* rejectListener= */ null,
73                 /* neutralListener= */ null);
74     }
75 
76     @Override
onStartInternal()77     public void onStartInternal() {
78         super.onStartInternal();
79         getNetworkPolicyEditor().read();
80     }
81 
82     @Override
updateState(PreferenceGroup preference)83     protected void updateState(PreferenceGroup preference) {
84         long limitBytes = getNetworkPolicyEditor().getPolicyLimitBytes(getNetworkTemplate());
85 
86         if (limitBytes == LIMIT_DISABLED) {
87             mEnableDataLimitPreference.setChecked(false);
88             mSetDataLimitPreference.setSummary(null);
89         } else {
90             mEnableDataLimitPreference.setChecked(true);
91             mSetDataLimitPreference.setSummary(
92                     DataUsageUtils.bytesToIecUnits(getContext(), limitBytes));
93         }
94         mSetDataLimitPreference.setEnabled(mEnableDataLimitPreference.isChecked());
95     }
96 
97     @Override
onPreferenceChange(Preference preference, Object newValue)98     public boolean onPreferenceChange(Preference preference, Object newValue) {
99         boolean enabled = (Boolean) newValue;
100         if (!enabled) {
101             getNetworkPolicyEditor().setPolicyLimitBytes(getNetworkTemplate(), LIMIT_DISABLED);
102             refreshUi();
103             return true;
104         }
105 
106         ConfirmationDialogFragment dialogFragment =
107                 new ConfirmationDialogFragment.Builder(getContext())
108                         .setTitle(R.string.data_usage_limit_dialog_title)
109                         .setMessage(R.string.data_usage_limit_dialog_mobile)
110                         .setPositiveButton(android.R.string.ok, this)
111                         .setNegativeButton(android.R.string.cancel, null)
112                         .build();
113         getFragmentController().showDialog(dialogFragment, ConfirmationDialogFragment.TAG);
114 
115         // This preference is enabled / disabled by ConfirmationDialogFragment.
116         return false;
117     }
118 
119     @Override
onConfirm(@ullable Bundle arguments)120     public void onConfirm(@Nullable Bundle arguments) {
121         long warningBytes = getNetworkPolicyEditor().getPolicyWarningBytes(getNetworkTemplate());
122         long minLimitBytes = 0;
123         if (warningBytes != WARNING_DISABLED) {
124             minLimitBytes = (long) (warningBytes * LIMIT_BYTES_MULTIPLIER);
125         }
126 
127         long limitBytes = Math.max(5 * GIB_IN_BYTES, minLimitBytes);
128 
129         getNetworkPolicyEditor().setPolicyLimitBytes(getNetworkTemplate(), limitBytes);
130         refreshUi();
131     }
132 
133     @Override
onPreferenceClick(Preference preference)134     public boolean onPreferenceClick(Preference preference) {
135         getFragmentController().launchFragment(DataLimitSetThresholdFragment
136                 .newInstance(getNetworkTemplate()));
137         return true;
138     }
139 }
140