1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.car.settings.datausage; 18 19 import android.content.Context; 20 import android.net.NetworkPolicyManager; 21 import android.net.NetworkTemplate; 22 import android.os.Bundle; 23 import android.telephony.SubscriptionManager; 24 import android.telephony.TelephonyManager; 25 26 import androidx.annotation.StringRes; 27 import androidx.annotation.VisibleForTesting; 28 import androidx.annotation.XmlRes; 29 30 import com.android.car.settings.R; 31 import com.android.car.settings.common.SettingsFragment; 32 import com.android.car.ui.toolbar.MenuItem; 33 import com.android.settingslib.NetworkPolicyEditor; 34 35 import java.util.Collections; 36 import java.util.List; 37 38 /** Screen used to pick the data usage warning threshold bytes. */ 39 public abstract class DataUsageSetThresholdBaseFragment extends SettingsFragment { 40 41 @VisibleForTesting 42 static final long MIB_IN_BYTES = 1024 * 1024; 43 @VisibleForTesting 44 static final long GIB_IN_BYTES = MIB_IN_BYTES * 1024; 45 @VisibleForTesting 46 static final long MAX_DATA_LIMIT_BYTES = 50000 * GIB_IN_BYTES; 47 @VisibleForTesting 48 static final float MB_GB_SUFFIX_THRESHOLD = 1.5f; 49 50 @VisibleForTesting 51 DataUsageUnitPreferenceController mDataWarningUnitsPreferenceController; 52 @VisibleForTesting 53 DataUsageEditTextPreferenceController mDataUsageEditTextPreferenceController; 54 @VisibleForTesting 55 NetworkPolicyEditor mPolicyEditor; 56 @VisibleForTesting 57 NetworkTemplate mNetworkTemplate; 58 59 private MenuItem mSaveButton; 60 private TelephonyManager mTelephonyManager; 61 private SubscriptionManager mSubscriptionManager; 62 63 @Override 64 @XmlRes getPreferenceScreenResId()65 protected int getPreferenceScreenResId() { 66 return R.xml.data_usage_set_threshold_fragment; 67 } 68 69 @Override getToolbarMenuItems()70 protected List<MenuItem> getToolbarMenuItems() { 71 return Collections.singletonList(mSaveButton); 72 } 73 74 @Override onAttach(Context context)75 public void onAttach(Context context) { 76 super.onAttach(context); 77 78 if (mPolicyEditor == null) { 79 mPolicyEditor = new NetworkPolicyEditor(NetworkPolicyManager.from(context)); 80 81 // Loads the current policies to the policy editor cache. 82 mPolicyEditor.read(); 83 } 84 mNetworkTemplate = getArguments().getParcelable( 85 NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE); 86 if (mNetworkTemplate == null) { 87 mTelephonyManager = context.getSystemService(TelephonyManager.class); 88 mSubscriptionManager = context.getSystemService(SubscriptionManager.class); 89 mNetworkTemplate = DataUsageUtils.getMobileNetworkTemplate(mTelephonyManager, 90 DataUsageUtils.getDefaultSubscriptionId(mSubscriptionManager)); 91 } 92 93 mSaveButton = new MenuItem.Builder(context) 94 .setTitle(R.string.data_usage_warning_save_title) 95 .setOnClickListener(i -> { 96 onSaveClicked(); 97 }) 98 .build(); 99 100 mDataUsageEditTextPreferenceController = use( 101 DataUsageEditTextPreferenceController.class, 102 R.string.pk_data_usage_edit_text); 103 mDataWarningUnitsPreferenceController = use(DataUsageUnitPreferenceController.class, 104 R.string.pk_data_usage_radio_group); 105 106 long currentWarningBytes = getInitialBytes(); 107 String bytesText; 108 if (currentWarningBytes > MB_GB_SUFFIX_THRESHOLD * GIB_IN_BYTES) { 109 mDataWarningUnitsPreferenceController.setDefaultSelection(/* isGb= */ true); 110 bytesText = formatText(currentWarningBytes / (float) GIB_IN_BYTES); 111 } else { 112 mDataWarningUnitsPreferenceController.setDefaultSelection(/* isGb= */ false); 113 bytesText = formatText(currentWarningBytes / (float) MIB_IN_BYTES); 114 } 115 116 mDataUsageEditTextPreferenceController.setDefaultText(bytesText); 117 } 118 119 @Override onCreate(Bundle savedInstanceState)120 public void onCreate(Bundle savedInstanceState) { 121 super.onCreate(savedInstanceState); 122 123 getPreferenceScreen().setTitle(getTitleResId()); 124 } 125 126 @VisibleForTesting onSaveClicked()127 void onSaveClicked() { 128 onSave(getCurrentThreshold()); 129 goBack(); 130 } 131 132 @VisibleForTesting getCurrentThreshold()133 long getCurrentThreshold() { 134 String bytesString = mDataUsageEditTextPreferenceController.getText(); 135 if (bytesString.isEmpty() || bytesString.equals(".")) { 136 bytesString = "0"; 137 } 138 139 long bytes = (long) (Float.parseFloat(bytesString) 140 * (mDataWarningUnitsPreferenceController.isGbSelected() 141 ? GIB_IN_BYTES : MIB_IN_BYTES)); 142 143 // To fix the overflow problem. 144 return Math.min(MAX_DATA_LIMIT_BYTES, bytes); 145 } 146 formatText(float v)147 private String formatText(float v) { 148 v = Math.round(v * 100) / 100f; 149 return String.valueOf(v); 150 } 151 152 /** 153 * Callback when save button is clicked 154 * 155 * @param threshold number of bytes set 156 */ 157 @VisibleForTesting onSave(long threshold)158 abstract void onSave(long threshold); 159 160 /** Returns the screen title res id */ 161 @StringRes getTitleResId()162 protected abstract int getTitleResId(); 163 164 /** Returns the initial bytes to be displayed */ getInitialBytes()165 protected abstract long getInitialBytes(); 166 } 167