1b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey/*
2b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * Copyright (C) 2011 The Android Open Source Project
3b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey *
4b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
5b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * you may not use this file except in compliance with the License.
6b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * You may obtain a copy of the License at
7b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey *
8b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
9b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey *
10b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * Unless required by applicable law or agreed to in writing, software
11b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
12b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * See the License for the specific language governing permissions and
14b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * limitations under the License.
15b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey */
16b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey
17b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeypackage com.android.settings.net;
18b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey
19b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport static android.net.NetworkStats.SET_DEFAULT;
20b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport static android.net.NetworkStats.SET_FOREGROUND;
21b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport static android.net.NetworkStats.TAG_NONE;
22b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport static android.net.NetworkStatsHistory.FIELD_RX_BYTES;
23b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport static android.net.NetworkStatsHistory.FIELD_TX_BYTES;
24e557c3349ee781162434ec4746fb71d45606f97cJeff Sharkeyimport static android.text.format.DateUtils.HOUR_IN_MILLIS;
25b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey
26b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport android.content.AsyncTaskLoader;
27b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport android.content.Context;
2808ce99e224145759904bbd6ae36e0b2bf4b0e4e6Jeff Sharkeyimport android.net.INetworkStatsSession;
29b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport android.net.NetworkStatsHistory;
30b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport android.net.NetworkTemplate;
31b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport android.os.Bundle;
32b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport android.os.RemoteException;
33b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey
34ef6e1ff728bdf67e222d4d3452f5f354f519556fJeff Sharkeyimport com.android.settings.DataUsageSummary.AppItem;
35ef6e1ff728bdf67e222d4d3452f5f354f519556fJeff Sharkey
36b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey/**
37b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * Loader for historical chart data for both network and UID details.
38b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey */
39b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeypublic class ChartDataLoader extends AsyncTaskLoader<ChartData> {
40b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey    private static final String KEY_TEMPLATE = "template";
41ef6e1ff728bdf67e222d4d3452f5f354f519556fJeff Sharkey    private static final String KEY_APP = "app";
42b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey    private static final String KEY_FIELDS = "fields";
43b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey
4408ce99e224145759904bbd6ae36e0b2bf4b0e4e6Jeff Sharkey    private final INetworkStatsSession mSession;
45b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey    private final Bundle mArgs;
46b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey
47ef6e1ff728bdf67e222d4d3452f5f354f519556fJeff Sharkey    public static Bundle buildArgs(NetworkTemplate template, AppItem app) {
48ef6e1ff728bdf67e222d4d3452f5f354f519556fJeff Sharkey        return buildArgs(template, app, FIELD_RX_BYTES | FIELD_TX_BYTES);
49b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey    }
50b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey
51ef6e1ff728bdf67e222d4d3452f5f354f519556fJeff Sharkey    public static Bundle buildArgs(NetworkTemplate template, AppItem app, int fields) {
52b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey        final Bundle args = new Bundle();
53b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey        args.putParcelable(KEY_TEMPLATE, template);
54ef6e1ff728bdf67e222d4d3452f5f354f519556fJeff Sharkey        args.putParcelable(KEY_APP, app);
55b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey        args.putInt(KEY_FIELDS, fields);
56b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey        return args;
57b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey    }
58b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey
5908ce99e224145759904bbd6ae36e0b2bf4b0e4e6Jeff Sharkey    public ChartDataLoader(Context context, INetworkStatsSession session, Bundle args) {
60b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey        super(context);
6108ce99e224145759904bbd6ae36e0b2bf4b0e4e6Jeff Sharkey        mSession = session;
62b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey        mArgs = args;
63b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey    }
64b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey
65b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey    @Override
66b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey    protected void onStartLoading() {
67b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey        super.onStartLoading();
68b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey        forceLoad();
69b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey    }
70b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey
71b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey    @Override
72b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey    public ChartData loadInBackground() {
73b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey        final NetworkTemplate template = mArgs.getParcelable(KEY_TEMPLATE);
74ef6e1ff728bdf67e222d4d3452f5f354f519556fJeff Sharkey        final AppItem app = mArgs.getParcelable(KEY_APP);
75b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey        final int fields = mArgs.getInt(KEY_FIELDS);
76b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey
77b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey        try {
78ef6e1ff728bdf67e222d4d3452f5f354f519556fJeff Sharkey            return loadInBackground(template, app, fields);
79b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey        } catch (RemoteException e) {
80b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey            // since we can't do much without history, and we don't want to
81b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey            // leave with half-baked UI, we bail hard.
82b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey            throw new RuntimeException("problem reading network stats", e);
83b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey        }
84b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey    }
85b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey
86ef6e1ff728bdf67e222d4d3452f5f354f519556fJeff Sharkey    private ChartData loadInBackground(NetworkTemplate template, AppItem app, int fields)
87b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey            throws RemoteException {
88b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey        final ChartData data = new ChartData();
8908ce99e224145759904bbd6ae36e0b2bf4b0e4e6Jeff Sharkey        data.network = mSession.getHistoryForNetwork(template, fields);
90b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey
91ef6e1ff728bdf67e222d4d3452f5f354f519556fJeff Sharkey        if (app != null) {
92b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey            // load stats for current uid and template
93ef6e1ff728bdf67e222d4d3452f5f354f519556fJeff Sharkey            final int size = app.uids.size();
94ef6e1ff728bdf67e222d4d3452f5f354f519556fJeff Sharkey            for (int i = 0; i < size; i++) {
95ef6e1ff728bdf67e222d4d3452f5f354f519556fJeff Sharkey                final int uid = app.uids.keyAt(i);
96b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey                data.detailDefault = collectHistoryForUid(
97b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey                        template, uid, SET_DEFAULT, data.detailDefault);
98b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey                data.detailForeground = collectHistoryForUid(
99b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey                        template, uid, SET_FOREGROUND, data.detailForeground);
100b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey            }
101b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey
102e557c3349ee781162434ec4746fb71d45606f97cJeff Sharkey            if (size > 0) {
103e557c3349ee781162434ec4746fb71d45606f97cJeff Sharkey                data.detail = new NetworkStatsHistory(data.detailForeground.getBucketDuration());
104e557c3349ee781162434ec4746fb71d45606f97cJeff Sharkey                data.detail.recordEntireHistory(data.detailDefault);
105e557c3349ee781162434ec4746fb71d45606f97cJeff Sharkey                data.detail.recordEntireHistory(data.detailForeground);
106e557c3349ee781162434ec4746fb71d45606f97cJeff Sharkey            } else {
107e557c3349ee781162434ec4746fb71d45606f97cJeff Sharkey                data.detailDefault = new NetworkStatsHistory(HOUR_IN_MILLIS);
108e557c3349ee781162434ec4746fb71d45606f97cJeff Sharkey                data.detailForeground = new NetworkStatsHistory(HOUR_IN_MILLIS);
109e557c3349ee781162434ec4746fb71d45606f97cJeff Sharkey                data.detail = new NetworkStatsHistory(HOUR_IN_MILLIS);
110e557c3349ee781162434ec4746fb71d45606f97cJeff Sharkey            }
111b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey        }
112b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey
113b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey        return data;
114b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey    }
115b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey
116b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey    @Override
117b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey    protected void onStopLoading() {
118b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey        super.onStopLoading();
119b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey        cancelLoad();
120b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey    }
121b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey
122b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey    @Override
123b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey    protected void onReset() {
124b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey        super.onReset();
125b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey        cancelLoad();
126b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey    }
127b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey
128b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey    /**
129b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey     * Collect {@link NetworkStatsHistory} for the requested UID, combining with
130b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey     * an existing {@link NetworkStatsHistory} if provided.
131b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey     */
132b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey    private NetworkStatsHistory collectHistoryForUid(
133b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey            NetworkTemplate template, int uid, int set, NetworkStatsHistory existing)
134b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey            throws RemoteException {
13508ce99e224145759904bbd6ae36e0b2bf4b0e4e6Jeff Sharkey        final NetworkStatsHistory history = mSession.getHistoryForUid(
136b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey                template, uid, set, TAG_NONE, FIELD_RX_BYTES | FIELD_TX_BYTES);
137b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey
138b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey        if (existing != null) {
139b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey            existing.recordEntireHistory(history);
140b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey            return existing;
141b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey        } else {
142b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey            return history;
143b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey        }
144b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey    }
145b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey}
146