blob: c7c89ee90eec8f65e58ba1e2d61637bfc16cefa6 [file] [log] [blame]
Jeff Sharkey4dfa6602011-06-13 00:42:03 -07001/*
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
17package com.android.settings;
18
19import static android.net.NetworkPolicyManager.POLICY_NONE;
20import static android.net.NetworkPolicyManager.POLICY_REJECT_PAID_BACKGROUND;
21import static android.net.TrafficStats.TEMPLATE_MOBILE_ALL;
22import static com.android.settings.DataUsageSummary.getHistoryBounds;
23
24import android.app.Fragment;
25import android.content.Context;
26import android.content.Intent;
27import android.content.pm.PackageManager;
28import android.graphics.Color;
29import android.net.INetworkPolicyManager;
30import android.net.INetworkStatsService;
31import android.net.NetworkStatsHistory;
32import android.os.Bundle;
33import android.os.RemoteException;
34import android.os.ServiceManager;
35import android.preference.CheckBoxPreference;
36import android.preference.Preference;
37import android.text.format.DateUtils;
38import android.text.format.Formatter;
39import android.util.Log;
40import android.view.LayoutInflater;
41import android.view.View;
42import android.view.View.OnClickListener;
43import android.view.ViewGroup;
44import android.widget.Button;
45import android.widget.FrameLayout;
46import android.widget.LinearLayout;
47import android.widget.TextView;
48
49import com.android.settings.widget.DataUsageChartView;
50import com.android.settings.widget.DataUsageChartView.DataUsageChartListener;
51
52public class DataUsageAppDetail extends Fragment {
53 private static final String TAG = "DataUsage";
54 private static final boolean LOGD = true;
55
56 private int mUid;
57
58 private INetworkStatsService mStatsService;
59 private INetworkPolicyManager mPolicyService;
60
61 private CheckBoxPreference mRestrictBackground;
62 private View mRestrictBackgroundView;
63
64 private FrameLayout mChartContainer;
65 private TextView mTitle;
66 private TextView mText1;
67 private Button mAppSettings;
68 private LinearLayout mSwitches;
69
70 private DataUsageChartView mChart;
71
72 private int mUidPolicy;
73 private NetworkStatsHistory mHistory;
74
75 @Override
76 public void onCreate(Bundle savedInstanceState) {
77 super.onCreate(savedInstanceState);
78
79 mStatsService = INetworkStatsService.Stub.asInterface(
80 ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
81 mPolicyService = INetworkPolicyManager.Stub.asInterface(
82 ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
83 }
84
85 @Override
86 public View onCreateView(LayoutInflater inflater, ViewGroup container,
87 Bundle savedInstanceState) {
88
89 final Context context = inflater.getContext();
90 final View view = inflater.inflate(R.layout.data_usage_detail, container, false);
91
92 mChartContainer = (FrameLayout) view.findViewById(R.id.chart_container);
93 mTitle = (TextView) view.findViewById(android.R.id.title);
94 mText1 = (TextView) view.findViewById(android.R.id.text1);
95 mAppSettings = (Button) view.findViewById(R.id.data_usage_app_settings);
96 mSwitches = (LinearLayout) view.findViewById(R.id.switches);
97
98 mRestrictBackground = new CheckBoxPreference(context);
99 mRestrictBackground.setTitle(R.string.data_usage_app_restrict_background);
100 mRestrictBackground.setSummary(R.string.data_usage_app_restrict_background_summary);
101
102 // kick refresh once to force-create views
103 refreshPreferenceViews();
104
105 mSwitches.addView(mRestrictBackgroundView);
106 mRestrictBackgroundView.setOnClickListener(mRestrictBackgroundListener);
107
108 mAppSettings.setOnClickListener(mAppSettingsListener);
109
110 mChart = new DataUsageChartView(context);
111 mChartContainer.addView(mChart);
112
113 mChart.setListener(mChartListener);
114 mChart.setChartColor(Color.parseColor("#d88d3a"), Color.parseColor("#c0ba7f3e"),
115 Color.parseColor("#88566abc"));
116
117 return view;
118 }
119
120 @Override
121 public void onResume() {
122 super.onResume();
123
124 final Context context = getActivity();
125
126 mUid = getArguments().getInt(Intent.EXTRA_UID);
127 mTitle.setText(context.getPackageManager().getNameForUid(mUid));
128
129 updateBody();
130 }
131
132 private void updateBody() {
133 try {
134 // load stats for current uid and template
135 // TODO: read template from extras
136 mUidPolicy = mPolicyService.getUidPolicy(mUid);
137 mHistory = mStatsService.getHistoryForUid(mUid, TEMPLATE_MOBILE_ALL);
138 } catch (RemoteException e) {
139 // since we can't do much without policy or history, and we don't
140 // want to leave with half-baked UI, we bail hard.
141 throw new RuntimeException("problem reading network stats", e);
142 }
143
144 // bind chart to historical stats
145 mChart.bindNetworkStats(mHistory);
146
147 // show entire history known
148 final long[] bounds = getHistoryBounds(mHistory);
149 mChart.setVisibleRange(bounds[0], bounds[1] + DateUtils.WEEK_IN_MILLIS, bounds[1]);
150 updateDetailData();
151
152 // update policy checkbox
153 final boolean restrictBackground = (mUidPolicy & POLICY_REJECT_PAID_BACKGROUND) != 0;
154 mRestrictBackground.setChecked(restrictBackground);
155
156 // kick preference views so they rebind from changes above
157 refreshPreferenceViews();
158 }
159
160 private void updateDetailData() {
161 if (LOGD) Log.d(TAG, "updateDetailData()");
162
163 final Context context = mChart.getContext();
164 final long[] range = mChart.getInspectRange();
165 final long[] total = mHistory.getTotalData(range[0], range[1], null);
166 final long totalCombined = total[0] + total[1];
167 mText1.setText(Formatter.formatFileSize(context, totalCombined));
168 }
169
170 /**
171 * Force rebind of hijacked {@link Preference} views.
172 */
173 private void refreshPreferenceViews() {
174 mRestrictBackgroundView = mRestrictBackground.getView(mRestrictBackgroundView, mSwitches);
175 }
176
177 private DataUsageChartListener mChartListener = new DataUsageChartListener() {
178 /** {@inheritDoc} */
179 public void onInspectRangeChanged() {
180 if (LOGD) Log.d(TAG, "onInspectRangeChanged()");
181 updateDetailData();
182 }
183
184 /** {@inheritDoc} */
185 public void onWarningChanged() {
186 // ignored
187 }
188
189 /** {@inheritDoc} */
190 public void onLimitChanged() {
191 // ignored
192 }
193 };
194
195 private OnClickListener mAppSettingsListener = new OnClickListener() {
196 /** {@inheritDoc} */
197 public void onClick(View v) {
198 // TODO: target torwards entire UID instead of just first package
199 final PackageManager pm = getActivity().getPackageManager();
200 final String packageName = pm.getPackagesForUid(mUid)[0];
201
202 final Intent intent = new Intent(Intent.ACTION_MANAGE_NETWORK_USAGE);
203 intent.setPackage(packageName);
204 startActivity(intent);
205 }
206 };
207
208 private OnClickListener mRestrictBackgroundListener = new OnClickListener() {
209 /** {@inheritDoc} */
210 public void onClick(View v) {
211 final boolean restrictBackground = !mRestrictBackground.isChecked();
212 mRestrictBackground.setChecked(restrictBackground);
213 refreshPreferenceViews();
214
215 try {
216 mPolicyService.setUidPolicy(
217 mUid, restrictBackground ? POLICY_REJECT_PAID_BACKGROUND : POLICY_NONE);
218 } catch (RemoteException e) {
219 throw new RuntimeException("unable to save policy", e);
220 }
221 }
222 };
223
224}