• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.car.settings.datausage;
17 
18 import android.car.drivingstate.CarUxRestrictions;
19 import android.content.Context;
20 import android.text.format.DateUtils;
21 
22 import androidx.annotation.CallSuper;
23 import androidx.preference.ListPreference;
24 
25 import com.android.car.settings.common.FragmentController;
26 import com.android.car.settings.common.PreferenceController;
27 import com.android.settingslib.net.DataUsageController;
28 import com.android.settingslib.net.NetworkCycleData;
29 
30 import java.util.ArrayList;
31 import java.util.HashMap;
32 import java.util.List;
33 import java.util.Map;
34 
35 /**
36  * Base preference controller for loading data cycle information
37  *
38  * @param <T> type of the {@link NetworkCycleData} objects that will be loaded.
39  */
40 public abstract class DataUsageCycleBasePreferenceController<T extends NetworkCycleData> extends
41         PreferenceController<ListPreference> {
42     private List<T> mList;
43     private boolean mIsLoaded = false;
44     private DataCyclePickedListener<T> mDataCyclePickedListener;
45     private Map<CharSequence, T> mDataUsages = new HashMap<>();
46     private DataUsageController.DataUsageInfo mDataUsageInfo;
47 
48     /** A listener that is called when a data cycle is selected.
49      *
50      * @param <T> type of the {@link NetworkCycleData} objects that was loaded.
51      */
52     public interface DataCyclePickedListener<T> {
53         /** Callback when a new data cycle is selected */
onDataCyclePicked(String cycle, Map<CharSequence, T> usages)54         void onDataCyclePicked(String cycle, Map<CharSequence, T> usages);
55     }
56 
DataUsageCycleBasePreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions)57     public DataUsageCycleBasePreferenceController(Context context, String preferenceKey,
58             FragmentController fragmentController, CarUxRestrictions uxRestrictions) {
59         super(context, preferenceKey, fragmentController, uxRestrictions);
60     }
61 
62     @Override
getPreferenceType()63     protected Class<ListPreference> getPreferenceType() {
64         return ListPreference.class;
65     }
66 
67     @Override
68     @CallSuper
updateState(ListPreference preference)69     protected void updateState(ListPreference preference) {
70         CharSequence entry = getPreference().getEntry();
71         if (entry != null) {
72             preference.setEnabled(true);
73             getPreference().setSummary(entry);
74         } else {
75             preference.setEnabled(false);
76             getPreference().setSummary(mDataUsageInfo.period);
77         }
78         String cycle = getPreference().getValue();
79         if (mIsLoaded) {
80             mDataCyclePickedListener.onDataCyclePicked(cycle, mDataUsages);
81         }
82     }
83 
84     @Override
85     @CallSuper
checkInitialized()86     protected void checkInitialized() {
87         if (mDataCyclePickedListener == null || mDataUsageInfo == null) {
88             throw new IllegalStateException("DataCyclePickedListener and DataUsageInfo should be "
89                     + "set before calling this function.");
90         }
91     }
92 
93     /** Set DataCyclePickedListener */
setDataCyclePickedListener( DataCyclePickedListener<T> listener)94     public DataUsageCycleBasePreferenceController<T> setDataCyclePickedListener(
95             DataCyclePickedListener<T> listener) {
96         mDataCyclePickedListener = listener;
97         return this;
98     }
99 
100     /** Set DataUsageInfo */
setDataUsageInfo(DataUsageController.DataUsageInfo dataUsageInfo)101     public void setDataUsageInfo(DataUsageController.DataUsageInfo dataUsageInfo) {
102         mDataUsageInfo = dataUsageInfo;
103     }
104 
105     /** Called to parse loaded data */
onLoaded(List<T> data)106     protected void onLoaded(List<T> data) {
107         mList = data;
108         // TODO: (b/202973988) The data loaded is empty occasionally. In that case, we will not
109         //  refresh the UI or mark it as loaded.
110         if (mList != null && !mList.isEmpty()) {
111             updateCycle(getPreference());
112             mIsLoaded = true;
113             refreshUi();
114         }
115     }
116 
updateCycle(ListPreference preference)117     private void updateCycle(ListPreference preference) {
118         if (mIsLoaded) {
119             return;
120         }
121         ArrayList<CharSequence> entries = new ArrayList<>();
122         ArrayList<CharSequence> entryValues = new ArrayList<>();
123         for (int i = 0; i < mList.size(); i++) {
124             T networkCycleData = mList.get(i);
125             CharSequence entry = formatDate(
126                     networkCycleData.getStartTime(), networkCycleData.getEndTime());
127             CharSequence entryValue = String.valueOf(i);
128             entries.add(entry);
129             entryValues.add(entryValue);
130             mDataUsages.put(entryValue, networkCycleData);
131         }
132         preference.setEntries(entries.toArray(new CharSequence[entries.size()]));
133         preference.setEntryValues(entryValues.toArray(new CharSequence[entries.size()]));
134         preference.setSummary(entries.get(0));
135         preference.setValueIndex(0);
136     }
137 
formatDate(long startTime, long endTime)138     private String formatDate(long startTime, long endTime) {
139         return DateUtils.formatDateRange(getContext(), startTime, endTime,
140                 DateUtils.FORMAT_ABBREV_MONTH | DateUtils.FORMAT_SHOW_DATE);
141     }
142 }
143