Home | History | Annotate | Download | only in net
      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