• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.settings.applications.appinfo;
18 
19 import android.content.Context;
20 import android.net.NetworkStats;
21 import android.net.NetworkTemplate;
22 import android.os.Bundle;
23 import android.os.Process;
24 import android.text.format.DateUtils;
25 import android.text.format.Formatter;
26 
27 import androidx.annotation.VisibleForTesting;
28 import androidx.loader.app.LoaderManager;
29 import androidx.loader.content.Loader;
30 import androidx.preference.Preference;
31 import androidx.preference.PreferenceScreen;
32 
33 import com.android.settings.R;
34 import com.android.settings.SettingsPreferenceFragment;
35 import com.android.settings.Utils;
36 import com.android.settings.datausage.AppDataUsage;
37 import com.android.settings.datausage.DataUsageUtils;
38 import com.android.settings.network.SubscriptionUtil;
39 import com.android.settingslib.AppItem;
40 import com.android.settingslib.applications.AppUtils;
41 import com.android.settingslib.core.lifecycle.LifecycleObserver;
42 import com.android.settingslib.core.lifecycle.events.OnPause;
43 import com.android.settingslib.core.lifecycle.events.OnResume;
44 import com.android.settingslib.net.NetworkCycleDataForUid;
45 import com.android.settingslib.net.NetworkCycleDataForUidLoader;
46 
47 import java.util.List;
48 
49 public class AppDataUsagePreferenceController extends AppInfoPreferenceControllerBase
50         implements LoaderManager.LoaderCallbacks<List<NetworkCycleDataForUid>>, LifecycleObserver,
51         OnResume, OnPause {
52 
53     private List<NetworkCycleDataForUid> mAppUsageData;
54 
AppDataUsagePreferenceController(Context context, String key)55     public AppDataUsagePreferenceController(Context context, String key) {
56         super(context, key);
57     }
58 
59     @Override
getAvailabilityStatus()60     public int getAvailabilityStatus() {
61         return isBandwidthControlEnabled() ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
62     }
63 
64     @Override
displayPreference(PreferenceScreen screen)65     public void displayPreference(PreferenceScreen screen) {
66         super.displayPreference(screen);
67         mPreference.setEnabled(AppUtils.isAppInstalled(mAppEntry));
68     }
69 
70     @Override
updateState(Preference preference)71     public void updateState(Preference preference) {
72         preference.setSummary(getDataSummary());
73     }
74 
75     @Override
onResume()76     public void onResume() {
77         if (isAvailable()) {
78             final int uid = mParent.getAppEntry().info.uid;
79             final AppItem app = new AppItem(uid);
80             app.addUid(uid);
81             mParent.getLoaderManager().restartLoader(mParent.LOADER_CHART_DATA, null /* args */,
82                     this);
83         }
84     }
85 
86     @Override
onPause()87     public void onPause() {
88         if (isAvailable()) {
89             mParent.getLoaderManager().destroyLoader(mParent.LOADER_CHART_DATA);
90         }
91     }
92 
93     @Override
onCreateLoader(int id, Bundle args)94     public Loader<List<NetworkCycleDataForUid>> onCreateLoader(int id, Bundle args) {
95         final NetworkTemplate template = getTemplate(mContext);
96         final int uid = mParent.getAppEntry().info.uid;
97 
98         final NetworkCycleDataForUidLoader.Builder builder =
99                 NetworkCycleDataForUidLoader.builder(mContext);
100         builder.setRetrieveDetail(false)
101                .setNetworkTemplate(template);
102 
103         builder.addUid(uid);
104         if (Process.isApplicationUid(uid)) {
105             // Also add in network usage for the app's SDK sandbox
106             builder.addUid(Process.toSdkSandboxUid(uid));
107         }
108         return builder.build();
109     }
110 
111     @Override
onLoadFinished(Loader<List<NetworkCycleDataForUid>> loader, List<NetworkCycleDataForUid> data)112     public void onLoadFinished(Loader<List<NetworkCycleDataForUid>> loader,
113             List<NetworkCycleDataForUid> data) {
114         mAppUsageData = data;
115         updateState(mPreference);
116     }
117 
118     @Override
onLoaderReset(Loader<List<NetworkCycleDataForUid>> loader)119     public void onLoaderReset(Loader<List<NetworkCycleDataForUid>> loader) {
120         // Leave last result.
121     }
122 
123     @Override
getDetailFragmentClass()124     protected Class<? extends SettingsPreferenceFragment> getDetailFragmentClass() {
125         return AppDataUsage.class;
126     }
127 
getDataSummary()128     private CharSequence getDataSummary() {
129         if (mAppUsageData != null) {
130             long totalBytes = 0;
131             long startTime = System.currentTimeMillis();
132             for (NetworkCycleDataForUid data : mAppUsageData) {
133                 totalBytes += data.getTotalUsage();
134                 final long cycleStart = data.getStartTime();
135                 if (cycleStart < startTime) {
136                     startTime = cycleStart;
137                 }
138             }
139             if (totalBytes == 0) {
140                 return mContext.getString(R.string.no_data_usage);
141             }
142             return mContext.getString(R.string.data_summary_format,
143                     Formatter.formatFileSize(mContext, totalBytes, Formatter.FLAG_IEC_UNITS),
144                     DateUtils.formatDateTime(mContext, startTime,
145                             DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_MONTH));
146         }
147         return mContext.getString(R.string.computing_size);
148     }
149 
getTemplate(Context context)150     private static NetworkTemplate getTemplate(Context context) {
151         if (SubscriptionUtil.isSimHardwareVisible(context)
152                 && DataUsageUtils.hasReadyMobileRadio(context)) {
153             return new NetworkTemplate.Builder(NetworkTemplate.MATCH_MOBILE).setMeteredness(
154                     NetworkStats.METERED_YES).build();
155         }
156         if (DataUsageUtils.hasWifiRadio(context)) {
157             return new NetworkTemplate.Builder(NetworkTemplate.MATCH_WIFI).build();
158         }
159         return new NetworkTemplate.Builder(NetworkTemplate.MATCH_ETHERNET).build();
160     }
161 
162     @VisibleForTesting
isBandwidthControlEnabled()163     boolean isBandwidthControlEnabled() {
164         return Utils.isBandwidthControlEnabled();
165     }
166 
167 }
168