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