1 /* 2 * Copyright (C) 2011 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 static android.net.NetworkStats.SET_DEFAULT; 20 import static android.net.NetworkStats.SET_FOREGROUND; 21 import static android.net.NetworkStats.TAG_NONE; 22 import static android.net.NetworkStatsHistory.FIELD_RX_BYTES; 23 import static android.net.NetworkStatsHistory.FIELD_TX_BYTES; 24 import static android.text.format.DateUtils.HOUR_IN_MILLIS; 25 26 import android.content.AsyncTaskLoader; 27 import android.content.Context; 28 import android.net.INetworkStatsSession; 29 import android.net.NetworkStatsHistory; 30 import android.net.NetworkTemplate; 31 import android.os.Bundle; 32 import android.os.RemoteException; 33 34 import com.android.settingslib.AppItem; 35 36 /** 37 * Loader for historical chart data for both network and UID details. 38 */ 39 public class ChartDataLoader extends AsyncTaskLoader<ChartData> { 40 private static final String KEY_TEMPLATE = "template"; 41 private static final String KEY_APP = "app"; 42 private static final String KEY_FIELDS = "fields"; 43 44 private final INetworkStatsSession mSession; 45 private final Bundle mArgs; 46 47 public static Bundle buildArgs(NetworkTemplate template, AppItem app) { 48 return buildArgs(template, app, FIELD_RX_BYTES | FIELD_TX_BYTES); 49 } 50 51 public static Bundle buildArgs(NetworkTemplate template, AppItem app, int fields) { 52 final Bundle args = new Bundle(); 53 args.putParcelable(KEY_TEMPLATE, template); 54 args.putParcelable(KEY_APP, app); 55 args.putInt(KEY_FIELDS, fields); 56 return args; 57 } 58 59 public ChartDataLoader(Context context, INetworkStatsSession session, Bundle args) { 60 super(context); 61 mSession = session; 62 mArgs = args; 63 } 64 65 @Override 66 protected void onStartLoading() { 67 super.onStartLoading(); 68 forceLoad(); 69 } 70 71 @Override 72 public ChartData loadInBackground() { 73 final NetworkTemplate template = mArgs.getParcelable(KEY_TEMPLATE); 74 final AppItem app = mArgs.getParcelable(KEY_APP); 75 final int fields = mArgs.getInt(KEY_FIELDS); 76 77 try { 78 return loadInBackground(template, app, fields); 79 } catch (RemoteException e) { 80 // since we can't do much without history, and we don't want to 81 // leave with half-baked UI, we bail hard. 82 throw new RuntimeException("problem reading network stats", e); 83 } 84 } 85 86 private ChartData loadInBackground(NetworkTemplate template, AppItem app, int fields) 87 throws RemoteException { 88 final ChartData data = new ChartData(); 89 data.network = mSession.getHistoryForNetwork(template, fields); 90 91 if (app != null) { 92 // load stats for current uid and template 93 final int size = app.uids.size(); 94 for (int i = 0; i < size; i++) { 95 final int uid = app.uids.keyAt(i); 96 data.detailDefault = collectHistoryForUid( 97 template, uid, SET_DEFAULT, data.detailDefault); 98 data.detailForeground = collectHistoryForUid( 99 template, uid, SET_FOREGROUND, data.detailForeground); 100 } 101 102 if (size > 0) { 103 data.detail = new NetworkStatsHistory(data.detailForeground.getBucketDuration()); 104 data.detail.recordEntireHistory(data.detailDefault); 105 data.detail.recordEntireHistory(data.detailForeground); 106 } else { 107 data.detailDefault = new NetworkStatsHistory(HOUR_IN_MILLIS); 108 data.detailForeground = new NetworkStatsHistory(HOUR_IN_MILLIS); 109 data.detail = new NetworkStatsHistory(HOUR_IN_MILLIS); 110 } 111 } 112 113 return data; 114 } 115 116 @Override 117 protected void onStopLoading() { 118 super.onStopLoading(); 119 cancelLoad(); 120 } 121 122 @Override 123 protected void onReset() { 124 super.onReset(); 125 cancelLoad(); 126 } 127 128 /** 129 * Collect {@link NetworkStatsHistory} for the requested UID, combining with 130 * an existing {@link NetworkStatsHistory} if provided. 131 */ 132 private NetworkStatsHistory collectHistoryForUid( 133 NetworkTemplate template, int uid, int set, NetworkStatsHistory existing) 134 throws RemoteException { 135 final NetworkStatsHistory history = mSession.getHistoryForUid( 136 template, uid, set, TAG_NONE, FIELD_RX_BYTES | FIELD_TX_BYTES); 137 138 if (existing != null) { 139 existing.recordEntireHistory(history); 140 return existing; 141 } else { 142 return history; 143 } 144 } 145 } 146