1 /*
2  * Copyright (C) 2018 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.settingslib.net;
18 
19 import android.app.usage.NetworkStats;
20 import android.content.Context;
21 import android.util.Log;
22 
23 import java.util.ArrayList;
24 import java.util.List;
25 
26 /**
27  * Loader for network data usage history. It returns a list of usage data per billing cycle with
28  * bucketized usages.
29  */
30 public class NetworkCycleChartDataLoader
31         extends NetworkCycleDataLoader<List<NetworkCycleChartData>> {
32 
33     private static final String TAG = "NetworkCycleChartLoader";
34 
35     private final List<NetworkCycleChartData> mData;
36 
NetworkCycleChartDataLoader(Builder builder)37     private NetworkCycleChartDataLoader(Builder builder) {
38         super(builder);
39         mData = new ArrayList<>();
40     }
41 
42     @Override
recordUsage(long start, long end)43     void recordUsage(long start, long end) {
44         try {
45             final NetworkStats.Bucket bucket = mNetworkStatsManager.querySummaryForDevice(
46                     mNetworkTemplate, start, end);
47             final long total = bucket == null ? 0L : bucket.getRxBytes() + bucket.getTxBytes();
48             if (total > 0L) {
49                 final NetworkCycleChartData.Builder builder = new NetworkCycleChartData.Builder();
50                 builder.setUsageBuckets(getUsageBuckets(start, end))
51                     .setStartTime(start)
52                     .setEndTime(end)
53                     .setTotalUsage(total);
54                 mData.add(builder.build());
55             }
56         } catch (RuntimeException e) {
57             Log.e(TAG, "Exception querying network detail.", e);
58         }
59     }
60 
61     @Override
getCycleUsage()62     List<NetworkCycleChartData> getCycleUsage() {
63         return mData;
64     }
65 
builder(Context context)66     public static Builder<?> builder(Context context) {
67         return new Builder<NetworkCycleChartDataLoader>(context) {
68             @Override
69             public NetworkCycleChartDataLoader build() {
70                 return new NetworkCycleChartDataLoader(this);
71             }
72         };
73     }
74 
75     private List<NetworkCycleData> getUsageBuckets(long start, long end) {
76         final List<NetworkCycleData> data = new ArrayList<>();
77         long bucketStart = start;
78         long bucketEnd = start + NetworkCycleChartData.BUCKET_DURATION_MS;
79         while (bucketEnd <= end) {
80             long usage = 0L;
81             try {
82                 final NetworkStats.Bucket bucket = mNetworkStatsManager.querySummaryForDevice(
83                         mNetworkTemplate, bucketStart, bucketEnd);
84                 if (bucket != null) {
85                     usage = bucket.getRxBytes() + bucket.getTxBytes();
86                 }
87             } catch (RuntimeException e) {
88                 Log.e(TAG, "Exception querying network detail.", e);
89             }
90             data.add(new NetworkCycleData.Builder()
91                 .setStartTime(bucketStart).setEndTime(bucketEnd).setTotalUsage(usage).build());
92             bucketStart = bucketEnd;
93             bucketEnd += NetworkCycleChartData.BUCKET_DURATION_MS;
94         }
95         return data;
96     }
97 
98     public static abstract class Builder<T extends NetworkCycleChartDataLoader>
99             extends NetworkCycleDataLoader.Builder<T> {
100 
101         public Builder(Context context) {
102             super(context);
103         }
104 
105     }
106 
107 }
108