From 27ee2f0865a535e4b4b9e879e7c340725a168856 Mon Sep 17 00:00:00 2001 From: Doris Ling Date: Mon, 17 Sep 2018 12:46:49 -0700 Subject: [PATCH] Use the new network stats loader to get usage data for all apps. - change to use the new NetworkStats.Bucket instead of NetworkStats.Entry when iterating through the detail data. Bug: 111751694 Test: make RunSettingsRoboTests Change-Id: I305cc384320e4a72531d80dd9a00a3034ab12837 --- .../settings/datausage/DataUsageListV2.java | 66 +++++++++++-------- .../datausage/DataUsagePreference.java | 3 + .../datausage/DataUsageListV2Test.java | 13 ++++ 3 files changed, 56 insertions(+), 26 deletions(-) diff --git a/src/com/android/settings/datausage/DataUsageListV2.java b/src/com/android/settings/datausage/DataUsageListV2.java index fd20e23a37c..4a05af3e19f 100644 --- a/src/com/android/settings/datausage/DataUsageListV2.java +++ b/src/com/android/settings/datausage/DataUsageListV2.java @@ -21,6 +21,8 @@ import static android.net.TrafficStats.UID_TETHERING; import static android.telephony.TelephonyManager.SIM_STATE_READY; import android.app.ActivityManager; +import android.app.usage.NetworkStats; +import android.app.usage.NetworkStats.Bucket; import android.content.Context; import android.content.Intent; import android.content.pm.UserInfo; @@ -28,7 +30,6 @@ import android.graphics.Color; import android.net.ConnectivityManager; import android.net.INetworkStatsSession; import android.net.NetworkPolicy; -import android.net.NetworkStats; import android.net.NetworkStatsHistory; import android.net.NetworkTemplate; import android.net.TrafficStats; @@ -65,7 +66,7 @@ import com.android.settings.widget.LoadingViewController; import com.android.settingslib.AppItem; import com.android.settingslib.net.ChartData; import com.android.settingslib.net.ChartDataLoaderCompat; -import com.android.settingslib.net.SummaryForAllUidLoaderCompat; +import com.android.settingslib.net.NetworkStatsDetailLoader; import com.android.settingslib.net.UidDetailProvider; import java.util.ArrayList; @@ -78,8 +79,9 @@ import java.util.List; */ public class DataUsageListV2 extends DataUsageBaseFragment { - public static final String EXTRA_SUB_ID = "sub_id"; - public static final String EXTRA_NETWORK_TEMPLATE = "network_template"; + static final String EXTRA_SUB_ID = "sub_id"; + static final String EXTRA_NETWORK_TEMPLATE = "network_template"; + static final String EXTRA_NETWORK_TYPE = "network_type"; private static final String TAG = "DataUsageListV2"; private static final boolean LOGD = false; @@ -106,6 +108,8 @@ public class DataUsageListV2 extends DataUsageBaseFragment { NetworkTemplate mTemplate; @VisibleForTesting int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; + @VisibleForTesting + int mNetworkType; private ChartData mChartData; private LoadingViewController mLoadingViewController; @@ -249,6 +253,7 @@ public class DataUsageListV2 extends DataUsageBaseFragment { if (args != null) { mSubId = args.getInt(EXTRA_SUB_ID, SubscriptionManager.INVALID_SUBSCRIPTION_ID); mTemplate = args.getParcelable(EXTRA_NETWORK_TEMPLATE); + mNetworkType = args.getInt(EXTRA_NETWORK_TYPE, ConnectivityManager.TYPE_MOBILE); } if (mTemplate == null && mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { final Intent intent = getIntent(); @@ -336,8 +341,8 @@ public class DataUsageListV2 extends DataUsageBaseFragment { } // kick off loader for detailed stats - getLoaderManager().restartLoader(LOADER_SUMMARY, - SummaryForAllUidLoaderCompat.buildArgs(mTemplate, start, end), mSummaryCallbacks); + getLoaderManager().restartLoader(LOADER_SUMMARY, null /* args */, + mNetworkStatsDetailCallbacks); final long totalBytes = entry != null ? entry.rxBytes + entry.txBytes : 0; final CharSequence totalPhrase = DataUsageUtils.formatDataUsage(context, totalBytes); @@ -348,22 +353,26 @@ public class DataUsageListV2 extends DataUsageBaseFragment { * Bind the given {@link NetworkStats}, or {@code null} to clear list. */ public void bindStats(NetworkStats stats, int[] restrictedUids) { - ArrayList items = new ArrayList<>(); + mApps.removeAll(); + if (stats == null) { + if (LOGD) { + Log.d(TAG, "No network stats data. App list cleared."); + } + return; + } + + final ArrayList items = new ArrayList<>(); long largest = 0; final int currentUserId = ActivityManager.getCurrentUser(); - UserManager userManager = UserManager.get(getContext()); + final UserManager userManager = UserManager.get(getContext()); final List profiles = userManager.getUserProfiles(); final SparseArray knownItems = new SparseArray(); - NetworkStats.Entry entry = null; - final int size = stats != null ? stats.size() : 0; - for (int i = 0; i < size; i++) { - entry = stats.getValues(i, entry); - + final Bucket bucket = new Bucket(); + while (stats.hasNextBucket() && stats.getNextBucket(bucket)) { // Decide how to collapse items together - final int uid = entry.uid; - + final int uid = bucket.getUid(); final int collapseKey; final int category; final int userId = UserHandle.getUserId(uid); @@ -372,8 +381,8 @@ public class DataUsageListV2 extends DataUsageBaseFragment { if (userId != currentUserId) { // Add to a managed user item. final int managedKey = UidDetailProvider.buildKeyForUser(userId); - largest = accumulate(managedKey, knownItems, entry, AppItem.CATEGORY_USER, - items, largest); + largest = accumulate(managedKey, knownItems, bucket, + AppItem.CATEGORY_USER, items, largest); } // Add to app item. collapseKey = uid; @@ -397,8 +406,9 @@ public class DataUsageListV2 extends DataUsageBaseFragment { collapseKey = android.os.Process.SYSTEM_UID; category = AppItem.CATEGORY_APP; } - largest = accumulate(collapseKey, knownItems, entry, category, items, largest); + largest = accumulate(collapseKey, knownItems, bucket, category, items, largest); } + stats.close(); final int restrictedUidsMax = restrictedUids.length; for (int i = 0; i < restrictedUidsMax; ++i) { @@ -419,7 +429,6 @@ public class DataUsageListV2 extends DataUsageBaseFragment { } Collections.sort(items); - mApps.removeAll(); for (int i = 0; i < items.size(); i++) { final int percentTotal = largest != 0 ? (int) (items.get(i).total * 100 / largest) : 0; AppDataUsagePreference preference = new AppDataUsagePreference(getContext(), @@ -456,12 +465,12 @@ public class DataUsageListV2 extends DataUsageBaseFragment { * * @param collapseKey the collapse key used to map the item. * @param knownItems collection of known (already existing) items. - * @param entry the network stats entry to extract data usage from. + * @param bucket the network stats bucket to extract data usage from. * @param itemCategory the item is categorized on the list view by this category. Must be */ private static long accumulate(int collapseKey, final SparseArray knownItems, - NetworkStats.Entry entry, int itemCategory, ArrayList items, long largest) { - final int uid = entry.uid; + Bucket bucket, int itemCategory, ArrayList items, long largest) { + final int uid = bucket.getUid(); AppItem item = knownItems.get(collapseKey); if (item == null) { item = new AppItem(collapseKey); @@ -470,7 +479,7 @@ public class DataUsageListV2 extends DataUsageBaseFragment { knownItems.put(item.key, item); } item.addUid(uid); - item.total += entry.rxBytes + entry.txBytes; + item.total += bucket.getRxBytes() + bucket.getTxBytes(); return Math.max(largest, item.total); } @@ -579,11 +588,16 @@ public class DataUsageListV2 extends DataUsageBaseFragment { } }; - private final LoaderCallbacks mSummaryCallbacks = new LoaderCallbacks< - NetworkStats>() { + private final LoaderCallbacks mNetworkStatsDetailCallbacks = + new LoaderCallbacks() { @Override public Loader onCreateLoader(int id, Bundle args) { - return new SummaryForAllUidLoaderCompat(getActivity(), mStatsSession, args); + return new NetworkStatsDetailLoader.Builder(getContext()) + .setStartTime(mChart.getInspectStart()) + .setEndTime(mChart.getInspectEnd()) + .setNetworkType(mNetworkType) + .setSubscriptionId(mSubId) + .build(); } @Override diff --git a/src/com/android/settings/datausage/DataUsagePreference.java b/src/com/android/settings/datausage/DataUsagePreference.java index cdec619a6bb..5bd8dcd08d3 100644 --- a/src/com/android/settings/datausage/DataUsagePreference.java +++ b/src/com/android/settings/datausage/DataUsagePreference.java @@ -17,6 +17,7 @@ package com.android.settings.datausage; import android.content.Context; import android.content.Intent; import android.content.res.TypedArray; +import android.net.ConnectivityManager; import android.net.NetworkTemplate; import android.os.Bundle; import android.util.AttributeSet; @@ -81,6 +82,8 @@ public class DataUsagePreference extends Preference implements TemplatePreferenc if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.DATA_USAGE_V2)) { args.putParcelable(DataUsageListV2.EXTRA_NETWORK_TEMPLATE, mTemplate); args.putInt(DataUsageListV2.EXTRA_SUB_ID, mSubId); + args.putInt(DataUsageListV2.EXTRA_NETWORK_TYPE, mTemplate.isMatchRuleMobile() + ? ConnectivityManager.TYPE_MOBILE : ConnectivityManager.TYPE_WIFI); launcher = new SubSettingLauncher(getContext()) .setArguments(args) .setDestination(DataUsageListV2.class.getName()) diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageListV2Test.java b/tests/robotests/src/com/android/settings/datausage/DataUsageListV2Test.java index 9eb800375bd..f561a054d1f 100644 --- a/tests/robotests/src/com/android/settings/datausage/DataUsageListV2Test.java +++ b/tests/robotests/src/com/android/settings/datausage/DataUsageListV2Test.java @@ -26,6 +26,7 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.content.Intent; +import android.net.ConnectivityManager; import android.net.NetworkTemplate; import android.os.Bundle; import android.provider.Settings; @@ -97,6 +98,18 @@ public class DataUsageListV2Test { assertThat(mDataUsageList.mSubId).isEqualTo(3); } + @Test + public void processArgument_shouldGetNetworkTypeFromArgument() { + final Bundle args = new Bundle(); + args.putInt(DataUsageListV2.EXTRA_NETWORK_TYPE, ConnectivityManager.TYPE_WIFI); + args.putInt(DataUsageListV2.EXTRA_SUB_ID, 3); + mDataUsageList.setArguments(args); + + mDataUsageList.processArgument(); + + assertThat(mDataUsageList.mNetworkType).isEqualTo(ConnectivityManager.TYPE_WIFI); + } + @Test public void processArgument_fromIntent_shouldGetTemplateFromIntent() { final FragmentActivity activity = mock(FragmentActivity.class);