diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 7689b11cb1c..f51127817de 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -2223,7 +2223,7 @@ + android:value="com.android.settings.datausage.DataUsageListV2" /> - - , LifecycleObserver, OnResume, OnPause { - - private ChartData mChartData; - private INetworkStatsSession mStatsSession; - - public AppDataUsagePreferenceController(Context context,String key) { - super(context, key); - } - - @Override - public int getAvailabilityStatus() { - if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.DATA_USAGE_V2)) { - return UNSUPPORTED_ON_DEVICE; - } - return isBandwidthControlEnabled() ? AVAILABLE : CONDITIONALLY_UNAVAILABLE; - } - - @Override - public void displayPreference(PreferenceScreen screen) { - super.displayPreference(screen); - if (isAvailable()) { - final INetworkStatsService statsService = INetworkStatsService.Stub.asInterface( - ServiceManager.getService(Context.NETWORK_STATS_SERVICE)); - try { - mStatsSession = statsService.openSession(); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - } - - @Override - public void updateState(Preference preference) { - preference.setSummary(getDataSummary()); - } - - @Override - public void onResume() { - if (mStatsSession != null) { - final int uid = mParent.getAppEntry().info.uid; - final AppItem app = new AppItem(uid); - app.addUid(uid); - mParent.getLoaderManager().restartLoader(mParent.LOADER_CHART_DATA, - ChartDataLoaderCompat.buildArgs(getTemplate(mContext), app), - this); - } - } - - @Override - public void onPause() { - if (mStatsSession != null) { - mParent.getLoaderManager().destroyLoader(mParent.LOADER_CHART_DATA); - } - } - - @Override - public Loader onCreateLoader(int id, Bundle args) { - return new ChartDataLoaderCompat(mContext, mStatsSession, args); - } - - @Override - public void onLoadFinished(Loader loader, ChartData data) { - mChartData = data; - updateState(mPreference); - } - - @Override - public void onLoaderReset(Loader loader) { - // Leave last result. - } - - @Override - protected Class getDetailFragmentClass() { - return AppDataUsage.class; - } - - private CharSequence getDataSummary() { - if (mChartData != null) { - final long totalBytes = mChartData.detail.getTotalBytes(); - if (totalBytes == 0) { - return mContext.getString(R.string.no_data_usage); - } - return mContext.getString(R.string.data_summary_format, - Formatter.formatFileSize(mContext, totalBytes), - DateUtils.formatDateTime(mContext, mChartData.detail.getStart(), - DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_MONTH)); - } - return mContext.getString(R.string.computing_size); - } - - private static NetworkTemplate getTemplate(Context context) { - if (DataUsageUtils.hasReadyMobileRadio(context)) { - return NetworkTemplate.buildTemplateMobileWildcard(); - } - if (DataUsageUtils.hasWifiRadio(context)) { - return NetworkTemplate.buildTemplateWifiWildcard(); - } - return NetworkTemplate.buildTemplateEthernet(); - } - - @VisibleForTesting - boolean isBandwidthControlEnabled() { - return Utils.isBandwidthControlEnabled(); - } - -} diff --git a/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceControllerV2.java b/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceControllerV2.java index 9bbc5c0935a..84f58e6fbfe 100644 --- a/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceControllerV2.java +++ b/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceControllerV2.java @@ -21,7 +21,6 @@ import android.net.NetworkTemplate; import android.os.Bundle; import android.text.format.DateUtils; import android.text.format.Formatter; -import android.util.FeatureFlagUtils; import androidx.annotation.VisibleForTesting; import androidx.loader.app.LoaderManager; @@ -32,7 +31,6 @@ import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.SettingsPreferenceFragment; import com.android.settings.Utils; -import com.android.settings.core.FeatureFlags; import com.android.settings.datausage.AppDataUsageV2; import com.android.settings.datausage.DataUsageUtils; import com.android.settingslib.AppItem; @@ -56,9 +54,6 @@ public class AppDataUsagePreferenceControllerV2 extends AppInfoPreferenceControl @Override public int getAvailabilityStatus() { - if (!FeatureFlagUtils.isEnabled(mContext, FeatureFlags.DATA_USAGE_V2)) { - return UNSUPPORTED_ON_DEVICE; - } return isBandwidthControlEnabled() ? AVAILABLE : CONDITIONALLY_UNAVAILABLE; } diff --git a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java index 32880d39441..742e2596eb4 100755 --- a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java +++ b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java @@ -34,7 +34,6 @@ import android.os.Bundle; import android.os.UserHandle; import android.os.UserManager; import android.text.TextUtils; -import android.util.FeatureFlagUtils; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; @@ -49,7 +48,6 @@ import com.android.settings.SettingsPreferenceFragment; import com.android.settings.applications.manageapplications.ManageApplications; import com.android.settings.applications.specialaccess.pictureinpicture .PictureInPictureDetailPreferenceController; -import com.android.settings.core.FeatureFlags; import com.android.settings.core.SubSettingLauncher; import com.android.settings.dashboard.DashboardFragment; import com.android.settingslib.RestrictedLockUtilsInternal; @@ -141,11 +139,7 @@ public class AppInfoDashboardFragment extends DashboardFragment final String packageName = getPackageName(); use(TimeSpentInAppPreferenceController.class).setPackageName(packageName); - if (FeatureFlagUtils.isEnabled(context, FeatureFlags.DATA_USAGE_V2)) { - use(AppDataUsagePreferenceControllerV2.class).setParentFragment(this); - } else { - use(AppDataUsagePreferenceController.class).setParentFragment(this); - } + use(AppDataUsagePreferenceControllerV2.class).setParentFragment(this); final AppInstallerInfoPreferenceController installer = use(AppInstallerInfoPreferenceController.class); installer.setPackageName(packageName); diff --git a/src/com/android/settings/core/FeatureFlags.java b/src/com/android/settings/core/FeatureFlags.java index 0a26b79c93d..daa1e7b1b08 100644 --- a/src/com/android/settings/core/FeatureFlags.java +++ b/src/com/android/settings/core/FeatureFlags.java @@ -24,7 +24,6 @@ public class FeatureFlags { public static final String DYNAMIC_HOMEPAGE = "settings_dynamic_homepage"; public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid"; public static final String MOBILE_NETWORK_V2 = "settings_mobile_network_v2"; - public static final String DATA_USAGE_V2 = "settings_data_usage_v2"; public static final String WIFI_MAC_RANDOMIZATION = "settings_wifi_mac_randomization"; public static final String NETWORK_INTERNET_V2 = "settings_network_and_internet_v2"; } diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java index 7ba36887c4d..2accd613b7f 100644 --- a/src/com/android/settings/core/gateway/SettingsGateway.java +++ b/src/com/android/settings/core/gateway/SettingsGateway.java @@ -57,7 +57,7 @@ import com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFrag import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment; import com.android.settings.connecteddevice.PreviouslyConnectedDeviceDashboardFragment; import com.android.settings.connecteddevice.usb.UsbDetailsFragment; -import com.android.settings.datausage.DataUsageList; +import com.android.settings.datausage.DataUsageListV2; import com.android.settings.datausage.DataUsageSummary; import com.android.settings.deletionhelper.AutomaticStorageManagerSettings; import com.android.settings.development.DevelopmentSettingsDashboardFragment; @@ -258,7 +258,7 @@ public class SettingsGateway { WebViewAppPicker.class.getName(), LockscreenDashboardFragment.class.getName(), BluetoothDeviceDetailsFragment.class.getName(), - DataUsageList.class.getName(), + DataUsageListV2.class.getName(), ToggleBackupSettingFragment.class.getName(), PreviouslyConnectedDeviceDashboardFragment.class.getName(), }; diff --git a/src/com/android/settings/datausage/AppDataUsage.java b/src/com/android/settings/datausage/AppDataUsage.java deleted file mode 100644 index 78aa6c27868..00000000000 --- a/src/com/android/settings/datausage/AppDataUsage.java +++ /dev/null @@ -1,452 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.android.settings.datausage; - -import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.graphics.drawable.Drawable; -import android.net.INetworkStatsSession; -import android.net.NetworkPolicy; -import android.net.NetworkStatsHistory; -import android.net.NetworkTemplate; -import android.net.TrafficStats; -import android.os.Bundle; -import android.os.RemoteException; -import android.os.UserHandle; -import android.util.ArraySet; -import android.util.IconDrawableFactory; -import android.util.Log; -import android.view.View; -import android.widget.AdapterView; - -import androidx.annotation.VisibleForTesting; -import androidx.loader.app.LoaderManager; -import androidx.loader.content.Loader; -import androidx.preference.Preference; -import androidx.preference.Preference.OnPreferenceChangeListener; -import androidx.preference.PreferenceCategory; - -import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.settings.R; -import com.android.settings.applications.AppInfoBase; -import com.android.settings.widget.EntityHeaderController; -import com.android.settingslib.AppItem; -import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; -import com.android.settingslib.RestrictedLockUtilsInternal; -import com.android.settingslib.RestrictedSwitchPreference; -import com.android.settingslib.net.ChartData; -import com.android.settingslib.net.ChartDataLoaderCompat; -import com.android.settingslib.net.UidDetail; -import com.android.settingslib.net.UidDetailProvider; - -public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceChangeListener, - DataSaverBackend.Listener { - - private static final String TAG = "AppDataUsage"; - - public static final String ARG_APP_ITEM = "app_item"; - public static final String ARG_NETWORK_TEMPLATE = "network_template"; - - private static final String KEY_TOTAL_USAGE = "total_usage"; - private static final String KEY_FOREGROUND_USAGE = "foreground_usage"; - private static final String KEY_BACKGROUND_USAGE = "background_usage"; - private static final String KEY_APP_SETTINGS = "app_settings"; - private static final String KEY_RESTRICT_BACKGROUND = "restrict_background"; - private static final String KEY_APP_LIST = "app_list"; - private static final String KEY_CYCLE = "cycle"; - private static final String KEY_UNRESTRICTED_DATA = "unrestricted_data_saver"; - - private static final int LOADER_CHART_DATA = 2; - private static final int LOADER_APP_PREF = 3; - - private PackageManager mPackageManager; - private final ArraySet mPackages = new ArraySet<>(); - private Preference mTotalUsage; - private Preference mForegroundUsage; - private Preference mBackgroundUsage; - private Preference mAppSettings; - private RestrictedSwitchPreference mRestrictBackground; - private PreferenceCategory mAppList; - - private Drawable mIcon; - private CharSequence mLabel; - private String mPackageName; - private INetworkStatsSession mStatsSession; - private CycleAdapter mCycleAdapter; - - private long mStart; - private long mEnd; - private ChartData mChartData; - private NetworkTemplate mTemplate; - private NetworkPolicy mPolicy; - private AppItem mAppItem; - private Intent mAppSettingsIntent; - private SpinnerPreference mCycle; - private RestrictedSwitchPreference mUnrestrictedData; - private DataSaverBackend mDataSaverBackend; - - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - mPackageManager = getPackageManager(); - final Bundle args = getArguments(); - - try { - mStatsSession = services.mStatsService.openSession(); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - - mAppItem = (args != null) ? (AppItem) args.getParcelable(ARG_APP_ITEM) : null; - mTemplate = (args != null) ? (NetworkTemplate) args.getParcelable(ARG_NETWORK_TEMPLATE) - : null; - if (mTemplate == null) { - Context context = getContext(); - mTemplate = DataUsageUtils.getDefaultTemplate(context, - DataUsageUtils.getDefaultSubscriptionId(context)); - } - if (mAppItem == null) { - int uid = (args != null) ? args.getInt(AppInfoBase.ARG_PACKAGE_UID, -1) - : getActivity().getIntent().getIntExtra(AppInfoBase.ARG_PACKAGE_UID, -1); - if (uid == -1) { - // TODO: Log error. - getActivity().finish(); - } else { - addUid(uid); - mAppItem = new AppItem(uid); - mAppItem.addUid(uid); - } - } else { - for (int i = 0; i < mAppItem.uids.size(); i++) { - addUid(mAppItem.uids.keyAt(i)); - } - } - - mTotalUsage = findPreference(KEY_TOTAL_USAGE); - mForegroundUsage = findPreference(KEY_FOREGROUND_USAGE); - mBackgroundUsage = findPreference(KEY_BACKGROUND_USAGE); - - mCycle = (SpinnerPreference) findPreference(KEY_CYCLE); - mCycleAdapter = new CycleAdapter(getContext(), mCycle, mCycleListener); - - if (mAppItem.key > 0) { - if (mPackages.size() != 0) { - try { - ApplicationInfo info = mPackageManager.getApplicationInfoAsUser( - mPackages.valueAt(0), 0, UserHandle.getUserId(mAppItem.key)); - mIcon = IconDrawableFactory.newInstance(getActivity()).getBadgedIcon(info); - mLabel = info.loadLabel(mPackageManager); - mPackageName = info.packageName; - } catch (PackageManager.NameNotFoundException e) { - } - } - if (!UserHandle.isApp(mAppItem.key)) { - removePreference(KEY_UNRESTRICTED_DATA); - removePreference(KEY_RESTRICT_BACKGROUND); - } else { - mRestrictBackground = (RestrictedSwitchPreference) findPreference( - KEY_RESTRICT_BACKGROUND); - mRestrictBackground.setOnPreferenceChangeListener(this); - mUnrestrictedData = (RestrictedSwitchPreference) findPreference( - KEY_UNRESTRICTED_DATA); - mUnrestrictedData.setOnPreferenceChangeListener(this); - } - mDataSaverBackend = new DataSaverBackend(getContext()); - mAppSettings = findPreference(KEY_APP_SETTINGS); - - mAppSettingsIntent = new Intent(Intent.ACTION_MANAGE_NETWORK_USAGE); - mAppSettingsIntent.addCategory(Intent.CATEGORY_DEFAULT); - - PackageManager pm = getPackageManager(); - boolean matchFound = false; - for (String packageName : mPackages) { - mAppSettingsIntent.setPackage(packageName); - if (pm.resolveActivity(mAppSettingsIntent, 0) != null) { - matchFound = true; - break; - } - } - if (!matchFound) { - removePreference(KEY_APP_SETTINGS); - mAppSettings = null; - } - - if (mPackages.size() > 1) { - mAppList = (PreferenceCategory) findPreference(KEY_APP_LIST); - LoaderManager.getInstance(this).restartLoader(LOADER_APP_PREF, Bundle.EMPTY, - mAppPrefCallbacks); - } else { - removePreference(KEY_APP_LIST); - } - } else { - final Context context = getActivity(); - UidDetail uidDetail = new UidDetailProvider(context).getUidDetail(mAppItem.key, true); - mIcon = uidDetail.icon; - mLabel = uidDetail.label; - mPackageName = context.getPackageName(); - - removePreference(KEY_UNRESTRICTED_DATA); - removePreference(KEY_APP_SETTINGS); - removePreference(KEY_RESTRICT_BACKGROUND); - removePreference(KEY_APP_LIST); - } - } - - @Override - public void onDestroy() { - TrafficStats.closeQuietly(mStatsSession); - super.onDestroy(); - } - - @Override - public void onResume() { - super.onResume(); - if (mDataSaverBackend != null) { - mDataSaverBackend.addListener(this); - } - mPolicy = services.mPolicyEditor.getPolicy(mTemplate); - LoaderManager.getInstance(this).restartLoader(LOADER_CHART_DATA, - ChartDataLoaderCompat.buildArgs(mTemplate, mAppItem), mChartDataCallbacks); - updatePrefs(); - } - - @Override - public void onPause() { - super.onPause(); - if (mDataSaverBackend != null) { - mDataSaverBackend.remListener(this); - } - } - - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - if (preference == mRestrictBackground) { - mDataSaverBackend.setIsBlacklisted(mAppItem.key, mPackageName, !(Boolean) newValue); - updatePrefs(); - return true; - } else if (preference == mUnrestrictedData) { - mDataSaverBackend.setIsWhitelisted(mAppItem.key, mPackageName, (Boolean) newValue); - return true; - } - return false; - } - - @Override - public boolean onPreferenceTreeClick(Preference preference) { - if (preference == mAppSettings) { - // TODO: target towards entire UID instead of just first package - getActivity().startActivityAsUser(mAppSettingsIntent, new UserHandle( - UserHandle.getUserId(mAppItem.key))); - return true; - } - return super.onPreferenceTreeClick(preference); - } - - @Override - protected int getPreferenceScreenResId() { - return R.xml.app_data_usage; - } - - @Override - protected String getLogTag() { - return TAG; - } - - @VisibleForTesting - void updatePrefs() { - updatePrefs(getAppRestrictBackground(), getUnrestrictData()); - } - - private void updatePrefs(boolean restrictBackground, boolean unrestrictData) { - final EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfMeteredDataRestricted( - getContext(), mPackageName, UserHandle.getUserId(mAppItem.key)); - if (mRestrictBackground != null) { - mRestrictBackground.setChecked(!restrictBackground); - mRestrictBackground.setDisabledByAdmin(admin); - } - if (mUnrestrictedData != null) { - if (restrictBackground) { - mUnrestrictedData.setVisible(false); - } else { - mUnrestrictedData.setVisible(true); - mUnrestrictedData.setChecked(unrestrictData); - mUnrestrictedData.setDisabledByAdmin(admin); - } - } - } - - private void addUid(int uid) { - String[] packages = getPackageManager().getPackagesForUid(uid); - if (packages != null) { - for (int i = 0; i < packages.length; i++) { - mPackages.add(packages[i]); - } - } - } - - private void bindData() { - final long backgroundBytes, foregroundBytes; - if (mChartData == null || mStart == 0) { - backgroundBytes = foregroundBytes = 0; - mCycle.setVisible(false); - } else { - mCycle.setVisible(true); - final long now = System.currentTimeMillis(); - NetworkStatsHistory.Entry entry = null; - entry = mChartData.detailDefault.getValues(mStart, mEnd, now, entry); - backgroundBytes = entry.rxBytes + entry.txBytes; - entry = mChartData.detailForeground.getValues(mStart, mEnd, now, entry); - foregroundBytes = entry.rxBytes + entry.txBytes; - } - final long totalBytes = backgroundBytes + foregroundBytes; - final Context context = getContext(); - - mTotalUsage.setSummary(DataUsageUtils.formatDataUsage(context, totalBytes)); - mForegroundUsage.setSummary(DataUsageUtils.formatDataUsage(context, foregroundBytes)); - mBackgroundUsage.setSummary(DataUsageUtils.formatDataUsage(context, backgroundBytes)); - } - - private boolean getAppRestrictBackground() { - final int uid = mAppItem.key; - final int uidPolicy = services.mPolicyManager.getUidPolicy(uid); - return (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0; - } - - private boolean getUnrestrictData() { - if (mDataSaverBackend != null) { - return mDataSaverBackend.isWhitelisted(mAppItem.key); - } - return false; - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - String pkg = mPackages.size() != 0 ? mPackages.valueAt(0) : null; - int uid = 0; - if (pkg != null) { - try { - uid = mPackageManager.getPackageUidAsUser(pkg, - UserHandle.getUserId(mAppItem.key)); - } catch (PackageManager.NameNotFoundException e) { - Log.w(TAG, "Skipping UID because cannot find package " + pkg); - } - } - - final boolean showInfoButton = mAppItem.key > 0; - - final Activity activity = getActivity(); - final Preference pref = EntityHeaderController - .newInstance(activity, this, null /* header */) - .setRecyclerView(getListView(), getSettingsLifecycle()) - .setUid(uid) - .setHasAppInfoLink(showInfoButton) - .setButtonActions(EntityHeaderController.ActionType.ACTION_NONE, - EntityHeaderController.ActionType.ACTION_NONE) - .setIcon(mIcon) - .setLabel(mLabel) - .setPackageName(pkg) - .done(activity, getPrefContext()); - getPreferenceScreen().addPreference(pref); - } - - @Override - public int getMetricsCategory() { - return MetricsEvent.APP_DATA_USAGE; - } - - private AdapterView.OnItemSelectedListener mCycleListener = - new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - final CycleAdapter.CycleItem cycle = (CycleAdapter.CycleItem) mCycle.getSelectedItem(); - - mStart = cycle.start; - mEnd = cycle.end; - bindData(); - } - - @Override - public void onNothingSelected(AdapterView parent) { - // ignored - } - }; - - private final LoaderManager.LoaderCallbacks mChartDataCallbacks = - new LoaderManager.LoaderCallbacks() { - @Override - public Loader onCreateLoader(int id, Bundle args) { - return new ChartDataLoaderCompat(getActivity(), mStatsSession, args); - } - - @Override - public void onLoadFinished(Loader loader, ChartData data) { - mChartData = data; - mCycleAdapter.updateCycleList(mPolicy, mChartData); - bindData(); - } - - @Override - public void onLoaderReset(Loader loader) { - } - }; - - private final LoaderManager.LoaderCallbacks> mAppPrefCallbacks = - new LoaderManager.LoaderCallbacks>() { - @Override - public Loader> onCreateLoader(int i, Bundle bundle) { - return new AppPrefLoader(getPrefContext(), mPackages, getPackageManager()); - } - - @Override - public void onLoadFinished(Loader> loader, - ArraySet preferences) { - if (preferences != null && mAppList != null) { - for (Preference preference : preferences) { - mAppList.addPreference(preference); - } - } - } - - @Override - public void onLoaderReset(Loader> loader) { - } - }; - - @Override - public void onDataSaverChanged(boolean isDataSaving) { - - } - - @Override - public void onWhitelistStatusChanged(int uid, boolean isWhitelisted) { - if (mAppItem.uids.get(uid, false)) { - updatePrefs(getAppRestrictBackground(), isWhitelisted); - } - } - - @Override - public void onBlacklistStatusChanged(int uid, boolean isBlacklisted) { - if (mAppItem.uids.get(uid, false)) { - updatePrefs(isBlacklisted, getUnrestrictData()); - } - } -} diff --git a/src/com/android/settings/datausage/AppDataUsageActivity.java b/src/com/android/settings/datausage/AppDataUsageActivity.java index 2b8e42dcdac..b4bac983e9f 100644 --- a/src/com/android/settings/datausage/AppDataUsageActivity.java +++ b/src/com/android/settings/datausage/AppDataUsageActivity.java @@ -59,9 +59,9 @@ public class AppDataUsageActivity extends SettingsActivity { final Bundle args = new Bundle(); final AppItem appItem = new AppItem(uid); appItem.addUid(uid); - args.putParcelable(AppDataUsage.ARG_APP_ITEM, appItem); + args.putParcelable(AppDataUsageV2.ARG_APP_ITEM, appItem); intent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, args); - intent.putExtra(EXTRA_SHOW_FRAGMENT, AppDataUsage.class.getName()); + intent.putExtra(EXTRA_SHOW_FRAGMENT, AppDataUsageV2.class.getName()); intent.putExtra(EXTRA_SHOW_FRAGMENT_TITLE_RESID, R.string.app_data_usage); super.onCreate(savedInstanceState); @@ -70,6 +70,6 @@ public class AppDataUsageActivity extends SettingsActivity { @Override protected boolean isValidFragment(String fragmentName) { return super.isValidFragment(fragmentName) - || AppDataUsage.class.getName().equals(fragmentName); + || AppDataUsageV2.class.getName().equals(fragmentName); } } diff --git a/src/com/android/settings/datausage/BillingCyclePreference.java b/src/com/android/settings/datausage/BillingCyclePreference.java index b30f32e0ff0..d53e43c535f 100644 --- a/src/com/android/settings/datausage/BillingCyclePreference.java +++ b/src/com/android/settings/datausage/BillingCyclePreference.java @@ -74,7 +74,7 @@ public class BillingCyclePreference extends Preference implements TemplatePrefer @Override public Intent getIntent() { Bundle args = new Bundle(); - args.putParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE, mTemplate); + args.putParcelable(DataUsageListV2.EXTRA_NETWORK_TEMPLATE, mTemplate); return new SubSettingLauncher(getContext()) .setDestination(BillingCycleSettings.class.getName()) .setArguments(args) diff --git a/src/com/android/settings/datausage/BillingCycleSettings.java b/src/com/android/settings/datausage/BillingCycleSettings.java index 45997f8efc3..e6370de9387 100644 --- a/src/com/android/settings/datausage/BillingCycleSettings.java +++ b/src/com/android/settings/datausage/BillingCycleSettings.java @@ -105,7 +105,7 @@ public class BillingCycleSettings extends DataUsageBaseFragment implements mDataUsageController = new DataUsageController(context); Bundle args = getArguments(); - mNetworkTemplate = args.getParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE); + mNetworkTemplate = args.getParcelable(DataUsageListV2.EXTRA_NETWORK_TEMPLATE); if (mNetworkTemplate == null) { mNetworkTemplate = DataUsageUtils.getDefaultTemplate(context, DataUsageUtils.getDefaultSubscriptionId(context)); diff --git a/src/com/android/settings/datausage/ChartDataUsagePreference.java b/src/com/android/settings/datausage/ChartDataUsagePreference.java index a0cef3ab0c9..1c8eb528694 100644 --- a/src/com/android/settings/datausage/ChartDataUsagePreference.java +++ b/src/com/android/settings/datausage/ChartDataUsagePreference.java @@ -16,14 +16,12 @@ package com.android.settings.datausage; import android.content.Context; import android.net.NetworkPolicy; -import android.net.NetworkStatsHistory; import android.net.TrafficStats; import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.text.format.Formatter; import android.text.style.ForegroundColorSpan; import android.util.AttributeSet; -import android.util.FeatureFlagUtils; import android.util.SparseIntArray; import androidx.annotation.VisibleForTesting; @@ -32,7 +30,6 @@ import androidx.preference.PreferenceViewHolder; import com.android.settings.R; import com.android.settings.Utils; -import com.android.settings.core.FeatureFlags; import com.android.settings.widget.UsageView; import com.android.settingslib.net.NetworkCycleChartData; import com.android.settingslib.net.NetworkCycleData; @@ -51,8 +48,6 @@ public class ChartDataUsagePreference extends Preference { private NetworkPolicy mPolicy; private long mStart; private long mEnd; - @Deprecated - private NetworkStatsHistory mNetwork; private NetworkCycleChartData mNetworkCycleChartData; private int mSecondaryColor; private int mSeriesColor; @@ -69,24 +64,14 @@ public class ChartDataUsagePreference extends Preference { public void onBindViewHolder(PreferenceViewHolder holder) { super.onBindViewHolder(holder); final UsageView chart = (UsageView) holder.findViewById(R.id.data_usage); - if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.DATA_USAGE_V2)) { - if (mNetworkCycleChartData == null) { - return; - } - } else { - if (mNetwork == null) { - return; - } + if (mNetworkCycleChartData == null) { + return; } final int top = getTop(); chart.clearPaths(); chart.configureGraph(toInt(mEnd - mStart), top); - if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.DATA_USAGE_V2)) { - calcPoints(chart, mNetworkCycleChartData.getUsageBuckets()); - } else { - calcPoints(chart); - } + calcPoints(chart, mNetworkCycleChartData.getUsageBuckets()); chart.setBottomLabels(new CharSequence[] { Utils.formatDateRange(getContext(), mStart, mStart), Utils.formatDateRange(getContext(), mEnd, mEnd), @@ -96,58 +81,12 @@ public class ChartDataUsagePreference extends Preference { } public int getTop() { - long totalData = 0; - if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.DATA_USAGE_V2)) { - totalData = mNetworkCycleChartData.getTotalUsage(); - } else { - NetworkStatsHistory.Entry entry = null; - final int start = mNetwork.getIndexBefore(mStart); - final int end = mNetwork.getIndexAfter(mEnd); - - for (int i = start; i <= end; i++) { - entry = mNetwork.getValues(i, entry); - - // increment by current bucket total - totalData += entry.rxBytes + entry.txBytes; - } - } - long policyMax = mPolicy != null ? Math.max(mPolicy.limitBytes, mPolicy.warningBytes) : 0; + final long totalData = mNetworkCycleChartData.getTotalUsage(); + final long policyMax = + mPolicy != null ? Math.max(mPolicy.limitBytes, mPolicy.warningBytes) : 0; return (int) (Math.max(totalData, policyMax) / RESOLUTION); } - @Deprecated - @VisibleForTesting - void calcPoints(UsageView chart) { - SparseIntArray points = new SparseIntArray(); - NetworkStatsHistory.Entry entry = null; - - long totalData = 0; - - final int start = mNetwork.getIndexAfter(mStart); - final int end = mNetwork.getIndexAfter(mEnd); - if (start < 0) return; - - points.put(0, 0); - for (int i = start; i <= end; i++) { - entry = mNetwork.getValues(i, entry); - - final long startTime = entry.bucketStart; - final long endTime = startTime + entry.bucketDuration; - - // increment by current bucket total - totalData += entry.rxBytes + entry.txBytes; - - if (i == 0) { - points.put(toInt(startTime - mStart) - 1, -1); - } - points.put(toInt(startTime - mStart + 1), (int) (totalData / RESOLUTION)); - points.put(toInt(endTime - mStart), (int) (totalData / RESOLUTION)); - } - if (points.size() > 1) { - chart.addPath(points); - } - } - @VisibleForTesting void calcPoints(UsageView chart, List usageSummary) { if (usageSummary == null) { @@ -220,13 +159,6 @@ public class ChartDataUsagePreference extends Preference { notifyChanged(); } - @Deprecated - public void setVisibleRange(long start, long end) { - mStart = start; - mEnd = end; - notifyChanged(); - } - public long getInspectStart() { return mStart; } @@ -235,12 +167,6 @@ public class ChartDataUsagePreference extends Preference { return mEnd; } - @Deprecated - public void setNetworkStats(NetworkStatsHistory network) { - mNetwork = network; - notifyChanged(); - } - public void setNetworkCycleData(NetworkCycleChartData data) { mNetworkCycleChartData = data; mStart = data.getStartTime(); diff --git a/src/com/android/settings/datausage/DataUsageList.java b/src/com/android/settings/datausage/DataUsageList.java deleted file mode 100644 index 24192cd02e7..00000000000 --- a/src/com/android/settings/datausage/DataUsageList.java +++ /dev/null @@ -1,552 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.android.settings.datausage; - -import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; -import static android.net.TrafficStats.UID_REMOVED; -import static android.net.TrafficStats.UID_TETHERING; - -import android.app.ActivityManager; -import android.content.Context; -import android.content.Intent; -import android.content.pm.UserInfo; -import android.graphics.Color; -import android.net.INetworkStatsSession; -import android.net.NetworkPolicy; -import android.net.NetworkStats; -import android.net.NetworkStatsHistory; -import android.net.NetworkTemplate; -import android.net.TrafficStats; -import android.os.AsyncTask; -import android.os.Bundle; -import android.os.RemoteException; -import android.os.UserHandle; -import android.os.UserManager; -import android.provider.Settings; -import android.telephony.SubscriptionInfo; -import android.telephony.SubscriptionManager; -import android.text.format.DateUtils; -import android.util.Log; -import android.util.SparseArray; -import android.view.View; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemSelectedListener; -import android.widget.ImageView; -import android.widget.Spinner; - -import androidx.annotation.VisibleForTesting; -import androidx.loader.app.LoaderManager.LoaderCallbacks; -import androidx.loader.content.Loader; -import androidx.preference.Preference; -import androidx.preference.PreferenceGroup; - -import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.settings.R; -import com.android.settings.core.SubSettingLauncher; -import com.android.settings.datausage.CycleAdapter.SpinnerInterface; -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.UidDetailProvider; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Panel showing data usage history across various networks, including options - * to inspect based on usage cycle and control through {@link NetworkPolicy}. - - * Deprecated in favor of {@link DataUsageListV2} - * - * @deprecated - */ -@Deprecated -public class DataUsageList extends DataUsageBaseFragment { - - public static final String EXTRA_SUB_ID = "sub_id"; - public static final String EXTRA_NETWORK_TEMPLATE = "network_template"; - - private static final String TAG = "DataUsageList"; - private static final boolean LOGD = false; - - private static final String KEY_USAGE_AMOUNT = "usage_amount"; - private static final String KEY_CHART_DATA = "chart_data"; - private static final String KEY_APPS_GROUP = "apps_group"; - - private static final int LOADER_CHART_DATA = 2; - private static final int LOADER_SUMMARY = 3; - - private final CellDataPreference.DataStateListener mDataStateListener = - new CellDataPreference.DataStateListener() { - @Override - public void onChange(boolean selfChange) { - updatePolicy(); - } - }; - - private INetworkStatsSession mStatsSession; - private ChartDataUsagePreference mChart; - - @VisibleForTesting - NetworkTemplate mTemplate; - @VisibleForTesting - int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; - private ChartData mChartData; - - private LoadingViewController mLoadingViewController; - private UidDetailProvider mUidDetailProvider; - private CycleAdapter mCycleAdapter; - private Spinner mCycleSpinner; - private Preference mUsageAmount; - private PreferenceGroup mApps; - private View mHeader; - - - @Override - public int getMetricsCategory() { - return MetricsEvent.DATA_USAGE_LIST; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - final Context context = getActivity(); - - if (!isBandwidthControlEnabled()) { - Log.w(TAG, "No bandwidth control; leaving"); - getActivity().finish(); - } - - try { - mStatsSession = services.mStatsService.openSession(); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - - mUidDetailProvider = new UidDetailProvider(context); - - mUsageAmount = findPreference(KEY_USAGE_AMOUNT); - mChart = (ChartDataUsagePreference) findPreference(KEY_CHART_DATA); - mApps = (PreferenceGroup) findPreference(KEY_APPS_GROUP); - processArgument(); - } - - @Override - public void onViewCreated(View v, Bundle savedInstanceState) { - super.onViewCreated(v, savedInstanceState); - - mHeader = setPinnedHeaderView(R.layout.apps_filter_spinner); - mHeader.findViewById(R.id.filter_settings).setOnClickListener(btn -> { - final Bundle args = new Bundle(); - args.putParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE, mTemplate); - new SubSettingLauncher(getContext()) - .setDestination(BillingCycleSettings.class.getName()) - .setTitleRes(R.string.billing_cycle) - .setSourceMetricsCategory(getMetricsCategory()) - .setArguments(args) - .launch(); - }); - mCycleSpinner = mHeader.findViewById(R.id.filter_spinner); - mCycleAdapter = new CycleAdapter(mCycleSpinner.getContext(), new SpinnerInterface() { - @Override - public void setAdapter(CycleAdapter cycleAdapter) { - mCycleSpinner.setAdapter(cycleAdapter); - } - - @Override - public void setOnItemSelectedListener(OnItemSelectedListener listener) { - mCycleSpinner.setOnItemSelectedListener(listener); - } - - @Override - public Object getSelectedItem() { - return mCycleSpinner.getSelectedItem(); - } - - @Override - public void setSelection(int position) { - mCycleSpinner.setSelection(position); - } - }, mCycleListener); - - mLoadingViewController = new LoadingViewController( - getView().findViewById(R.id.loading_container), getListView()); - mLoadingViewController.showLoadingViewDelayed(); - } - - @Override - public void onResume() { - super.onResume(); - mDataStateListener.setListener(true, mSubId, getContext()); - - // kick off background task to update stats - new AsyncTask() { - @Override - protected Void doInBackground(Void... params) { - try { - services.mStatsService.forceUpdate(); - } catch (RemoteException e) { - } - return null; - } - - @Override - protected void onPostExecute(Void result) { - updateBody(); - } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } - - @Override - public void onPause() { - super.onPause(); - mDataStateListener.setListener(false, mSubId, getContext()); - } - - @Override - public void onDestroy() { - mUidDetailProvider.clearCache(); - mUidDetailProvider = null; - - TrafficStats.closeQuietly(mStatsSession); - - super.onDestroy(); - } - - @Override - protected int getPreferenceScreenResId() { - return R.xml.data_usage_list; - } - - @Override - protected String getLogTag() { - return TAG; - } - - void processArgument() { - final Bundle args = getArguments(); - if (args != null) { - mSubId = args.getInt(EXTRA_SUB_ID, SubscriptionManager.INVALID_SUBSCRIPTION_ID); - mTemplate = args.getParcelable(EXTRA_NETWORK_TEMPLATE); - } - if (mTemplate == null && mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { - final Intent intent = getIntent(); - mSubId = intent.getIntExtra(Settings.EXTRA_SUB_ID, - SubscriptionManager.INVALID_SUBSCRIPTION_ID); - mTemplate = intent.getParcelableExtra(Settings.EXTRA_NETWORK_TEMPLATE); - } - } - - /** - * Update body content based on current tab. Loads - * {@link NetworkStatsHistory} and {@link NetworkPolicy} from system, and - * binds them to visible controls. - */ - private void updateBody() { - if (!isAdded()) return; - - final Context context = getActivity(); - - // kick off loader for network history - // TODO: consider chaining two loaders together instead of reloading - // network history when showing app detail. - getLoaderManager().restartLoader(LOADER_CHART_DATA, - ChartDataLoaderCompat.buildArgs(mTemplate, null), mChartDataCallbacks); - - // detail mode can change visible menus, invalidate - getActivity().invalidateOptionsMenu(); - - int seriesColor = context.getColor(R.color.sim_noitification); - if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { - final SubscriptionInfo sir = services.mSubscriptionManager - .getActiveSubscriptionInfo(mSubId); - - if (sir != null) { - seriesColor = sir.getIconTint(); - } - } - - final int secondaryColor = Color.argb(127, Color.red(seriesColor), Color.green(seriesColor), - Color.blue(seriesColor)); - mChart.setColors(seriesColor, secondaryColor); - } - - /** - * Update chart sweeps and cycle list to reflect {@link NetworkPolicy} for - * current {@link #mTemplate}. - */ - private void updatePolicy() { - final NetworkPolicy policy = services.mPolicyEditor.getPolicy(mTemplate); - final View configureButton = mHeader.findViewById(R.id.filter_settings); - //SUB SELECT - if (isNetworkPolicyModifiable(policy, mSubId) && isMobileDataAvailable(mSubId)) { - mChart.setNetworkPolicy(policy); - configureButton.setVisibility(View.VISIBLE); - ((ImageView) configureButton).setColorFilter(android.R.color.white); - } else { - // controls are disabled; don't bind warning/limit sweeps - mChart.setNetworkPolicy(null); - configureButton.setVisibility(View.GONE); - } - - // generate cycle list based on policy and available history - if (mCycleAdapter.updateCycleList(policy, mChartData)) { - updateDetailData(); - } - } - - /** - * Update details based on {@link #mChart} inspection range depending on - * current mode. Updates {@link #mAdapter} with sorted list - * of applications data usage. - */ - private void updateDetailData() { - if (LOGD) Log.d(TAG, "updateDetailData()"); - - final long start = mChart.getInspectStart(); - final long end = mChart.getInspectEnd(); - final long now = System.currentTimeMillis(); - - final Context context = getActivity(); - - NetworkStatsHistory.Entry entry = null; - if (mChartData != null) { - entry = mChartData.network.getValues(start, end, now, null); - } - - // kick off loader for detailed stats - getLoaderManager().restartLoader(LOADER_SUMMARY, - SummaryForAllUidLoaderCompat.buildArgs(mTemplate, start, end), mSummaryCallbacks); - - final long totalBytes = entry != null ? entry.rxBytes + entry.txBytes : 0; - final CharSequence totalPhrase = DataUsageUtils.formatDataUsage(context, totalBytes); - mUsageAmount.setTitle(getString(R.string.data_used_template, totalPhrase)); - } - - /** - * Bind the given {@link NetworkStats}, or {@code null} to clear list. - */ - private void bindStats(NetworkStats stats, int[] restrictedUids) { - ArrayList items = new ArrayList<>(); - long largest = 0; - - final int currentUserId = ActivityManager.getCurrentUser(); - 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); - - // Decide how to collapse items together - final int uid = entry.uid; - - final int collapseKey; - final int category; - final int userId = UserHandle.getUserId(uid); - if (UserHandle.isApp(uid)) { - if (profiles.contains(new UserHandle(userId))) { - 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); - } - // Add to app item. - collapseKey = uid; - category = AppItem.CATEGORY_APP; - } else { - // If it is a removed user add it to the removed users' key - final UserInfo info = userManager.getUserInfo(userId); - if (info == null) { - collapseKey = UID_REMOVED; - category = AppItem.CATEGORY_APP; - } else { - // Add to other user item. - collapseKey = UidDetailProvider.buildKeyForUser(userId); - category = AppItem.CATEGORY_USER; - } - } - } else if (uid == UID_REMOVED || uid == UID_TETHERING) { - collapseKey = uid; - category = AppItem.CATEGORY_APP; - } else { - collapseKey = android.os.Process.SYSTEM_UID; - category = AppItem.CATEGORY_APP; - } - largest = accumulate(collapseKey, knownItems, entry, category, items, largest); - } - - final int restrictedUidsMax = restrictedUids.length; - for (int i = 0; i < restrictedUidsMax; ++i) { - final int uid = restrictedUids[i]; - // Only splice in restricted state for current user or managed users - if (!profiles.contains(new UserHandle(UserHandle.getUserId(uid)))) { - continue; - } - - AppItem item = knownItems.get(uid); - if (item == null) { - item = new AppItem(uid); - item.total = -1; - items.add(item); - knownItems.put(item.key, item); - } - item.restricted = true; - } - - 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(), - items.get(i), percentTotal, mUidDetailProvider); - preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - AppDataUsagePreference pref = (AppDataUsagePreference) preference; - AppItem item = pref.getItem(); - startAppDataUsage(item); - return true; - } - }); - mApps.addPreference(preference); - } - } - - private void startAppDataUsage(AppItem item) { - final Bundle args = new Bundle(); - args.putParcelable(AppDataUsage.ARG_APP_ITEM, item); - args.putParcelable(AppDataUsage.ARG_NETWORK_TEMPLATE, mTemplate); - - new SubSettingLauncher(getContext()) - .setDestination(AppDataUsage.class.getName()) - .setTitleRes(R.string.app_data_usage) - .setArguments(args) - .setSourceMetricsCategory(getMetricsCategory()) - .launch(); - } - - /** - * Accumulate data usage of a network stats entry for the item mapped by the collapse key. - * Creates the item if needed. - * - * @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 itemCategory the item is categorized on the list view by this category. Must be - */ - private long accumulate(int collapseKey, final SparseArray knownItems, - NetworkStats.Entry entry, int itemCategory, ArrayList items, long largest) { - final int uid = entry.uid; - AppItem item = knownItems.get(collapseKey); - if (item == null) { - item = new AppItem(collapseKey); - item.category = itemCategory; - items.add(item); - knownItems.put(item.key, item); - } - item.addUid(uid); - item.total += entry.rxBytes + entry.txBytes; - return Math.max(largest, item.total); - } - - private OnItemSelectedListener mCycleListener = new OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - final CycleAdapter.CycleItem cycle = (CycleAdapter.CycleItem) - mCycleSpinner.getSelectedItem(); - - if (LOGD) { - Log.d(TAG, "showing cycle " + cycle + ", start=" + cycle.start + ", end=" - + cycle.end + "]"); - } - - // update chart to show selected cycle, and update detail data - // to match updated sweep bounds. - mChart.setVisibleRange(cycle.start, cycle.end); - - updateDetailData(); - } - - @Override - public void onNothingSelected(AdapterView parent) { - // ignored - } - }; - - private final LoaderCallbacks mChartDataCallbacks = new LoaderCallbacks< - ChartData>() { - @Override - public Loader onCreateLoader(int id, Bundle args) { - return new ChartDataLoaderCompat(getActivity(), mStatsSession, args); - } - - @Override - public void onLoadFinished(Loader loader, ChartData data) { - mLoadingViewController.showContent(false /* animate */); - mChartData = data; - mChart.setNetworkStats(mChartData.network); - - // calculate policy cycles based on available data - updatePolicy(); - } - - @Override - public void onLoaderReset(Loader loader) { - mChartData = null; - mChart.setNetworkStats(null); - } - }; - - private final LoaderCallbacks mSummaryCallbacks = new LoaderCallbacks< - NetworkStats>() { - @Override - public Loader onCreateLoader(int id, Bundle args) { - return new SummaryForAllUidLoaderCompat(getActivity(), mStatsSession, args); - } - - @Override - public void onLoadFinished(Loader loader, NetworkStats data) { - final int[] restrictedUids = services.mPolicyManager.getUidsWithPolicy( - POLICY_REJECT_METERED_BACKGROUND); - bindStats(data, restrictedUids); - updateEmptyVisible(); - } - - @Override - public void onLoaderReset(Loader loader) { - bindStats(null, new int[0]); - updateEmptyVisible(); - } - - private void updateEmptyVisible() { - if ((mApps.getPreferenceCount() != 0) != - (getPreferenceScreen().getPreferenceCount() != 0)) { - if (mApps.getPreferenceCount() != 0) { - getPreferenceScreen().addPreference(mUsageAmount); - getPreferenceScreen().addPreference(mApps); - } else { - getPreferenceScreen().removeAll(); - } - } - } - }; -} diff --git a/src/com/android/settings/datausage/DataUsageListV2.java b/src/com/android/settings/datausage/DataUsageListV2.java index 3a71935a865..d883e3243c0 100644 --- a/src/com/android/settings/datausage/DataUsageListV2.java +++ b/src/com/android/settings/datausage/DataUsageListV2.java @@ -15,6 +15,8 @@ package com.android.settings.datausage; import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; +import static android.net.NetworkStatsHistory.FIELD_RX_BYTES; +import static android.net.NetworkStatsHistory.FIELD_TX_BYTES; import static android.net.TrafficStats.UID_REMOVED; import static android.net.TrafficStats.UID_TETHERING; @@ -59,7 +61,6 @@ import com.android.settings.core.SubSettingLauncher; import com.android.settings.datausage.CycleAdapter.SpinnerInterface; import com.android.settings.widget.LoadingViewController; import com.android.settingslib.AppItem; -import com.android.settingslib.net.ChartDataLoaderCompat; import com.android.settingslib.net.NetworkCycleChartDataLoader; import com.android.settingslib.net.NetworkCycleChartData; import com.android.settingslib.net.NetworkStatsSummaryLoader; @@ -85,6 +86,9 @@ public class DataUsageListV2 extends DataUsageBaseFragment { private static final String KEY_USAGE_AMOUNT = "usage_amount"; private static final String KEY_CHART_DATA = "chart_data"; private static final String KEY_APPS_GROUP = "apps_group"; + private static final String KEY_TEMPLATE = "template"; + private static final String KEY_APP = "app"; + private static final String KEY_FIELDS = "fields"; private static final int LOADER_CHART_DATA = 2; private static final int LOADER_SUMMARY = 3; @@ -241,7 +245,7 @@ public class DataUsageListV2 extends DataUsageBaseFragment { // TODO: consider chaining two loaders together instead of reloading // network history when showing app detail. getLoaderManager().restartLoader(LOADER_CHART_DATA, - ChartDataLoaderCompat.buildArgs(mTemplate, null), mNetworkCycleDataCallbacks); + buildArgs(mTemplate), mNetworkCycleDataCallbacks); // detail mode can change visible menus, invalidate getActivity().invalidateOptionsMenu(); @@ -261,6 +265,14 @@ public class DataUsageListV2 extends DataUsageBaseFragment { mChart.setColors(seriesColor, secondaryColor); } + private Bundle buildArgs(NetworkTemplate template) { + final Bundle args = new Bundle(); + args.putParcelable(KEY_TEMPLATE, template); + args.putParcelable(KEY_APP, null); + args.putInt(KEY_FIELDS, FIELD_RX_BYTES | FIELD_TX_BYTES); + return args; + } + /** * Update chart sweeps and cycle list to reflect {@link NetworkPolicy} for * current {@link #mTemplate}. diff --git a/src/com/android/settings/datausage/DataUsagePreference.java b/src/com/android/settings/datausage/DataUsagePreference.java index aa4e646bdb5..fbfca48d073 100644 --- a/src/com/android/settings/datausage/DataUsagePreference.java +++ b/src/com/android/settings/datausage/DataUsagePreference.java @@ -21,7 +21,6 @@ import android.net.ConnectivityManager; import android.net.NetworkTemplate; import android.os.Bundle; import android.util.AttributeSet; -import android.util.FeatureFlagUtils; import androidx.annotation.VisibleForTesting; import androidx.core.content.res.TypedArrayUtils; @@ -29,7 +28,6 @@ import androidx.preference.Preference; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; -import com.android.settings.core.FeatureFlags; import com.android.settings.core.SubSettingLauncher; import com.android.settingslib.net.DataUsageController; @@ -78,23 +76,14 @@ public class DataUsagePreference extends Preference implements TemplatePreferenc public Intent getIntent() { final Bundle args = new Bundle(); final SubSettingLauncher launcher; - 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()) - .setSourceMetricsCategory(MetricsProto.MetricsEvent.VIEW_UNKNOWN); - } else { - args.putParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE, mTemplate); - args.putInt(DataUsageList.EXTRA_SUB_ID, mSubId); - launcher = new SubSettingLauncher(getContext()) - .setArguments(args) - .setDestination(DataUsageList.class.getName()) - .setSourceMetricsCategory(MetricsProto.MetricsEvent.VIEW_UNKNOWN); - } + 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()) + .setSourceMetricsCategory(MetricsProto.MetricsEvent.VIEW_UNKNOWN); if (mTemplate.isMatchRuleMobile()) { launcher.setTitleRes(R.string.app_cellular_data_usage); } else { diff --git a/src/com/android/settings/datausage/DataUsageSummaryPreference.java b/src/com/android/settings/datausage/DataUsageSummaryPreference.java index 92d3e29c317..edde661c4ad 100644 --- a/src/com/android/settings/datausage/DataUsageSummaryPreference.java +++ b/src/com/android/settings/datausage/DataUsageSummaryPreference.java @@ -208,11 +208,11 @@ public class DataUsageSummaryPreference extends Preference { private static void launchWifiDataUsage(Context context) { final Bundle args = new Bundle(1); - args.putParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE, + args.putParcelable(DataUsageListV2.EXTRA_NETWORK_TEMPLATE, NetworkTemplate.buildTemplateWifiWildcard()); final SubSettingLauncher launcher = new SubSettingLauncher(context) .setArguments(args) - .setDestination(DataUsageList.class.getName()) + .setDestination(DataUsageListV2.class.getName()) .setSourceMetricsCategory(MetricsProto.MetricsEvent.VIEW_UNKNOWN); launcher.setTitleRes(R.string.wifi_data_usage); launcher.launch(); diff --git a/src/com/android/settings/datausage/DataUsageUtils.java b/src/com/android/settings/datausage/DataUsageUtils.java index 53565ac803e..b3d0e61ae1d 100644 --- a/src/com/android/settings/datausage/DataUsageUtils.java +++ b/src/com/android/settings/datausage/DataUsageUtils.java @@ -22,12 +22,8 @@ import android.app.usage.NetworkStats.Bucket; import android.app.usage.NetworkStatsManager; import android.content.Context; import android.net.ConnectivityManager; -import android.net.INetworkStatsService; -import android.net.INetworkStatsSession; import android.net.NetworkTemplate; -import android.net.TrafficStats; import android.os.RemoteException; -import android.os.ServiceManager; import android.os.SystemProperties; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; @@ -35,11 +31,8 @@ import android.telephony.TelephonyManager; import android.text.BidiFormatter; import android.text.format.Formatter; import android.text.format.Formatter.BytesResult; -import android.util.FeatureFlagUtils; import android.util.Log; -import com.android.settings.core.FeatureFlags; - import java.util.List; /** @@ -78,44 +71,21 @@ public final class DataUsageUtils { return false; } - if (FeatureFlagUtils.isEnabled(context, FeatureFlags.DATA_USAGE_V2)) { - final TelephonyManager telephonyManager = TelephonyManager.from(context);; - final NetworkStatsManager networkStatsManager = - context.getSystemService(NetworkStatsManager.class); - boolean hasEthernetUsage = false; - try { - final Bucket bucket = networkStatsManager.querySummaryForUser( - ConnectivityManager.TYPE_ETHERNET, telephonyManager.getSubscriberId(), - 0L /* startTime */, System.currentTimeMillis() /* endTime */); - if (bucket != null) { - hasEthernetUsage = bucket.getRxBytes() > 0 || bucket.getTxBytes() > 0; - } - } catch (RemoteException e) { - Log.e(TAG, "Exception querying network detail.", e); + final TelephonyManager telephonyManager = TelephonyManager.from(context);; + final NetworkStatsManager networkStatsManager = + context.getSystemService(NetworkStatsManager.class); + boolean hasEthernetUsage = false; + try { + final Bucket bucket = networkStatsManager.querySummaryForUser( + ConnectivityManager.TYPE_ETHERNET, telephonyManager.getSubscriberId(), + 0L /* startTime */, System.currentTimeMillis() /* endTime */); + if (bucket != null) { + hasEthernetUsage = bucket.getRxBytes() > 0 || bucket.getTxBytes() > 0; } - return hasEthernetUsage; - } else { - final long ethernetBytes; - try { - INetworkStatsService statsService = INetworkStatsService.Stub.asInterface( - ServiceManager.getService(Context.NETWORK_STATS_SERVICE)); - - INetworkStatsSession statsSession = statsService.openSession(); - if (statsSession != null) { - ethernetBytes = statsSession.getSummaryForNetwork( - NetworkTemplate.buildTemplateEthernet(), Long.MIN_VALUE, Long.MAX_VALUE) - .getTotalBytes(); - TrafficStats.closeQuietly(statsSession); - } else { - ethernetBytes = 0; - } - } catch (RemoteException e) { - throw new RuntimeException(e); - } - - // only show ethernet when both hardware present and traffic has occurred - return ethernetBytes > 0; + } catch (RemoteException e) { + Log.e(TAG, "Exception querying network detail.", e); } + return hasEthernetUsage; } /** diff --git a/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java b/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java index 824c102aaec..9918411ea2a 100644 --- a/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java +++ b/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java @@ -81,7 +81,7 @@ public class UnrestrictedDataAccessPreference extends AppSwitchPreference implem protected void onClick() { if (mDataUsageState.isDataSaverBlacklisted) { // app is blacklisted, launch App Data Usage screen - AppInfoDashboardFragment.startAppInfoFragment(AppDataUsage.class, + AppInfoDashboardFragment.startAppInfoFragment(AppDataUsageV2.class, R.string.app_data_usage, null /* arguments */, mParentFragment, diff --git a/tests/robotests/assets/grandfather_not_implementing_index_provider b/tests/robotests/assets/grandfather_not_implementing_index_provider index 479ffee26c8..b8f1fa545d5 100644 --- a/tests/robotests/assets/grandfather_not_implementing_index_provider +++ b/tests/robotests/assets/grandfather_not_implementing_index_provider @@ -26,9 +26,7 @@ com.android.settings.biometrics.fingerprint.FingerprintSettings$FingerprintSetti com.android.settings.bluetooth.BluetoothDeviceDetailsFragment com.android.settings.bluetooth.BluetoothPairingDetail com.android.settings.bluetooth.DevicePickerFragment -com.android.settings.datausage.AppDataUsage com.android.settings.datausage.AppDataUsageV2 -com.android.settings.datausage.DataUsageList com.android.settings.datausage.DataUsageListV2 com.android.settings.datetime.timezone.TimeZoneSettings com.android.settings.deviceinfo.PrivateVolumeSettings diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceControllerTest.java deleted file mode 100644 index 1adc6781aec..00000000000 --- a/tests/robotests/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceControllerTest.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.applications.appinfo; - -import static com.android.settings.core.FeatureFlags.DATA_USAGE_V2; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.net.ConnectivityManager; -import android.net.INetworkStatsSession; -import android.os.Bundle; -import android.util.FeatureFlagUtils; - -import androidx.loader.app.LoaderManager; -import androidx.preference.Preference; - -import com.android.settings.core.BasePreferenceController; -import com.android.settings.datausage.AppDataUsage; -import com.android.settings.testutils.SettingsRobolectricTestRunner; -import com.android.settingslib.applications.ApplicationsState.AppEntry; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.util.ReflectionHelpers; - -@RunWith(SettingsRobolectricTestRunner.class) -public class AppDataUsagePreferenceControllerTest { - - @Mock - private LoaderManager mLoaderManager; - @Mock - private AppInfoDashboardFragment mFragment; - - private Context mContext; - private AppDataUsagePreferenceController mController; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mContext = spy(RuntimeEnvironment.application.getApplicationContext()); - FeatureFlagUtils.setEnabled(mContext, DATA_USAGE_V2, false); - mController = spy(new AppDataUsagePreferenceController(mContext, "test_key")); - mController.setParentFragment(mFragment); - } - - @Test - public void getAvailabilityStatus_bandwidthControlEnabled_shouldReturnAvailable() { - doReturn(true).when(mController).isBandwidthControlEnabled(); - - assertThat(mController.getAvailabilityStatus()) - .isEqualTo(BasePreferenceController.AVAILABLE); - } - - @Test - public void getAvailabilityStatus_bandwidthControlDisabled_shouldReturnDisabled() { - doReturn(false).when(mController).isBandwidthControlEnabled(); - - assertThat(mController.getAvailabilityStatus()) - .isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE); - } - - @Test - public void onResume_noSession_shouldNotRestartDataLoader() { - doReturn(mLoaderManager).when(mFragment).getLoaderManager(); - - mController.onResume(); - - verify(mLoaderManager, never()).restartLoader( - AppInfoDashboardFragment.LOADER_CHART_DATA, Bundle.EMPTY, mController); - } - - @Test - public void onResume_hasSession_shouldRestartDataLoader() { - final ConnectivityManager connectivityManager = mock(ConnectivityManager.class); - when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE)) - .thenReturn(connectivityManager); - when(connectivityManager.isNetworkSupported(anyInt())).thenReturn(true); - doReturn(mLoaderManager).when(mFragment).getLoaderManager(); - ReflectionHelpers.setField(mController, "mStatsSession", mock(INetworkStatsSession.class)); - final AppEntry appEntry = mock(AppEntry.class); - appEntry.info = new ApplicationInfo(); - when(mFragment.getAppEntry()).thenReturn(appEntry); - - mController.onResume(); - - verify(mLoaderManager).restartLoader( - eq(AppInfoDashboardFragment.LOADER_CHART_DATA), any(Bundle.class), eq(mController)); - } - - @Test - public void onPause_shouldDestroyDataLoader() { - ReflectionHelpers.setField(mController, "mStatsSession", mock(INetworkStatsSession.class)); - doReturn(mLoaderManager).when(mFragment).getLoaderManager(); - - mController.onPause(); - - verify(mLoaderManager).destroyLoader(AppInfoDashboardFragment.LOADER_CHART_DATA); - } - - @Test - public void getDetailFragmentClass_shouldReturnAppDataUsage() { - assertThat(mController.getDetailFragmentClass()).isEqualTo(AppDataUsage.class); - } - - @Test - public void updateState_shouldUpdatePreferenceSummary() { - final Preference preference = mock(Preference.class); - - mController.updateState(preference); - - verify(preference).setSummary(any()); - } -} diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceControllerV2Test.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceControllerV2Test.java index 708222ebaf9..494fa407a82 100644 --- a/tests/robotests/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceControllerV2Test.java +++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceControllerV2Test.java @@ -35,7 +35,6 @@ import android.net.ConnectivityManager; import android.os.Bundle; import com.android.settings.core.BasePreferenceController; -import com.android.settings.core.FeatureFlags; import com.android.settings.datausage.AppDataUsageV2; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settingslib.applications.ApplicationsState.AppEntry; @@ -44,7 +43,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import android.util.FeatureFlagUtils; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; @@ -69,7 +67,6 @@ public class AppDataUsagePreferenceControllerV2Test { mContext = spy(RuntimeEnvironment.application.getApplicationContext()); mController = spy(new AppDataUsagePreferenceControllerV2(mContext, "test_key")); mController.setParentFragment(mFragment); - FeatureFlagUtils.setEnabled(mContext, FeatureFlags.DATA_USAGE_V2, true); } @Test @@ -90,8 +87,8 @@ public class AppDataUsagePreferenceControllerV2Test { @Test public void onResume_notAvailable_shouldNotRestartDataLoader() { - FeatureFlagUtils.setEnabled(mContext, FeatureFlags.DATA_USAGE_V2, false); doReturn(mLoaderManager).when(mFragment).getLoaderManager(); + doReturn(BasePreferenceController.CONDITIONALLY_UNAVAILABLE).when(mController).getAvailabilityStatus(); mController.onResume(); diff --git a/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java b/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java deleted file mode 100644 index 01fa32fb85e..00000000000 --- a/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.datausage; - -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.RETURNS_DEEP_STUBS; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.pm.PackageManager; -import android.net.NetworkPolicyManager; -import android.os.Bundle; -import android.util.ArraySet; -import android.view.View; - -import androidx.preference.PreferenceManager; -import androidx.preference.PreferenceScreen; - -import com.android.settings.testutils.FakeFeatureFactory; -import com.android.settings.testutils.SettingsRobolectricTestRunner; -import com.android.settings.testutils.shadow.ShadowEntityHeaderController; -import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal; -import com.android.settings.widget.EntityHeaderController; -import com.android.settingslib.AppItem; -import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; -import com.android.settingslib.RestrictedSwitchPreference; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Answers; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; -import org.robolectric.util.ReflectionHelpers; - -@RunWith(SettingsRobolectricTestRunner.class) -@Config(shadows = {ShadowEntityHeaderController.class, ShadowRestrictedLockUtilsInternal.class}) -public class AppDataUsageTest { - - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - private EntityHeaderController mHeaderController; - @Mock - private PackageManager mPackageManager; - - private AppDataUsage mFragment; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - FakeFeatureFactory.setupForTest(); - } - - @After - public void tearDown() { - ShadowEntityHeaderController.reset(); - } - - @Test - public void bindAppHeader_allWorkApps_shouldNotShowAppInfoLink() { - ShadowEntityHeaderController.setUseMock(mHeaderController); - when(mHeaderController.setRecyclerView(any(), any())).thenReturn(mHeaderController); - when(mHeaderController.setUid(anyInt())).thenReturn(mHeaderController); - - mFragment = spy(new AppDataUsage()); - - when(mFragment.getPreferenceManager()) - .thenReturn(mock(PreferenceManager.class, RETURNS_DEEP_STUBS)); - doReturn(mock(PreferenceScreen.class)).when(mFragment).getPreferenceScreen(); - ReflectionHelpers.setField(mFragment, "mAppItem", mock(AppItem.class)); - - mFragment.onViewCreated(new View(RuntimeEnvironment.application), new Bundle()); - - verify(mHeaderController).setHasAppInfoLink(false); - } - - @Test - public void bindAppHeader_workApp_shouldSetWorkAppUid() throws - PackageManager.NameNotFoundException { - final int fakeUserId = 100; - - mFragment = spy(new AppDataUsage()); - final ArraySet packages = new ArraySet<>(); - packages.add("pkg"); - final AppItem appItem = new AppItem(123456789); - - ReflectionHelpers.setField(mFragment, "mPackageManager", mPackageManager); - ReflectionHelpers.setField(mFragment, "mAppItem", appItem); - ReflectionHelpers.setField(mFragment, "mPackages", packages); - - when(mPackageManager.getPackageUidAsUser(anyString(), anyInt())) - .thenReturn(fakeUserId); - - ShadowEntityHeaderController.setUseMock(mHeaderController); - when(mHeaderController.setRecyclerView(any(), any())).thenReturn(mHeaderController); - when(mHeaderController.setUid(fakeUserId)).thenReturn(mHeaderController); - when(mHeaderController.setHasAppInfoLink(anyBoolean())).thenReturn(mHeaderController); - - when(mFragment.getPreferenceManager()) - .thenReturn(mock(PreferenceManager.class, RETURNS_DEEP_STUBS)); - doReturn(mock(PreferenceScreen.class)).when(mFragment).getPreferenceScreen(); - - mFragment.onViewCreated(new View(RuntimeEnvironment.application), new Bundle()); - - verify(mHeaderController).setHasAppInfoLink(true); - verify(mHeaderController).setUid(fakeUserId); - } - - @Test - public void changePreference_backgroundData_shouldUpdateUI() { - mFragment = spy(new AppDataUsage()); - final AppItem appItem = new AppItem(123456789); - final RestrictedSwitchPreference pref = mock(RestrictedSwitchPreference.class); - final DataSaverBackend dataSaverBackend = mock(DataSaverBackend.class); - ReflectionHelpers.setField(mFragment, "mAppItem", appItem); - ReflectionHelpers.setField(mFragment, "mRestrictBackground", pref); - ReflectionHelpers.setField(mFragment, "mDataSaverBackend", dataSaverBackend); - - doNothing().when(mFragment).updatePrefs(); - - mFragment.onPreferenceChange(pref, true /* value */); - - verify(mFragment).updatePrefs(); - } - - @Test - public void updatePrefs_restrictedByAdmin_shouldDisablePreference() { - mFragment = spy(new AppDataUsage()); - final int testUid = 123123; - final AppItem appItem = new AppItem(testUid); - final RestrictedSwitchPreference restrictBackgroundPref - = mock(RestrictedSwitchPreference.class); - final RestrictedSwitchPreference unrestrictedDataPref - = mock(RestrictedSwitchPreference.class); - final DataSaverBackend dataSaverBackend = mock(DataSaverBackend.class); - final NetworkPolicyManager networkPolicyManager = mock(NetworkPolicyManager.class); - ReflectionHelpers.setField(mFragment, "mAppItem", appItem); - ReflectionHelpers.setField(mFragment, "mRestrictBackground", restrictBackgroundPref); - ReflectionHelpers.setField(mFragment, "mUnrestrictedData", unrestrictedDataPref); - ReflectionHelpers.setField(mFragment, "mDataSaverBackend", dataSaverBackend); - ReflectionHelpers.setField(mFragment.services, "mPolicyManager", networkPolicyManager); - - ShadowRestrictedLockUtilsInternal.setRestricted(true); - doReturn(NetworkPolicyManager.POLICY_NONE).when(networkPolicyManager) - .getUidPolicy(testUid); - - mFragment.updatePrefs(); - - verify(restrictBackgroundPref).setDisabledByAdmin(any(EnforcedAdmin.class)); - verify(unrestrictedDataPref).setDisabledByAdmin(any(EnforcedAdmin.class)); - } -} diff --git a/tests/robotests/src/com/android/settings/datausage/ChartDataUsagePreferenceTest.java b/tests/robotests/src/com/android/settings/datausage/ChartDataUsagePreferenceTest.java index ce58ae23c8d..af56029ddc0 100644 --- a/tests/robotests/src/com/android/settings/datausage/ChartDataUsagePreferenceTest.java +++ b/tests/robotests/src/com/android/settings/datausage/ChartDataUsagePreferenceTest.java @@ -18,17 +18,15 @@ package com.android.settings.datausage; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; import android.content.Context; -import android.net.NetworkStatsHistory; -import android.net.NetworkStatsHistory.Entry; import android.util.SparseIntArray; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.widget.UsageView; +import com.android.settingslib.net.NetworkCycleChartData; +import com.android.settingslib.net.NetworkCycleData; import org.junit.Before; import org.junit.Test; @@ -37,14 +35,17 @@ import org.mockito.ArgumentCaptor; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; +import java.util.ArrayList; +import java.util.List; + @RunWith(SettingsRobolectricTestRunner.class) public class ChartDataUsagePreferenceTest { - private static final long MILLIS_IN_ONE_HOUR = 60 * 60 * 1000; - private static final long MILLIS_IN_ONE_DAY = 24 * MILLIS_IN_ONE_HOUR; - private static final long TIMESTAMP_NOW = Integer.MAX_VALUE; + private static final long TIMESTAMP_START = 1521583200000L; + private static final long TIMESTAMP_END = 1521676800000L; - private NetworkStatsHistory mNetworkStatsHistory; + private List mNetworkCycleData; + private NetworkCycleChartData mNetworkCycleChartData; private Context mContext; private ChartDataUsagePreference mPreference; @@ -54,23 +55,17 @@ public class ChartDataUsagePreferenceTest { mContext = RuntimeEnvironment.application; mPreference = new ChartDataUsagePreference(mContext, null); - mNetworkStatsHistory = spy(new NetworkStatsHistory(MILLIS_IN_ONE_HOUR, 10)); - addTestNetworkEntries(); - mPreference.setNetworkStats(mNetworkStatsHistory); + createTestNetworkData(); + mPreference.setNetworkCycleData(mNetworkCycleChartData); } @Test - public void calcPoints_notStartOfData_shouldAddDataPointsOnly() { - final long start = TIMESTAMP_NOW - 20 * MILLIS_IN_ONE_DAY; - final long end = TIMESTAMP_NOW - 5 * MILLIS_IN_ONE_DAY; - mPreference.setVisibleRange(start, end); - when(mNetworkStatsHistory.getIndexAfter(start)).thenReturn(2); - when(mNetworkStatsHistory.getIndexAfter(end)).thenReturn(7); + public void calcPoints_dataAvailableFromCycleStart_shouldAddDataPointsOnly() { final UsageView usageView = mock(UsageView.class); final ArgumentCaptor pointsCaptor = ArgumentCaptor.forClass(SparseIntArray.class); - mPreference.calcPoints(usageView); + mPreference.calcPoints(usageView, mNetworkCycleData.subList(0, 5)); verify(usageView).addPath(pointsCaptor.capture()); SparseIntArray points = pointsCaptor.getValue(); @@ -79,17 +74,12 @@ public class ChartDataUsagePreferenceTest { } @Test - public void calcPoints_startOfData_shouldIndicateStartOfData() { - final long start = TIMESTAMP_NOW - 20 * MILLIS_IN_ONE_DAY; - final long end = TIMESTAMP_NOW - 5 * MILLIS_IN_ONE_DAY; - mPreference.setVisibleRange(start, end); - when(mNetworkStatsHistory.getIndexAfter(start)).thenReturn(0); - when(mNetworkStatsHistory.getIndexAfter(end)).thenReturn(5); + public void calcPoints_dataNotAvailableAtCycleStart_shouldIndicateStartOfData() { final UsageView usageView = mock(UsageView.class); final ArgumentCaptor pointsCaptor = ArgumentCaptor.forClass(SparseIntArray.class); - mPreference.calcPoints(usageView); + mPreference.calcPoints(usageView, mNetworkCycleData.subList(2, 7)); verify(usageView).addPath(pointsCaptor.capture()); SparseIntArray points = pointsCaptor.getValue(); @@ -98,35 +88,29 @@ public class ChartDataUsagePreferenceTest { assertThat(points.valueAt(1)).isEqualTo(-1); } - private void addTestNetworkEntries() { - // create 10 arbitary network data - mNetworkStatsHistory.setValues(0, createEntry(1521583200000L, 743823454L, 16574289L)); - mNetworkStatsHistory.setValues(1, createEntry(1521586800000L, 64396L, 160364L)); - mNetworkStatsHistory.setValues(2, createEntry(1521590400000L, 2832L, 5299L)); - mNetworkStatsHistory.setValues(3, createEntry(1521655200000L, 83849690L, 3558238L)); - mNetworkStatsHistory.setValues(4, createEntry(1521658800000L, 1883657L, 353330L)); - mNetworkStatsHistory.setValues(5, createEntry(1521662400000L, 705259L, 279065L)); - mNetworkStatsHistory.setValues(6, createEntry(1521666000000L, 216169L, 155302L)); - mNetworkStatsHistory.setValues(7, createEntry(1521669600000L, 6069175L, 427581L)); - mNetworkStatsHistory.setValues(8, createEntry(1521673200000L, 120389L, 110807L)); - mNetworkStatsHistory.setValues(9, createEntry(1521676800000L, 29947L, 73257L)); + private void createTestNetworkData() { + mNetworkCycleData = new ArrayList<>(); + // create 10 arbitrary network data + mNetworkCycleData.add(createNetworkCycleData(1521583200000L, 1521586800000L, 743823454L)); + mNetworkCycleData.add(createNetworkCycleData(1521586800000L, 1521590400000L, 64396L)); + mNetworkCycleData.add(createNetworkCycleData(1521590400000L, 1521655200000L, 2832L)); + mNetworkCycleData.add(createNetworkCycleData(1521655200000L, 1521658800000L, 83849690L)); + mNetworkCycleData.add(createNetworkCycleData(1521658800000L, 1521662400000L, 1883657L)); + mNetworkCycleData.add(createNetworkCycleData(1521662400000L, 1521666000000L, 705259L)); + mNetworkCycleData.add(createNetworkCycleData(1521666000000L, 1521669600000L, 216169L)); + mNetworkCycleData.add(createNetworkCycleData(1521669600000L, 1521673200000L, 6069175L)); + mNetworkCycleData.add(createNetworkCycleData(1521673200000L, 1521676800000L, 120389L)); + mNetworkCycleData.add(createNetworkCycleData(1521676800000L, 1521678800000L, 29947L)); + + final NetworkCycleChartData.Builder builder = new NetworkCycleChartData.Builder(); + builder.setUsageBuckets(mNetworkCycleData) + .setStartTime(TIMESTAMP_START) + .setEndTime(TIMESTAMP_END); + mNetworkCycleChartData = builder.build(); } - /** - * Create a network entry to be used to calculate the usage chart. In the calculation, we only - * need bucketStart, total bytes (rx + tx), and bucketDuration (which is set when we create - * the NetworkStatsHistory object). Other fields are ignored, so we don't initialize here. - * - * @param start the timestamp when this entry begins - * @param rx the total number of received bytes - * @param tx the total number of transmitted bytes - * @return the network entry with the corresponding start time and data usage - */ - private Entry createEntry(long start, long rx, long tx) { - Entry entry = new Entry(); - entry.bucketStart = start; - entry.rxBytes = rx; - entry.txBytes = tx; - return entry; + private NetworkCycleData createNetworkCycleData(long start, long end, long usage) { + return new NetworkCycleData.Builder() + .setStartTime(start).setEndTime(end).setTotalUsage(usage).build(); } } diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java deleted file mode 100644 index acd00fda0fe..00000000000 --- a/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.datausage; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.content.Intent; -import android.net.NetworkTemplate; -import android.os.Bundle; -import android.provider.Settings; - -import androidx.fragment.app.FragmentActivity; -import androidx.preference.PreferenceManager; - -import com.android.settings.testutils.FakeFeatureFactory; -import com.android.settings.testutils.SettingsRobolectricTestRunner; -import com.android.settingslib.NetworkPolicyEditor; -import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.util.ReflectionHelpers; - -@RunWith(SettingsRobolectricTestRunner.class) -public class DataUsageListTest { - - @Mock - private CellDataPreference.DataStateListener mListener; - @Mock - private TemplatePreference.NetworkServices mNetworkServices; - @Mock - private Context mContext; - private DataUsageList mDataUsageList; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - FakeFeatureFactory.setupForTest(); - mNetworkServices.mPolicyEditor = mock(NetworkPolicyEditor.class); - mDataUsageList = spy(DataUsageList.class); - - doReturn(mContext).when(mDataUsageList).getContext(); - ReflectionHelpers.setField(mDataUsageList, "mDataStateListener", mListener); - ReflectionHelpers.setField(mDataUsageList, "services", mNetworkServices); - } - - @Test - public void resumePause_shouldListenUnlistenDataStateChange() { - ReflectionHelpers.setField( - mDataUsageList, "mVisibilityLoggerMixin", mock(VisibilityLoggerMixin.class)); - ReflectionHelpers.setField( - mDataUsageList, "mPreferenceManager", mock(PreferenceManager.class)); - - mDataUsageList.onResume(); - - verify(mListener).setListener(true, mDataUsageList.mSubId, mContext); - - mDataUsageList.onPause(); - - verify(mListener).setListener(false, mDataUsageList.mSubId, mContext); - } - - @Test - public void processArgument_shouldGetTemplateFromArgument() { - final Bundle args = new Bundle(); - args.putParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE, mock(NetworkTemplate.class)); - args.putInt(DataUsageList.EXTRA_SUB_ID, 3); - mDataUsageList.setArguments(args); - - mDataUsageList.processArgument(); - - assertThat(mDataUsageList.mTemplate).isNotNull(); - assertThat(mDataUsageList.mSubId).isEqualTo(3); - } - - @Test - public void processArgument_fromIntent_shouldGetTemplateFromIntent() { - final FragmentActivity activity = mock(FragmentActivity.class); - final Intent intent = new Intent(); - intent.putExtra(Settings.EXTRA_NETWORK_TEMPLATE, mock(NetworkTemplate.class)); - intent.putExtra(Settings.EXTRA_SUB_ID, 3); - when(activity.getIntent()).thenReturn(intent); - doReturn(activity).when(mDataUsageList).getActivity(); - - mDataUsageList.processArgument(); - - assertThat(mDataUsageList.mTemplate).isNotNull(); - assertThat(mDataUsageList.mSubId).isEqualTo(3); - } -} diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceTest.java index 855e40bb948..581a7bedde1 100644 --- a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceTest.java +++ b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceTest.java @@ -513,11 +513,11 @@ public class DataUsageSummaryPreferenceTest { SubSettings.class.getName())); final Bundle expect = new Bundle(1); - expect.putParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE, + expect.putParcelable(DataUsageListV2.EXTRA_NETWORK_TEMPLATE, NetworkTemplate.buildTemplateWifiWildcard()); final Bundle actual = startedIntent .getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS); - assertThat((NetworkTemplate) actual.getParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE)) + assertThat((NetworkTemplate) actual.getParcelable(DataUsageListV2.EXTRA_NETWORK_TEMPLATE)) .isEqualTo(NetworkTemplate.buildTemplateWifiWildcard()); assertThat(startedIntent.getIntExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE_RESID, 0)) diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageUtilsTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageUtilsTest.java index 9a67df861b1..4bd584e7e91 100644 --- a/tests/robotests/src/com/android/settings/datausage/DataUsageUtilsTest.java +++ b/tests/robotests/src/com/android/settings/datausage/DataUsageUtilsTest.java @@ -29,9 +29,7 @@ import android.content.Context; import android.net.ConnectivityManager; import android.telephony.TelephonyManager; import android.util.DataUnit; -import android.util.FeatureFlagUtils; -import com.android.settings.core.FeatureFlags; import com.android.settings.testutils.SettingsRobolectricTestRunner; import org.junit.Before; @@ -102,7 +100,6 @@ public final class DataUsageUtilsTest { @Test public void hasEthernet_shouldQueryEthernetSummaryForUser() throws Exception { - FeatureFlagUtils.setEnabled(mContext, FeatureFlags.DATA_USAGE_V2, true); when(mManager.isNetworkSupported(anyInt())).thenReturn(true); final String subscriber = "TestSub"; when(mTelephonyManager.getSubscriberId()).thenReturn(subscriber);