1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the
10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11  * KIND, either express or implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */
14 package com.android.settings.datausage;
15 
16 import android.content.Context;
17 import android.util.Range;
18 
19 import com.android.settings.Utils;
20 import com.android.settingslib.widget.SettingsSpinnerAdapter;
21 
22 import java.util.List;
23 
24 public class CycleAdapter extends SettingsSpinnerAdapter<CycleAdapter.CycleItem> {
25 
26     private final SpinnerInterface mSpinner;
27 
CycleAdapter(Context context, SpinnerInterface spinner)28     public CycleAdapter(Context context, SpinnerInterface spinner) {
29         super(context);
30         mSpinner = spinner;
31         mSpinner.setAdapter(this);
32     }
33 
34     /**
35      * Find position of {@link CycleItem} in this adapter which is nearest
36      * the given {@link CycleItem}.
37      */
findNearestPosition(CycleItem target)38     public int findNearestPosition(CycleItem target) {
39         if (target != null) {
40             final int count = getCount();
41             for (int i = count - 1; i >= 0; i--) {
42                 final CycleItem item = getItem(i);
43                 if (item.compareTo(target) >= 0) {
44                     return i;
45                 }
46             }
47         }
48         return 0;
49     }
50 
setInitialCycleList(List<Long> cycles, long selectedCycle)51     void setInitialCycleList(List<Long> cycles, long selectedCycle) {
52         clear();
53         for (int i = 0; i < cycles.size() - 1; i++) {
54             add(new CycleAdapter.CycleItem(getContext(), cycles.get(i + 1), cycles.get(i)));
55             if (cycles.get(i) == selectedCycle) {
56                 mSpinner.setSelection(i);
57             }
58         }
59     }
60 
61     /**
62      * Rebuild list based on network data. Always selects the newest item,
63      * updating the inspection range on chartData.
64      */
updateCycleList(List<Range<Long>> cycleData)65     public void updateCycleList(List<Range<Long>> cycleData) {
66         // stash away currently selected cycle to try restoring below
67         final CycleAdapter.CycleItem previousItem = (CycleAdapter.CycleItem)
68                 mSpinner.getSelectedItem();
69         clear();
70 
71         final Context context = getContext();
72         for (Range<Long> cycle : cycleData) {
73             add(new CycleAdapter.CycleItem(context, cycle.getLower(), cycle.getUpper()));
74         }
75 
76         // force pick the current cycle (first item)
77         if (getCount() > 0) {
78             final int position = findNearestPosition(previousItem);
79             mSpinner.setSelection(position);
80         }
81     }
82 
83     /**
84      * List item that reflects a specific data usage cycle.
85      */
86     public static class CycleItem implements Comparable<CycleItem> {
87         public CharSequence label;
88         public long start;
89         public long end;
90 
CycleItem(Context context, long start, long end)91         public CycleItem(Context context, long start, long end) {
92             this.label = Utils.formatDateRange(context, start, end);
93             this.start = start;
94             this.end = end;
95         }
96 
97         @Override
toString()98         public String toString() {
99             return label.toString();
100         }
101 
102         @Override
equals(Object o)103         public boolean equals(Object o) {
104             if (o instanceof CycleItem) {
105                 final CycleItem another = (CycleItem) o;
106                 return start == another.start && end == another.end;
107             }
108             return false;
109         }
110 
111         @Override
compareTo(CycleItem another)112         public int compareTo(CycleItem another) {
113             return Long.compare(start, another.start);
114         }
115     }
116 
117     public interface SpinnerInterface {
setAdapter(CycleAdapter cycleAdapter)118         void setAdapter(CycleAdapter cycleAdapter);
119 
getSelectedItem()120         Object getSelectedItem();
121 
setSelection(int position)122         void setSelection(int position);
123     }
124 }
125