diff --git a/src/com/android/settings/AppHeader.java b/src/com/android/settings/AppHeader.java
index 257b2f0..36026bb 100644
--- a/src/com/android/settings/AppHeader.java
+++ b/src/com/android/settings/AppHeader.java
@@ -57,7 +57,7 @@
                 tintColorRes, bar);
     }
 
-    private static View setupHeaderView(final Activity activity, Drawable icon, CharSequence label,
+    public static View setupHeaderView(final Activity activity, Drawable icon, CharSequence label,
             final String pkgName, final int uid, boolean includeAppInfo, int tintColorRes,
             View bar) {
         final ImageView appIcon = (ImageView) bar.findViewById(R.id.app_icon);
@@ -86,7 +86,7 @@
         return bar;
     }
 
-    private static boolean includeAppInfo(final Fragment fragment) {
+    public static boolean includeAppInfo(final Fragment fragment) {
         Bundle args = fragment.getArguments();
         boolean showInfo = true;
         if (args != null && args.getBoolean(EXTRA_HIDE_INFO_BUTTON, false)) {
diff --git a/src/com/android/settings/DataUsageSummary.java b/src/com/android/settings/DataUsageSummary.java
deleted file mode 100644
index c9a2999..0000000
--- a/src/com/android/settings/DataUsageSummary.java
+++ /dev/null
@@ -1,2848 +0,0 @@
-/*
- * Copyright (C) 2011 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;
-
-import android.animation.LayoutTransition;
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.app.Fragment;
-import android.app.FragmentTransaction;
-import android.app.LoaderManager.LoaderCallbacks;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.Loader;
-import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.UserInfo;
-import android.content.res.Resources;
-import android.graphics.Color;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.icu.impl.ICUResourceBundle;
-import android.icu.util.UResourceBundle;
-import android.net.ConnectivityManager;
-import android.net.INetworkPolicyManager;
-import android.net.INetworkStatsService;
-import android.net.INetworkStatsSession;
-import android.net.NetworkPolicy;
-import android.net.NetworkPolicyManager;
-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.INetworkManagementService;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.support.v7.preference.Preference;
-import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.text.format.DateUtils;
-import android.text.format.Formatter;
-import android.text.format.Time;
-import android.util.Log;
-import android.util.SparseArray;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.AdapterView.OnItemSelectedListener;
-import android.widget.ArrayAdapter;
-import android.widget.BaseAdapter;
-import android.widget.Button;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.NumberPicker;
-import android.widget.ProgressBar;
-import android.widget.Spinner;
-import android.widget.Switch;
-import android.widget.TabHost;
-import android.widget.TabHost.OnTabChangeListener;
-import android.widget.TabHost.TabContentFactory;
-import android.widget.TabHost.TabSpec;
-import android.widget.TabWidget;
-import android.widget.TextView;
-import android.widget.Toast;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.settings.dashboard.SummaryLoader;
-import com.android.settings.dashboard.conditional.BackgroundDataCondition;
-import com.android.settings.dashboard.conditional.ConditionManager;
-import com.android.settings.drawable.InsetBoundsDrawable;
-import com.android.settings.net.DataUsageMeteredSettings;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
-import com.android.settings.search.SearchIndexableRaw;
-import com.android.settings.widget.ChartDataUsageView;
-import com.android.settings.widget.ChartDataUsageView.DataUsageChartListener;
-import com.android.settings.widget.ChartNetworkSeriesView;
-import com.android.settingslib.AppItem;
-import com.android.settingslib.NetworkPolicyEditor;
-import com.android.settingslib.net.ChartData;
-import com.android.settingslib.net.ChartDataLoader;
-import com.android.settingslib.net.MobileDataController;
-import com.android.settingslib.net.SummaryForAllUidLoader;
-import com.android.settingslib.net.UidDetail;
-import com.android.settingslib.net.UidDetailProvider;
-import com.google.android.collect.Lists;
-import libcore.util.Objects;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-
-import static android.net.ConnectivityManager.TYPE_ETHERNET;
-import static android.net.ConnectivityManager.TYPE_MOBILE;
-import static android.net.ConnectivityManager.TYPE_WIFI;
-import static android.net.ConnectivityManager.TYPE_WIMAX;
-import static android.net.NetworkPolicy.LIMIT_DISABLED;
-import static android.net.NetworkPolicy.WARNING_DISABLED;
-import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
-import static android.net.NetworkPolicyManager.POLICY_NONE;
-import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
-import static android.net.NetworkPolicyManager.computeLastCycleBoundary;
-import static android.net.NetworkPolicyManager.computeNextCycleBoundary;
-import static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER;
-import static android.net.NetworkTemplate.MATCH_MOBILE_4G;
-import static android.net.NetworkTemplate.MATCH_MOBILE_ALL;
-import static android.net.NetworkTemplate.MATCH_WIFI;
-import static android.net.NetworkTemplate.buildTemplateEthernet;
-import static android.net.NetworkTemplate.buildTemplateMobile3gLower;
-import static android.net.NetworkTemplate.buildTemplateMobile4g;
-import static android.net.NetworkTemplate.buildTemplateMobileAll;
-import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
-import static android.net.TrafficStats.GB_IN_BYTES;
-import static android.net.TrafficStats.MB_IN_BYTES;
-import static android.net.TrafficStats.UID_REMOVED;
-import static android.net.TrafficStats.UID_TETHERING;
-import static android.telephony.TelephonyManager.SIM_STATE_READY;
-import static android.text.format.DateUtils.FORMAT_ABBREV_MONTH;
-import static android.text.format.DateUtils.FORMAT_SHOW_DATE;
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
-import static com.android.internal.util.Preconditions.checkNotNull;
-import static com.android.settings.Utils.prepareCustomPreferencesList;
-
-/**
- * Panel showing data usage history across various networks, including options
- * to inspect based on usage cycle and control through {@link NetworkPolicy}.
- */
-public class DataUsageSummary extends HighlightingFragment implements Indexable {
-    private static final String TAG = "DataUsage";
-    private static final boolean LOGD = false;
-
-    // TODO: remove this testing code
-    private static final boolean TEST_ANIM = false;
-    private static final boolean TEST_RADIOS = false;
-
-    private static final String TEST_RADIOS_PROP = "test.radios";
-    private static final String TEST_SUBSCRIBER_PROP = "test.subscriberid";
-
-    private static final String TAB_3G = "3g";
-    private static final String TAB_4G = "4g";
-    private static final String TAB_MOBILE = "mobile";
-    private static final String TAB_WIFI = "wifi";
-    private static final String TAB_ETHERNET = "ethernet";
-
-    private static final String TAG_CONFIRM_DATA_DISABLE = "confirmDataDisable";
-    private static final String TAG_CONFIRM_LIMIT = "confirmLimit";
-    private static final String TAG_CYCLE_EDITOR = "cycleEditor";
-    private static final String TAG_WARNING_EDITOR = "warningEditor";
-    private static final String TAG_LIMIT_EDITOR = "limitEditor";
-    private static final String TAG_CONFIRM_RESTRICT = "confirmRestrict";
-    private static final String TAG_DENIED_RESTRICT = "deniedRestrict";
-    private static final String TAG_CONFIRM_APP_RESTRICT = "confirmAppRestrict";
-    private static final String TAG_APP_DETAILS = "appDetails";
-
-    private static final String DATA_USAGE_ENABLE_MOBILE_KEY = "data_usage_enable_mobile";
-    private static final String DATA_USAGE_DISABLE_MOBILE_LIMIT_KEY =
-            "data_usage_disable_mobile_limit";
-    private static final String DATA_USAGE_CYCLE_KEY = "data_usage_cycle";
-
-    public static final String EXTRA_SHOW_APP_IMMEDIATE_PKG = "showAppImmediatePkg";
-
-    private static final int LOADER_CHART_DATA = 2;
-    private static final int LOADER_SUMMARY = 3;
-
-    private INetworkManagementService mNetworkService;
-    private INetworkStatsService mStatsService;
-    private NetworkPolicyManager mPolicyManager;
-    private TelephonyManager mTelephonyManager;
-    private SubscriptionManager mSubscriptionManager;
-    private UserManager mUserManager;
-
-    private INetworkStatsSession mStatsSession;
-
-    private static final String PREF_FILE = "data_usage";
-    private static final String PREF_SHOW_WIFI = "show_wifi";
-    private static final String PREF_SHOW_ETHERNET = "show_ethernet";
-
-    private SharedPreferences mPrefs;
-
-    private TabHost mTabHost;
-    private ViewGroup mTabsContainer;
-    private TabWidget mTabWidget;
-    private ListView mListView;
-    private ChartNetworkSeriesView mSeries;
-    private ChartNetworkSeriesView mDetailedSeries;
-    private DataUsageAdapter mAdapter;
-
-    /** Distance to inset content from sides, when needed. */
-    private int mInsetSide = 0;
-
-    private ViewGroup mHeader;
-
-    private ViewGroup mNetworkSwitchesContainer;
-    private LinearLayout mNetworkSwitches;
-    private boolean mDataEnabledSupported;
-    private Switch mDataEnabled;
-    private View mDataEnabledView;
-    private boolean mDisableAtLimitSupported;
-    private Switch mDisableAtLimit;
-    private View mDisableAtLimitView;
-
-    private View mCycleView;
-    private Spinner mCycleSpinner;
-    private CycleAdapter mCycleAdapter;
-    private TextView mCycleSummary;
-
-    private ChartDataUsageView mChart;
-    private View mDisclaimer;
-    private TextView mEmpty;
-    private View mStupidPadding;
-
-    private View mAppDetail;
-    private ImageView mAppIcon;
-    private ViewGroup mAppTitles;
-    private TextView mAppTotal;
-    private TextView mAppForeground;
-    private TextView mAppBackground;
-    private Button mAppSettings;
-
-    private LinearLayout mAppSwitches;
-    private Switch mAppRestrict;
-    private View mAppRestrictView;
-
-    private boolean mShowWifi = false;
-    private boolean mShowEthernet = false;
-
-    private NetworkTemplate mTemplate;
-    private ChartData mChartData;
-
-    private AppItem mCurrentApp = null;
-
-    private Intent mAppSettingsIntent;
-
-    private NetworkPolicyEditor mPolicyEditor;
-
-    private String mCurrentTab = null;
-    private String mIntentTab = null;
-
-    private MenuItem mMenuRestrictBackground;
-    private MenuItem mMenuShowWifi;
-    private MenuItem mMenuShowEthernet;
-    private MenuItem mMenuSimCards;
-    private MenuItem mMenuCellularNetworks;
-
-    private List<SubscriptionInfo> mSubInfoList;
-    private Map<Integer,String> mMobileTagMap;
-
-    /** Flag used to ignore listeners during binding. */
-    private boolean mBinding;
-
-    private UidDetailProvider mUidDetailProvider;
-
-    // Indicates request to show app immediately rather than list.
-    private String mShowAppImmediatePkg;
-
-    /**
-     * Local cache of data enabled for subId, used to work around delays.
-     */
-    private final Map<String, Boolean> mMobileDataEnabled = new HashMap<String, Boolean>();
-
-    @Override
-    protected int getMetricsCategory() {
-        return MetricsLogger.DATA_USAGE_SUMMARY;
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        final Context context = getActivity();
-
-        mNetworkService = INetworkManagementService.Stub.asInterface(
-                ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
-        mStatsService = INetworkStatsService.Stub.asInterface(
-                ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
-        mPolicyManager = NetworkPolicyManager.from(context);
-        mTelephonyManager = TelephonyManager.from(context);
-        mSubscriptionManager = SubscriptionManager.from(context);
-        mUserManager = UserManager.get(context);
-
-        mPrefs = getActivity().getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE);
-
-        mPolicyEditor = new NetworkPolicyEditor(mPolicyManager);
-        mPolicyEditor.read();
-
-        mSubInfoList = mSubscriptionManager.getActiveSubscriptionInfoList();
-        mMobileTagMap = initMobileTabTag(mSubInfoList);
-
-        try {
-            if (!mNetworkService.isBandwidthControlEnabled()) {
-                Log.w(TAG, "No bandwidth control; leaving");
-                getActivity().finish();
-            }
-        } catch (RemoteException e) {
-            Log.w(TAG, "No bandwidth control; leaving");
-            getActivity().finish();
-        }
-
-        try {
-            mStatsSession = mStatsService.openSession();
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-
-        mShowWifi = mPrefs.getBoolean(PREF_SHOW_WIFI, false);
-        mShowEthernet = mPrefs.getBoolean(PREF_SHOW_ETHERNET, false);
-
-        // override preferences when no mobile radio
-        if (!hasReadyMobileRadio(context)) {
-            mShowWifi = true;
-            mShowEthernet = true;
-        }
-
-        mUidDetailProvider = new UidDetailProvider(context);
-
-        Bundle arguments = getArguments();
-        if (arguments != null) {
-            mShowAppImmediatePkg = arguments.getString(EXTRA_SHOW_APP_IMMEDIATE_PKG);
-        }
-
-        setHasOptionsMenu(true);
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-            Bundle savedInstanceState) {
-
-        final Context context = inflater.getContext();
-        final View view = inflater.inflate(R.layout.data_usage_summary, container, false);
-
-
-        mTabHost = (TabHost) view.findViewById(android.R.id.tabhost);
-        mTabsContainer = (ViewGroup) view.findViewById(R.id.tabs_container);
-        mTabWidget = (TabWidget) view.findViewById(android.R.id.tabs);
-        mListView = (ListView) view.findViewById(android.R.id.list);
-
-        // decide if we need to manually inset our content, or if we should rely
-        // on parent container for inset.
-        final boolean shouldInset = mListView.getScrollBarStyle()
-                == View.SCROLLBARS_OUTSIDE_OVERLAY;
-        mInsetSide = 0;
-
-        // adjust padding around tabwidget as needed
-        prepareCustomPreferencesList(container, view, mListView, false);
-
-        mTabHost.setup();
-        mTabHost.setOnTabChangedListener(mTabListener);
-
-        mHeader = (ViewGroup) inflater.inflate(R.layout.data_usage_header, mListView, false);
-        mHeader.setClickable(true);
-
-        mListView.addHeaderView(new View(context), null, true);
-        mListView.addHeaderView(mHeader, null, true);
-        mListView.setItemsCanFocus(true);
-
-        if (mInsetSide > 0) {
-            // inset selector and divider drawables
-            insetListViewDrawables(mListView, mInsetSide);
-            mHeader.setPaddingRelative(mInsetSide, 0, mInsetSide, 0);
-        }
-
-        {
-            // bind network switches
-            mNetworkSwitchesContainer = (ViewGroup) mHeader.findViewById(
-                    R.id.network_switches_container);
-            mNetworkSwitches = (LinearLayout) mHeader.findViewById(R.id.network_switches);
-
-            mDataEnabled = new Switch(inflater.getContext());
-            mDataEnabled.setClickable(false);
-            mDataEnabled.setFocusable(false);
-            mDataEnabledView = inflatePreference(inflater, mNetworkSwitches, mDataEnabled);
-            mDataEnabledView.setTag(R.id.preference_highlight_key,
-                    DATA_USAGE_ENABLE_MOBILE_KEY);
-            mDataEnabledView.setClickable(true);
-            mDataEnabledView.setFocusable(true);
-            mDataEnabledView.setOnClickListener(mDataEnabledListener);
-            mNetworkSwitches.addView(mDataEnabledView);
-
-            mDisableAtLimit = new Switch(inflater.getContext());
-            mDisableAtLimit.setClickable(false);
-            mDisableAtLimit.setFocusable(false);
-            mDisableAtLimitView = inflatePreference(inflater, mNetworkSwitches, mDisableAtLimit);
-            mDisableAtLimitView.setTag(R.id.preference_highlight_key,
-                    DATA_USAGE_DISABLE_MOBILE_LIMIT_KEY);
-            mDisableAtLimitView.setClickable(true);
-            mDisableAtLimitView.setFocusable(true);
-            mDisableAtLimitView.setOnClickListener(mDisableAtLimitListener);
-            mNetworkSwitches.addView(mDisableAtLimitView);
-
-            mCycleView = inflater.inflate(R.layout.data_usage_cycles, mNetworkSwitches, false);
-            mCycleView.setTag(R.id.preference_highlight_key, DATA_USAGE_CYCLE_KEY);
-            mCycleSpinner = (Spinner) mCycleView.findViewById(R.id.cycles_spinner);
-            mCycleAdapter = new CycleAdapter(context);
-            mCycleSpinner.setAdapter(mCycleAdapter);
-            mCycleSpinner.setOnItemSelectedListener(mCycleListener);
-            mCycleSummary = (TextView) mCycleView.findViewById(R.id.cycle_summary);
-            mNetworkSwitches.addView(mCycleView);
-            mSeries = (ChartNetworkSeriesView)view.findViewById(R.id.series);
-            mDetailedSeries = (ChartNetworkSeriesView)view.findViewById(R.id.detail_series);
-        }
-
-        mChart = (ChartDataUsageView) mHeader.findViewById(R.id.chart);
-        mChart.setListener(mChartListener);
-        mChart.bindNetworkPolicy(null);
-
-        {
-            // bind app detail controls
-            mAppDetail = mHeader.findViewById(R.id.app_detail);
-            mAppIcon = (ImageView) mAppDetail.findViewById(R.id.app_icon);
-            mAppTitles = (ViewGroup) mAppDetail.findViewById(R.id.app_titles);
-            mAppForeground = (TextView) mAppDetail.findViewById(R.id.app_foreground);
-            mAppBackground = (TextView) mAppDetail.findViewById(R.id.app_background);
-            mAppSwitches = (LinearLayout) mAppDetail.findViewById(R.id.app_switches);
-
-            mAppSettings = (Button) mAppDetail.findViewById(R.id.app_settings);
-
-            mAppRestrict = new Switch(inflater.getContext());
-            mAppRestrict.setClickable(false);
-            mAppRestrict.setFocusable(false);
-            mAppRestrictView = inflatePreference(inflater, mAppSwitches, mAppRestrict);
-            mAppRestrictView.setClickable(true);
-            mAppRestrictView.setFocusable(true);
-            mAppRestrictView.setOnClickListener(mAppRestrictListener);
-            mAppSwitches.addView(mAppRestrictView);
-        }
-
-        mDisclaimer = mHeader.findViewById(R.id.disclaimer);
-        mEmpty = (TextView) mHeader.findViewById(android.R.id.empty);
-        mStupidPadding = mHeader.findViewById(R.id.stupid_padding);
-
-        final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
-        mAdapter = new DataUsageAdapter(um, mUidDetailProvider, mInsetSide);
-        mListView.setOnItemClickListener(mListListener);
-        mListView.setAdapter(mAdapter);
-
-        showRequestedAppIfNeeded(view);
-
-        return view;
-    }
-
-    private void showRequestedAppIfNeeded(View rootView) {
-        if (mShowAppImmediatePkg == null) {
-            return;
-        }
-        try {
-            int uid = getActivity().getPackageManager().getPackageUidAsUser(mShowAppImmediatePkg,
-                UserHandle.myUserId());
-            AppItem app = new AppItem(uid);
-            app.addUid(uid);
-
-            final UidDetail detail = mUidDetailProvider.getUidDetail(app.key, true);
-            // When we are going straight to an app then we are coming from App Info and want
-            // a header at the top.
-            FrameLayout pinnedHeader = (FrameLayout) rootView.findViewById(R.id.pinned_header);
-            AppHeader.createAppHeader(getActivity(), detail.icon, detail.label,
-                    mShowAppImmediatePkg, uid, pinnedHeader);
-            AppDetailsFragment.show(DataUsageSummary.this, app, detail.label, false);
-        } catch (NameNotFoundException e) {
-            Log.w(TAG, "Could not find " + mShowAppImmediatePkg, e);
-            Toast.makeText(getActivity(), getString(R.string.unknown_app), Toast.LENGTH_LONG)
-                    .show();
-            getActivity().finish();
-        }
-    }
-
-    @Override
-    public void onViewStateRestored(Bundle savedInstanceState) {
-        super.onViewStateRestored(savedInstanceState);
-
-        // pick default tab based on incoming intent
-        final Intent intent = getActivity().getIntent();
-        mIntentTab = computeTabFromIntent(intent);
-
-        // this kicks off chain reaction which creates tabs, binds the body to
-        // selected network, and binds chart, cycles and detail list.
-        updateTabs();
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-
-        getView().post(new Runnable() {
-            @Override
-            public void run() {
-                highlightViewIfNeeded();
-            }
-        });
-
-        // kick off background task to update stats
-        new AsyncTask<Void, Void, Void>() {
-            @Override
-            protected Void doInBackground(Void... params) {
-                try {
-                    // wait a few seconds before kicking off
-                    Thread.sleep(2 * DateUtils.SECOND_IN_MILLIS);
-                    mStatsService.forceUpdate();
-                } catch (InterruptedException e) {
-                } catch (RemoteException e) {
-                }
-                return null;
-            }
-
-            @Override
-            protected void onPostExecute(Void result) {
-                if (isAdded()) {
-                    updateBody();
-                }
-            }
-        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-    }
-
-    @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        inflater.inflate(R.menu.data_usage, menu);
-    }
-
-    @Override
-    public void onPrepareOptionsMenu(Menu menu) {
-        final Context context = getContext();
-        if (context == null) return;
-        final boolean appDetailMode = isAppDetailMode();
-        final boolean isAdmin = mUserManager.isAdminUser();
-
-        mMenuShowWifi = menu.findItem(R.id.data_usage_menu_show_wifi);
-        if (hasWifiRadio(context) && hasReadyMobileRadio(context)) {
-            mMenuShowWifi.setVisible(!appDetailMode);
-        } else {
-            mMenuShowWifi.setVisible(false);
-        }
-
-        mMenuShowEthernet = menu.findItem(R.id.data_usage_menu_show_ethernet);
-        if (hasEthernet(context) && hasReadyMobileRadio(context)) {
-            mMenuShowEthernet.setVisible(!appDetailMode);
-        } else {
-            mMenuShowEthernet.setVisible(false);
-        }
-
-        mMenuRestrictBackground = menu.findItem(R.id.data_usage_menu_restrict_background);
-        mMenuRestrictBackground.setVisible(
-                hasReadyMobileRadio(context) && isAdmin && !appDetailMode);
-
-        final MenuItem metered = menu.findItem(R.id.data_usage_menu_metered);
-        if (hasReadyMobileRadio(context) || hasWifiRadio(context)) {
-            metered.setVisible(!appDetailMode);
-        } else {
-            metered.setVisible(false);
-        }
-
-        // TODO: show when multiple sims available
-        mMenuSimCards = menu.findItem(R.id.data_usage_menu_sim_cards);
-        mMenuSimCards.setVisible(false);
-
-        mMenuCellularNetworks = menu.findItem(R.id.data_usage_menu_cellular_networks);
-        mMenuCellularNetworks.setVisible(hasReadyMobileRadio(context)
-                && !appDetailMode && isAdmin);
-
-        final MenuItem help = menu.findItem(R.id.data_usage_menu_help);
-        String helpUrl;
-        if (!TextUtils.isEmpty(helpUrl = getResources().getString(R.string.help_url_data_usage))) {
-            HelpUtils.prepareHelpMenuItem(getActivity(), help, helpUrl, getClass().getName());
-        } else {
-            help.setVisible(false);
-        }
-
-        updateMenuTitles();
-    }
-
-    private void updateMenuTitles() {
-        if (mPolicyManager.getRestrictBackground()) {
-            mMenuRestrictBackground.setTitle(R.string.data_usage_menu_allow_background);
-        } else {
-            mMenuRestrictBackground.setTitle(R.string.data_usage_menu_restrict_background);
-        }
-
-        if (mShowWifi) {
-            mMenuShowWifi.setTitle(R.string.data_usage_menu_hide_wifi);
-        } else {
-            mMenuShowWifi.setTitle(R.string.data_usage_menu_show_wifi);
-        }
-
-        if (mShowEthernet) {
-            mMenuShowEthernet.setTitle(R.string.data_usage_menu_hide_ethernet);
-        } else {
-            mMenuShowEthernet.setTitle(R.string.data_usage_menu_show_ethernet);
-        }
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case R.id.data_usage_menu_restrict_background: {
-                final boolean restrictBackground = !mPolicyManager.getRestrictBackground();
-                if (restrictBackground) {
-                    ConfirmRestrictFragment.show(this);
-                } else {
-                    // no confirmation to drop restriction
-                    setRestrictBackground(false);
-                }
-                return true;
-            }
-            case R.id.data_usage_menu_show_wifi: {
-                mShowWifi = !mShowWifi;
-                mPrefs.edit().putBoolean(PREF_SHOW_WIFI, mShowWifi).apply();
-                updateMenuTitles();
-                updateTabs();
-                return true;
-            }
-            case R.id.data_usage_menu_show_ethernet: {
-                mShowEthernet = !mShowEthernet;
-                mPrefs.edit().putBoolean(PREF_SHOW_ETHERNET, mShowEthernet).apply();
-                updateMenuTitles();
-                updateTabs();
-                return true;
-            }
-            case R.id.data_usage_menu_sim_cards: {
-                // TODO: hook up to sim cards
-                return true;
-            }
-            case R.id.data_usage_menu_cellular_networks: {
-                final Intent intent = new Intent(Intent.ACTION_MAIN);
-                intent.setComponent(new ComponentName("com.android.phone",
-                        "com.android.phone.MobileNetworkSettings"));
-                startActivity(intent);
-                return true;
-            }
-            case R.id.data_usage_menu_metered: {
-                final SettingsActivity sa = (SettingsActivity) getActivity();
-                sa.startPreferencePanel(DataUsageMeteredSettings.class.getCanonicalName(), null,
-                        R.string.data_usage_metered_title, null, this, 0);
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public void onDestroy() {
-        mDataEnabledView = null;
-        mDisableAtLimitView = null;
-
-        mUidDetailProvider.clearCache();
-        mUidDetailProvider = null;
-
-        TrafficStats.closeQuietly(mStatsSession);
-
-        super.onDestroy();
-    }
-
-    /**
-     * Build and assign {@link LayoutTransition} to various containers. Should
-     * only be assigned after initial layout is complete.
-     */
-    private void ensureLayoutTransitions() {
-        if (mShowAppImmediatePkg != null) {
-            // If we are skipping right to showing an app, we don't care about transitions.
-            return;
-        }
-        // skip when already setup
-        if (mChart.getLayoutTransition() != null) return;
-
-        mTabsContainer.setLayoutTransition(buildLayoutTransition());
-        mHeader.setLayoutTransition(buildLayoutTransition());
-        mNetworkSwitchesContainer.setLayoutTransition(buildLayoutTransition());
-
-        final LayoutTransition chartTransition = buildLayoutTransition();
-        chartTransition.disableTransitionType(LayoutTransition.APPEARING);
-        chartTransition.disableTransitionType(LayoutTransition.DISAPPEARING);
-        mChart.setLayoutTransition(chartTransition);
-    }
-
-    private static LayoutTransition buildLayoutTransition() {
-        final LayoutTransition transition = new LayoutTransition();
-        if (TEST_ANIM) {
-            transition.setDuration(1500);
-        }
-        transition.setAnimateParentHierarchy(false);
-        return transition;
-    }
-
-    /**
-     * Rebuild all tabs based on {@link NetworkPolicyEditor} and
-     * {@link #mShowWifi}, hiding the tabs entirely when applicable. Selects
-     * first tab, and kicks off a full rebind of body contents.
-     */
-    private void updateTabs() {
-        final Context context = getActivity();
-        mTabHost.clearAllTabs();
-
-        int simCount = mTelephonyManager.getSimCount();
-
-        List<SubscriptionInfo> sirs = mSubscriptionManager.getActiveSubscriptionInfoList();
-        if (sirs != null) {
-            for (SubscriptionInfo sir : sirs) {
-                addMobileTab(context, sir, (simCount > 1));
-            }
-        }
-
-        if (mShowWifi && hasWifiRadio(context)) {
-            mTabHost.addTab(buildTabSpec(TAB_WIFI, R.string.data_usage_tab_wifi));
-        }
-
-        if (mShowEthernet && hasEthernet(context)) {
-            mTabHost.addTab(buildTabSpec(TAB_ETHERNET, R.string.data_usage_tab_ethernet));
-        }
-
-        final boolean noTabs = mTabWidget.getTabCount() == 0;
-        final boolean multipleTabs = mTabWidget.getTabCount() > 1;
-        mTabWidget.setVisibility(multipleTabs ? View.VISIBLE : View.GONE);
-        if (mIntentTab != null) {
-            if (Objects.equal(mIntentTab, mTabHost.getCurrentTabTag())) {
-                // already hit updateBody() when added; ignore
-                updateBody();
-            } else {
-                mTabHost.setCurrentTabByTag(mIntentTab);
-            }
-            mIntentTab = null;
-        } else if (noTabs) {
-            // no usable tabs, so hide body
-            updateBody();
-        } else {
-            // already hit updateBody() when added; ignore
-        }
-    }
-
-    /**
-     * Factory that provide empty {@link View} to make {@link TabHost} happy.
-     */
-    private TabContentFactory mEmptyTabContent = new TabContentFactory() {
-        @Override
-        public View createTabContent(String tag) {
-            return new View(mTabHost.getContext());
-        }
-    };
-
-    /**
-     * Build {@link TabSpec} with thin indicator, and empty content.
-     */
-    private TabSpec buildTabSpec(String tag, int titleRes) {
-        return mTabHost.newTabSpec(tag).setIndicator(getText(titleRes)).setContent(
-                mEmptyTabContent);
-    }
-
-    /**
-     * Build {@link TabSpec} with thin indicator, and empty content.
-     */
-    private TabSpec buildTabSpec(String tag, CharSequence title) {
-        return mTabHost.newTabSpec(tag).setIndicator(title).setContent(
-                mEmptyTabContent);
-    }
-
-
-    private OnTabChangeListener mTabListener = new OnTabChangeListener() {
-        @Override
-        public void onTabChanged(String tabId) {
-            // user changed tab; update body
-            updateBody();
-        }
-    };
-
-    /**
-     * Update body content based on current tab. Loads
-     * {@link NetworkStatsHistory} and {@link NetworkPolicy} from system, and
-     * binds them to visible controls.
-     */
-    private void updateBody() {
-        mBinding = true;
-        if (!isAdded()) return;
-
-        final Context context = getActivity();
-        final String currentTab = mTabHost.getCurrentTabTag();
-        final boolean isAdmin = mUserManager.isAdminUser();
-
-        if (currentTab == null) {
-            Log.w(TAG, "no tab selected; hiding body");
-            mListView.setVisibility(View.GONE);
-            return;
-        } else {
-            mListView.setVisibility(View.VISIBLE);
-        }
-
-        mCurrentTab = currentTab;
-
-        if (LOGD) Log.d(TAG, "updateBody() with currentTab=" + currentTab);
-
-        mDataEnabledSupported = isAdmin;
-        mDisableAtLimitSupported = true;
-
-        // TODO: remove mobile tabs when SIM isn't ready probably by
-        // TODO: using SubscriptionManager.getActiveSubscriptionInfoList.
-        if (LOGD) Log.d(TAG, "updateBody() isMobileTab=" + isMobileTab(currentTab));
-
-        if (isMobileTab(currentTab)) {
-            if (LOGD) Log.d(TAG, "updateBody() mobile tab");
-            setPreferenceTitle(mDataEnabledView, R.string.data_usage_enable_mobile);
-            setPreferenceTitle(mDisableAtLimitView, R.string.data_usage_disable_mobile_limit);
-            mDataEnabledSupported = isMobileDataAvailable(getSubId(currentTab));
-
-            // Match mobile traffic for this subscriber, but normalize it to
-            // catch any other merged subscribers.
-            mTemplate = buildTemplateMobileAll(
-                    getActiveSubscriberId(context, getSubId(currentTab)));
-            mTemplate = NetworkTemplate.normalize(mTemplate,
-                    mTelephonyManager.getMergedSubscriberIds());
-
-        } else if (TAB_3G.equals(currentTab)) {
-            if (LOGD) Log.d(TAG, "updateBody() 3g tab");
-            setPreferenceTitle(mDataEnabledView, R.string.data_usage_enable_3g);
-            setPreferenceTitle(mDisableAtLimitView, R.string.data_usage_disable_3g_limit);
-            // TODO: bind mDataEnabled to 3G radio state
-            mTemplate = buildTemplateMobile3gLower(getActiveSubscriberId(context));
-
-        } else if (TAB_4G.equals(currentTab)) {
-            if (LOGD) Log.d(TAG, "updateBody() 4g tab");
-            setPreferenceTitle(mDataEnabledView, R.string.data_usage_enable_4g);
-            setPreferenceTitle(mDisableAtLimitView, R.string.data_usage_disable_4g_limit);
-            // TODO: bind mDataEnabled to 4G radio state
-            mTemplate = buildTemplateMobile4g(getActiveSubscriberId(context));
-
-        } else if (TAB_WIFI.equals(currentTab)) {
-            // wifi doesn't have any controls
-            if (LOGD) Log.d(TAG, "updateBody() wifi tab");
-            mDataEnabledSupported = false;
-            mDisableAtLimitSupported = false;
-            mTemplate = buildTemplateWifiWildcard();
-
-        } else if (TAB_ETHERNET.equals(currentTab)) {
-            // ethernet doesn't have any controls
-            if (LOGD) Log.d(TAG, "updateBody() ethernet tab");
-            mDataEnabledSupported = false;
-            mDisableAtLimitSupported = false;
-            mTemplate = buildTemplateEthernet();
-
-        } else {
-            if (LOGD) Log.d(TAG, "updateBody() unknown tab");
-            throw new IllegalStateException("unknown tab: " + currentTab);
-        }
-
-        mPolicyEditor.read();
-        final NetworkPolicy policy = mPolicyEditor.getPolicy(mTemplate);
-        if (policy != null) {
-            final long currentTime = System.currentTimeMillis();
-            final long start = computeLastCycleBoundary(currentTime, policy);
-            final long end = currentTime;
-            long totalBytes = 0;
-
-            try {
-                totalBytes = mStatsService.getNetworkTotalBytes(policy.template, start, end);
-            } catch (RuntimeException e) {
-            } catch (RemoteException e) {
-            }
-
-            if (policy.isOverLimit(totalBytes) && policy.lastLimitSnooze < start) {
-                setPreferenceSummary(mDataEnabledView,
-                        getString(R.string.data_usage_cellular_data_summary));
-            } else {
-                final TextView summary = (TextView) mDataEnabledView
-                        .findViewById(android.R.id.summary);
-                summary.setVisibility(View.GONE);
-            }
-        }
-
-        // 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,
-                ChartDataLoader.buildArgs(mTemplate, mCurrentApp), mChartDataCallbacks);
-
-        // detail mode can change visible menus, invalidate
-        getActivity().invalidateOptionsMenu();
-
-        mBinding = false;
-
-        int seriesColor = context.getColor(R.color.sim_noitification);
-        if (mCurrentTab != null && mCurrentTab.length() > TAB_MOBILE.length() ){
-            final int slotId = Integer.parseInt(mCurrentTab.substring(TAB_MOBILE.length(),
-                    mCurrentTab.length()));
-            final SubscriptionInfo sir = mSubscriptionManager
-                    .getActiveSubscriptionInfoForSimSlotIndex(slotId);
-
-            if (sir != null) {
-                seriesColor = sir.getIconTint();
-            }
-        }
-
-        final int secondaryColor = Color.argb(127, Color.red(seriesColor), Color.green(seriesColor),
-                Color.blue(seriesColor));
-        mSeries.setChartColor(Color.BLACK, seriesColor, secondaryColor);
-        mDetailedSeries.setChartColor(Color.BLACK, seriesColor, secondaryColor);
-    }
-
-    private boolean isAppDetailMode() {
-        return mCurrentApp != null;
-    }
-
-    /**
-     * Update UID details panels to match {@link #mCurrentApp}, showing or
-     * hiding them depending on {@link #isAppDetailMode()}.
-     */
-    private void updateAppDetail() {
-        final Context context = getActivity();
-        final PackageManager pm = context.getPackageManager();
-        final LayoutInflater inflater = getActivity().getLayoutInflater();
-
-        if (isAppDetailMode()) {
-            mAppDetail.setVisibility(View.VISIBLE);
-            mCycleAdapter.setChangeVisible(false);
-            mChart.setVisibility(View.GONE);
-        } else {
-            mAppDetail.setVisibility(View.GONE);
-            mCycleAdapter.setChangeVisible(true);
-            mChart.setVisibility(View.VISIBLE);
-
-            // hide detail stats when not in detail mode
-            mChart.bindDetailNetworkStats(null);
-            return;
-        }
-
-        // remove warning/limit sweeps while in detail mode
-        mChart.bindNetworkPolicy(null);
-
-        // show icon and all labels appearing under this app
-        final int uid = mCurrentApp.key;
-        final UidDetail detail = mUidDetailProvider.getUidDetail(uid, true);
-        mAppIcon.setImageDrawable(detail.icon);
-
-        mAppTitles.removeAllViews();
-
-        View title = null;
-        if (detail.detailLabels != null) {
-            final int n = detail.detailLabels.length;
-            for (int i = 0; i < n; ++i) {
-                CharSequence label = detail.detailLabels[i];
-                CharSequence contentDescription = detail.detailContentDescriptions[i];
-                title = inflater.inflate(R.layout.data_usage_app_title, mAppTitles, false);
-                TextView appTitle = (TextView) title.findViewById(R.id.app_title);
-                appTitle.setText(label);
-                appTitle.setContentDescription(contentDescription);
-                mAppTitles.addView(title);
-            }
-        } else {
-            title = inflater.inflate(R.layout.data_usage_app_title, mAppTitles, false);
-            TextView appTitle = (TextView) title.findViewById(R.id.app_title);
-            appTitle.setText(detail.label);
-            appTitle.setContentDescription(detail.contentDescription);
-            mAppTitles.addView(title);
-        }
-
-        // Remember last slot for summary
-        if (title != null) {
-            mAppTotal = (TextView) title.findViewById(R.id.app_summary);
-        } else {
-            mAppTotal = null;
-        }
-
-        // enable settings button when package provides it
-        final String[] packageNames = pm.getPackagesForUid(uid);
-        if (packageNames != null && packageNames.length > 0) {
-            mAppSettingsIntent = new Intent(Intent.ACTION_MANAGE_NETWORK_USAGE);
-            mAppSettingsIntent.addCategory(Intent.CATEGORY_DEFAULT);
-
-            // Search for match across all packages
-            boolean matchFound = false;
-            for (String packageName : packageNames) {
-                mAppSettingsIntent.setPackage(packageName);
-                if (pm.resolveActivity(mAppSettingsIntent, 0) != null) {
-                    matchFound = true;
-                    break;
-                }
-            }
-
-            mAppSettings.setOnClickListener(new OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    if (!isAdded()) {
-                        return;
-                    }
-
-                    // TODO: target towards entire UID instead of just first package
-                    getActivity().startActivityAsUser(mAppSettingsIntent,
-                            new UserHandle(UserHandle.getUserId(uid)));
-                }
-            });
-            mAppSettings.setEnabled(matchFound);
-            mAppSettings.setVisibility(View.VISIBLE);
-
-        } else {
-            mAppSettingsIntent = null;
-            mAppSettings.setOnClickListener(null);
-            mAppSettings.setVisibility(View.GONE);
-        }
-
-        updateDetailData();
-
-        if (UserHandle.isApp(uid) && !mPolicyManager.getRestrictBackground()
-                && isBandwidthControlEnabled() && hasReadyMobileRadio(context)) {
-            setPreferenceTitle(mAppRestrictView, R.string.data_usage_app_restrict_background);
-            setPreferenceSummary(mAppRestrictView,
-                    getString(R.string.data_usage_app_restrict_background_summary));
-
-            mAppRestrictView.setVisibility(View.VISIBLE);
-            mAppRestrict.setChecked(getAppRestrictBackground());
-
-        } else {
-            mAppRestrictView.setVisibility(View.GONE);
-        }
-    }
-
-    private void setPolicyWarningBytes(long warningBytes) {
-        if (LOGD) Log.d(TAG, "setPolicyWarningBytes()");
-        mPolicyEditor.setPolicyWarningBytes(mTemplate, warningBytes);
-        updatePolicy(false);
-    }
-
-    private void setPolicyLimitBytes(long limitBytes) {
-        if (LOGD) Log.d(TAG, "setPolicyLimitBytes()");
-        mPolicyEditor.setPolicyLimitBytes(mTemplate, limitBytes);
-        updatePolicy(false);
-    }
-
-    private boolean isMobileDataEnabled(int subId) {
-        if (LOGD) Log.d(TAG, "isMobileDataEnabled:+ subId=" + subId);
-        boolean isEnable = false;
-        if (mMobileDataEnabled.get(String.valueOf(subId)) != null) {
-            //TODO: deprecate and remove this once enabled flag is on policy
-            //Multiple Subscriptions, the value need to be reseted
-            isEnable = mMobileDataEnabled.get(String.valueOf(subId)).booleanValue();
-            if (LOGD) {
-                Log.d(TAG, "isMobileDataEnabled: != null, subId=" + subId
-                        + " isEnable=" + isEnable);
-            }
-            mMobileDataEnabled.put(String.valueOf(subId), null);
-        } else {
-            // SUB SELECT
-            isEnable = mTelephonyManager.getDataEnabled(subId);
-            if (LOGD) {
-                Log.d(TAG, "isMobileDataEnabled: == null, subId=" + subId
-                        + " isEnable=" + isEnable);
-            }
-        }
-        return isEnable;
-    }
-
-    private void setMobileDataEnabled(int subId, boolean enabled) {
-        if (LOGD) Log.d(TAG, "setMobileDataEnabled()");
-        mTelephonyManager.setDataEnabled(subId, enabled);
-        mMobileDataEnabled.put(String.valueOf(subId), enabled);
-        updatePolicy(false);
-    }
-
-    private boolean isNetworkPolicyModifiable(NetworkPolicy policy) {
-        return policy != null && isBandwidthControlEnabled() && mDataEnabled.isChecked()
-                && mUserManager.isAdminUser();
-    }
-
-    private boolean isBandwidthControlEnabled() {
-        try {
-            return mNetworkService.isBandwidthControlEnabled();
-        } catch (RemoteException e) {
-            Log.w(TAG, "problem talking with INetworkManagementService: " + e);
-            return false;
-        }
-    }
-
-    public void setRestrictBackground(boolean restrictBackground) {
-        mPolicyManager.setRestrictBackground(restrictBackground);
-        updateMenuTitles();
-        ConditionManager.get(getContext()).getCondition(BackgroundDataCondition.class)
-                .refreshState();
-    }
-
-    private boolean getAppRestrictBackground() {
-        final int uid = mCurrentApp.key;
-        final int uidPolicy = mPolicyManager.getUidPolicy(uid);
-        return (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0;
-    }
-
-    private void setAppRestrictBackground(boolean restrictBackground) {
-        if (LOGD) Log.d(TAG, "setAppRestrictBackground()");
-        final int uid = mCurrentApp.key;
-        mPolicyManager.setUidPolicy(
-                uid, restrictBackground ? POLICY_REJECT_METERED_BACKGROUND : POLICY_NONE);
-        mAppRestrict.setChecked(restrictBackground);
-    }
-
-    /**
-     * Update chart sweeps and cycle list to reflect {@link NetworkPolicy} for
-     * current {@link #mTemplate}.
-     */
-    private void updatePolicy(boolean refreshCycle) {
-        boolean dataEnabledVisible = mDataEnabledSupported;
-        boolean disableAtLimitVisible = mDisableAtLimitSupported;
-
-        if (isAppDetailMode()) {
-            dataEnabledVisible = false;
-            disableAtLimitVisible = false;
-        }
-
-        // TODO: move enabled state directly into policy
-        if (isMobileTab(mCurrentTab)) {
-            mBinding = true;
-            mDataEnabled.setChecked(isMobileDataEnabled(getSubId(mCurrentTab)));
-            mBinding = false;
-        }
-
-        final NetworkPolicy policy = mPolicyEditor.getPolicy(mTemplate);
-        //SUB SELECT
-        if (isNetworkPolicyModifiable(policy) && isMobileDataAvailable(getSubId(mCurrentTab))) {
-            mDisableAtLimit.setChecked(policy != null && policy.limitBytes != LIMIT_DISABLED);
-            if (!isAppDetailMode()) {
-                mChart.bindNetworkPolicy(policy);
-            }
-
-        } else {
-            // controls are disabled; don't bind warning/limit sweeps
-            disableAtLimitVisible = false;
-            mChart.bindNetworkPolicy(null);
-        }
-
-        mDataEnabledView.setVisibility(dataEnabledVisible ? View.VISIBLE : View.GONE);
-        mDisableAtLimitView.setVisibility(disableAtLimitVisible ? View.VISIBLE : View.GONE);
-
-        if (refreshCycle) {
-            // generate cycle list based on policy and available history
-            updateCycleList(policy);
-        }
-    }
-
-    /**
-     * Rebuild {@link #mCycleAdapter} based on {@link NetworkPolicy#cycleDay}
-     * and available {@link NetworkStatsHistory} data. Always selects the newest
-     * item, updating the inspection range on {@link #mChart}.
-     */
-    private void updateCycleList(NetworkPolicy policy) {
-        // stash away currently selected cycle to try restoring below
-        final CycleItem previousItem = (CycleItem) mCycleSpinner.getSelectedItem();
-        mCycleAdapter.clear();
-
-        final Context context = mCycleSpinner.getContext();
-        NetworkStatsHistory.Entry entry = null;
-
-        long historyStart = Long.MAX_VALUE;
-        long historyEnd = Long.MIN_VALUE;
-        if (mChartData != null) {
-            historyStart = mChartData.network.getStart();
-            historyEnd = mChartData.network.getEnd();
-        }
-
-        final long now = System.currentTimeMillis();
-        if (historyStart == Long.MAX_VALUE) historyStart = now;
-        if (historyEnd == Long.MIN_VALUE) historyEnd = now + 1;
-
-        boolean hasCycles = false;
-        if (policy != null) {
-            // find the next cycle boundary
-            long cycleEnd = computeNextCycleBoundary(historyEnd, policy);
-
-            // walk backwards, generating all valid cycle ranges
-            while (cycleEnd > historyStart) {
-                final long cycleStart = computeLastCycleBoundary(cycleEnd, policy);
-                Log.d(TAG, "generating cs=" + cycleStart + " to ce=" + cycleEnd + " waiting for hs="
-                        + historyStart);
-
-                final boolean includeCycle;
-                if (mChartData != null) {
-                    entry = mChartData.network.getValues(cycleStart, cycleEnd, entry);
-                    includeCycle = (entry.rxBytes + entry.txBytes) > 0;
-                } else {
-                    includeCycle = true;
-                }
-
-                if (includeCycle) {
-                    mCycleAdapter.add(new CycleItem(context, cycleStart, cycleEnd));
-                    hasCycles = true;
-                }
-                cycleEnd = cycleStart;
-            }
-
-            // one last cycle entry to modify policy cycle day
-            mCycleAdapter.setChangePossible(isNetworkPolicyModifiable(policy));
-        }
-
-        if (!hasCycles) {
-            // no policy defined cycles; show entry for each four-week period
-            long cycleEnd = historyEnd;
-            while (cycleEnd > historyStart) {
-                final long cycleStart = cycleEnd - (DateUtils.WEEK_IN_MILLIS * 4);
-
-                final boolean includeCycle;
-                if (mChartData != null) {
-                    entry = mChartData.network.getValues(cycleStart, cycleEnd, entry);
-                    includeCycle = (entry.rxBytes + entry.txBytes) > 0;
-                } else {
-                    includeCycle = true;
-                }
-
-                if (includeCycle) {
-                    mCycleAdapter.add(new CycleItem(context, cycleStart, cycleEnd));
-                }
-                cycleEnd = cycleStart;
-            }
-
-            mCycleAdapter.setChangePossible(false);
-        }
-
-        // force pick the current cycle (first item)
-        if (mCycleAdapter.getCount() > 0) {
-            final int position = mCycleAdapter.findNearestPosition(previousItem);
-            mCycleSpinner.setSelection(position);
-
-            // only force-update cycle when changed; skipping preserves any
-            // user-defined inspection region.
-            final CycleItem selectedItem = mCycleAdapter.getItem(position);
-            if (!Objects.equal(selectedItem, previousItem)) {
-                mCycleListener.onItemSelected(mCycleSpinner, null, position, 0);
-            } else {
-                // but still kick off loader for detailed list
-                updateDetailData();
-            }
-        } else {
-            updateDetailData();
-        }
-    }
-
-    private void disableDataForOtherSubscriptions(SubscriptionInfo currentSir) {
-        if (mSubInfoList != null) {
-            for (SubscriptionInfo subInfo : mSubInfoList) {
-                if (subInfo.getSubscriptionId() != currentSir.getSubscriptionId()) {
-                    setMobileDataEnabled(subInfo.getSubscriptionId(), false);
-                }
-            }
-        }
-    }
-
-    private View.OnClickListener mDataEnabledListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            if (mBinding) return;
-
-            final boolean enabled = !mDataEnabled.isChecked();
-            final String currentTab = mCurrentTab;
-            if (isMobileTab(currentTab)) {
-                MetricsLogger.action(getContext(), MetricsLogger.ACTION_CELL_DATA_TOGGLE, enabled);
-                if (enabled) {
-                    // If we are showing the Sim Card tile then we are a Multi-Sim device.
-                    if (Utils.showSimCardTile(getActivity())) {
-                        handleMultiSimDataDialog();
-                    } else {
-                        setMobileDataEnabled(getSubId(currentTab), true);
-                    }
-                } else {
-                    // disabling data; show confirmation dialog which eventually
-                    // calls setMobileDataEnabled() once user confirms.
-                    ConfirmDataDisableFragment.show(DataUsageSummary.this, getSubId(mCurrentTab));
-                }
-            }
-
-            updatePolicy(false);
-        }
-    };
-
-    private void handleMultiSimDataDialog() {
-        final Context context = getActivity();
-        final SubscriptionInfo currentSir = getCurrentTabSubInfo(context);
-
-        //If sim has not loaded after toggling data switch, return.
-        if (currentSir == null) {
-            return;
-        }
-
-        final SubscriptionInfo nextSir = mSubscriptionManager.getDefaultDataSubscriptionInfo();
-
-        // If the device is single SIM or is enabling data on the active data SIM then forgo
-        // the pop-up.
-        if (!Utils.showSimCardTile(context) ||
-                (nextSir != null && currentSir != null &&
-                currentSir.getSubscriptionId() == nextSir.getSubscriptionId())) {
-            setMobileDataEnabled(currentSir.getSubscriptionId(), true);
-            if (nextSir != null && currentSir != null &&
-                currentSir.getSubscriptionId() == nextSir.getSubscriptionId()) {
-                disableDataForOtherSubscriptions(currentSir);
-            }
-            updateBody();
-            return;
-        }
-
-        final String previousName = (nextSir == null)
-            ? context.getResources().getString(R.string.sim_selection_required_pref)
-            : nextSir.getDisplayName().toString();
-
-        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-
-        builder.setTitle(R.string.sim_change_data_title);
-        builder.setMessage(getActivity().getResources().getString(R.string.sim_change_data_message,
-                    currentSir.getDisplayName(), previousName));
-
-        builder.setPositiveButton(R.string.okay, new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(DialogInterface dialog, int id) {
-                mSubscriptionManager.setDefaultDataSubId(currentSir.getSubscriptionId());
-                setMobileDataEnabled(currentSir.getSubscriptionId(), true);
-                disableDataForOtherSubscriptions(currentSir);
-                updateBody();
-            }
-        });
-        builder.setNegativeButton(R.string.cancel, null);
-
-        builder.create().show();
-    }
-
-    private View.OnClickListener mDisableAtLimitListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            final boolean disableAtLimit = !mDisableAtLimit.isChecked();
-            if (disableAtLimit) {
-                // enabling limit; show confirmation dialog which eventually
-                // calls setPolicyLimitBytes() once user confirms.
-                ConfirmLimitFragment.show(DataUsageSummary.this);
-            } else {
-                setPolicyLimitBytes(LIMIT_DISABLED);
-            }
-        }
-    };
-
-    private View.OnClickListener mAppRestrictListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            final boolean restrictBackground = !mAppRestrict.isChecked();
-
-            if (restrictBackground) {
-                // enabling restriction; show confirmation dialog which
-                // eventually calls setRestrictBackground() once user
-                // confirms.
-                ConfirmAppRestrictFragment.show(DataUsageSummary.this);
-            } else {
-                setAppRestrictBackground(false);
-            }
-        }
-    };
-
-    private OnItemClickListener mListListener = new OnItemClickListener() {
-        @Override
-        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-            final Context context = view.getContext();
-            final AppItem app = (AppItem) parent.getItemAtPosition(position);
-
-            // TODO: sigh, remove this hack once we understand 6450986
-            if (mUidDetailProvider == null || app == null) return;
-
-            final UidDetail detail = mUidDetailProvider.getUidDetail(app.key, true);
-            AppDetailsFragment.show(DataUsageSummary.this, app, detail.label);
-        }
-    };
-
-    private OnItemSelectedListener mCycleListener = new OnItemSelectedListener() {
-        @Override
-        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
-            final CycleItem cycle = (CycleItem) parent.getItemAtPosition(position);
-            if (cycle instanceof CycleChangeItem) {
-                // show cycle editor; will eventually call setPolicyCycleDay()
-                // when user finishes editing.
-                CycleEditorFragment.show(DataUsageSummary.this);
-
-                // reset spinner to something other than "change cycle..."
-                mCycleSpinner.setSelection(0);
-
-            } else {
-                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
-        }
-    };
-
-    /**
-     * Update details based on {@link #mChart} inspection range depending on
-     * current mode. In network mode, updates {@link #mAdapter} with sorted list
-     * of applications data usage, and when {@link #isAppDetailMode()} update
-     * app details.
-     */
-    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 (isAppDetailMode() && mChartData != null && mChartData.detail != null) {
-            // bind foreground/background to piechart and labels
-            entry = mChartData.detailDefault.getValues(start, end, now, entry);
-            final long defaultBytes = entry.rxBytes + entry.txBytes;
-            entry = mChartData.detailForeground.getValues(start, end, now, entry);
-            final long foregroundBytes = entry.rxBytes + entry.txBytes;
-            final long totalBytes = defaultBytes + foregroundBytes;
-
-            if (mAppTotal != null) {
-                mAppTotal.setText(Formatter.formatFileSize(context, totalBytes));
-            }
-            mAppBackground.setText(Formatter.formatFileSize(context, defaultBytes));
-            mAppForeground.setText(Formatter.formatFileSize(context, foregroundBytes));
-
-            // and finally leave with summary data for label below
-            entry = mChartData.detail.getValues(start, end, now, null);
-
-            getLoaderManager().destroyLoader(LOADER_SUMMARY);
-
-            mCycleSummary.setVisibility(View.GONE);
-
-        } else {
-            if (mChartData != null) {
-                entry = mChartData.network.getValues(start, end, now, null);
-            }
-
-            mCycleSummary.setVisibility(View.VISIBLE);
-
-            // kick off loader for detailed stats
-            getLoaderManager().restartLoader(LOADER_SUMMARY,
-                    SummaryForAllUidLoader.buildArgs(mTemplate, start, end), mSummaryCallbacks);
-        }
-
-        final long totalBytes = entry != null ? entry.rxBytes + entry.txBytes : 0;
-        final String totalPhrase = Formatter.formatFileSize(context, totalBytes);
-        mCycleSummary.setText(totalPhrase);
-
-        if (isMobileTab(mCurrentTab) || TAB_3G.equals(mCurrentTab)
-                || TAB_4G.equals(mCurrentTab)) {
-            if (isAppDetailMode()) {
-                mDisclaimer.setVisibility(View.GONE);
-            } else {
-                mDisclaimer.setVisibility(View.VISIBLE);
-            }
-        } else {
-            mDisclaimer.setVisibility(View.GONE);
-        }
-
-        // initial layout is finished above, ensure we have transitions
-        ensureLayoutTransitions();
-    }
-
-    private final LoaderCallbacks<ChartData> mChartDataCallbacks = new LoaderCallbacks<
-            ChartData>() {
-        @Override
-        public Loader<ChartData> onCreateLoader(int id, Bundle args) {
-            return new ChartDataLoader(getActivity(), mStatsSession, args);
-        }
-
-        @Override
-        public void onLoadFinished(Loader<ChartData> loader, ChartData data) {
-            mChartData = data;
-            mChart.bindNetworkStats(mChartData.network);
-            mChart.bindDetailNetworkStats(mChartData.detail);
-
-            // calcuate policy cycles based on available data
-            updatePolicy(true);
-            updateAppDetail();
-
-            // force scroll to top of body when showing detail
-            if (mChartData.detail != null) {
-                mListView.smoothScrollToPosition(0);
-            }
-        }
-
-        @Override
-        public void onLoaderReset(Loader<ChartData> loader) {
-            mChartData = null;
-            mChart.bindNetworkStats(null);
-            mChart.bindDetailNetworkStats(null);
-        }
-    };
-
-    private final LoaderCallbacks<NetworkStats> mSummaryCallbacks = new LoaderCallbacks<
-            NetworkStats>() {
-        @Override
-        public Loader<NetworkStats> onCreateLoader(int id, Bundle args) {
-            return new SummaryForAllUidLoader(getActivity(), mStatsSession, args);
-        }
-
-        @Override
-        public void onLoadFinished(Loader<NetworkStats> loader, NetworkStats data) {
-            final int[] restrictedUids = mPolicyManager.getUidsWithPolicy(
-                    POLICY_REJECT_METERED_BACKGROUND);
-            mAdapter.bindStats(data, restrictedUids);
-            updateEmptyVisible();
-        }
-
-        @Override
-        public void onLoaderReset(Loader<NetworkStats> loader) {
-            mAdapter.bindStats(null, new int[0]);
-            updateEmptyVisible();
-        }
-
-        private void updateEmptyVisible() {
-            final boolean isEmpty = mAdapter.isEmpty() && !isAppDetailMode();
-            mEmpty.setVisibility(isEmpty ? View.VISIBLE : View.GONE);
-            mStupidPadding.setVisibility(isEmpty ? View.VISIBLE : View.GONE);
-        }
-    };
-
-    private static String getActiveSubscriberId(Context context) {
-        final TelephonyManager tele = TelephonyManager.from(context);
-        final String actualSubscriberId = tele.getSubscriberId();
-        String retVal = SystemProperties.get(TEST_SUBSCRIBER_PROP, actualSubscriberId);
-        if (LOGD) Log.d(TAG, "getActiveSubscriberId=" + retVal + " actualSubscriberId=" + actualSubscriberId);
-        return retVal;
-    }
-
-    private static String getActiveSubscriberId(Context context, int subId) {
-        final TelephonyManager tele = TelephonyManager.from(context);
-        String retVal = tele.getSubscriberId(subId);
-        if (LOGD) Log.d(TAG, "getActiveSubscriberId=" + retVal + " subId=" + subId);
-        return retVal;
-    }
-
-    private DataUsageChartListener mChartListener = new DataUsageChartListener() {
-        @Override
-        public void onWarningChanged() {
-            setPolicyWarningBytes(mChart.getWarningBytes());
-        }
-
-        @Override
-        public void onLimitChanged() {
-            setPolicyLimitBytes(mChart.getLimitBytes());
-            updateBody();
-        }
-
-        @Override
-        public void requestWarningEdit() {
-            WarningEditorFragment.show(DataUsageSummary.this);
-        }
-
-        @Override
-        public void requestLimitEdit() {
-            LimitEditorFragment.show(DataUsageSummary.this);
-        }
-    };
-
-    /**
-     * List item that reflects a specific data usage cycle.
-     */
-    public static class CycleItem implements Comparable<CycleItem> {
-        public CharSequence label;
-        public long start;
-        public long end;
-
-        CycleItem(CharSequence label) {
-            this.label = label;
-        }
-
-        public CycleItem(Context context, long start, long end) {
-            this.label = formatDateRange(context, start, end);
-            this.start = start;
-            this.end = end;
-        }
-
-        @Override
-        public String toString() {
-            return label.toString();
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (o instanceof CycleItem) {
-                final CycleItem another = (CycleItem) o;
-                return start == another.start && end == another.end;
-            }
-            return false;
-        }
-
-        @Override
-        public int compareTo(CycleItem another) {
-            return Long.compare(start, another.start);
-        }
-    }
-
-    private static final StringBuilder sBuilder = new StringBuilder(50);
-    private static final java.util.Formatter sFormatter = new java.util.Formatter(
-            sBuilder, Locale.getDefault());
-
-    public static String formatDateRange(Context context, long start, long end) {
-        final int flags = FORMAT_SHOW_DATE | FORMAT_ABBREV_MONTH;
-
-        synchronized (sBuilder) {
-            sBuilder.setLength(0);
-            return DateUtils.formatDateRange(context, sFormatter, start, end, flags, null)
-                    .toString();
-        }
-    }
-
-    /**
-     * Special-case data usage cycle that triggers dialog to change
-     * {@link NetworkPolicy#cycleDay}.
-     */
-    public static class CycleChangeItem extends CycleItem {
-        public CycleChangeItem(Context context) {
-            super(context.getString(R.string.data_usage_change_cycle));
-        }
-    }
-
-    public static class CycleAdapter extends ArrayAdapter<CycleItem> {
-        private boolean mChangePossible = false;
-        private boolean mChangeVisible = false;
-
-        private final CycleChangeItem mChangeItem;
-
-        public CycleAdapter(Context context) {
-            super(context, R.layout.data_usage_cycle_item);
-            setDropDownViewResource(R.layout.data_usage_cycle_item_dropdown);
-            mChangeItem = new CycleChangeItem(context);
-        }
-
-        public void setChangePossible(boolean possible) {
-            mChangePossible = possible;
-            updateChange();
-        }
-
-        public void setChangeVisible(boolean visible) {
-            mChangeVisible = visible;
-            updateChange();
-        }
-
-        private void updateChange() {
-            remove(mChangeItem);
-            if (mChangePossible && mChangeVisible) {
-                add(mChangeItem);
-            }
-        }
-
-        /**
-         * Find position of {@link CycleItem} in this adapter which is nearest
-         * the given {@link CycleItem}.
-         */
-        public int findNearestPosition(CycleItem target) {
-            if (target != null) {
-                final int count = getCount();
-                for (int i = count - 1; i >= 0; i--) {
-                    final CycleItem item = getItem(i);
-                    if (item instanceof CycleChangeItem) {
-                        continue;
-                    } else if (item.compareTo(target) >= 0) {
-                        return i;
-                    }
-                }
-            }
-            return 0;
-        }
-    }
-
-    /**
-     * Adapter of applications, sorted by total usage descending.
-     */
-    public static class DataUsageAdapter extends BaseAdapter {
-        private final UidDetailProvider mProvider;
-        private final int mInsetSide;
-        private final UserManager mUm;
-
-        private ArrayList<AppItem> mItems = Lists.newArrayList();
-        private long mLargest;
-
-        public DataUsageAdapter(final UserManager userManager, UidDetailProvider provider, int insetSide) {
-            mProvider = checkNotNull(provider);
-            mInsetSide = insetSide;
-            mUm = userManager;
-        }
-
-        /**
-         * Bind the given {@link NetworkStats}, or {@code null} to clear list.
-         */
-        public void bindStats(NetworkStats stats, int[] restrictedUids) {
-            mItems.clear();
-            mLargest = 0;
-
-            final int currentUserId = ActivityManager.getCurrentUser();
-            final List<UserHandle> profiles = mUm.getUserProfiles();
-            final SparseArray<AppItem> knownItems = new SparseArray<AppItem>();
-
-            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);
-                            accumulate(managedKey, knownItems, entry,
-                                    AppItem.CATEGORY_USER);
-                        }
-                        // 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 = mUm.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;
-                }
-                accumulate(collapseKey, knownItems, entry, category);
-            }
-
-            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;
-                    mItems.add(item);
-                    knownItems.put(item.key, item);
-                }
-                item.restricted = true;
-            }
-
-            if (!mItems.isEmpty()) {
-                final AppItem title = new AppItem();
-                title.category = AppItem.CATEGORY_APP_TITLE;
-                mItems.add(title);
-            }
-
-            Collections.sort(mItems);
-            notifyDataSetChanged();
-        }
-
-        /**
-         * 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
-         *            either AppItem.APP_ITEM_CATEGORY or AppItem.MANAGED_USER_ITEM_CATEGORY
-         */
-        private void accumulate(int collapseKey, final SparseArray<AppItem> knownItems,
-                NetworkStats.Entry entry, int itemCategory) {
-            final int uid = entry.uid;
-            AppItem item = knownItems.get(collapseKey);
-            if (item == null) {
-                item = new AppItem(collapseKey);
-                item.category = itemCategory;
-                mItems.add(item);
-                knownItems.put(item.key, item);
-            }
-            item.addUid(uid);
-            item.total += entry.rxBytes + entry.txBytes;
-            if (mLargest < item.total) {
-                mLargest = item.total;
-            }
-        }
-
-        @Override
-        public int getCount() {
-            return mItems.size();
-        }
-
-        @Override
-        public Object getItem(int position) {
-            return mItems.get(position);
-        }
-
-        @Override
-        public long getItemId(int position) {
-            return mItems.get(position).key;
-        }
-
-        /**
-         * See {@link #getItemViewType} for the view types.
-         */
-        @Override
-        public int getViewTypeCount() {
-            return 2;
-        }
-
-        /**
-         * Returns 1 for separator items and 0 for anything else.
-         */
-        @Override
-        public int getItemViewType(int position) {
-            final AppItem item = mItems.get(position);
-            if (item.category == AppItem.CATEGORY_APP_TITLE) {
-                return 1;
-            } else {
-                return 0;
-            }
-        }
-
-        @Override
-        public boolean areAllItemsEnabled() {
-            return false;
-        }
-
-        @Override
-        public boolean isEnabled(int position) {
-            if (position > mItems.size()) {
-                throw new ArrayIndexOutOfBoundsException();
-            }
-            return getItemViewType(position) == 0;
-        }
-
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            final AppItem item = mItems.get(position);
-            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
-            if (getItemViewType(position) == 1) {
-                if (convertView == null) {
-                    convertView = Utils.inflateCategoryHeader(inflater, parent);
-                }
-
-                final TextView title = (TextView) convertView.findViewById(android.R.id.title);
-                title.setText(R.string.data_usage_app);
-
-            } else {
-                if (convertView == null) {
-                    convertView = inflater.inflate(R.layout.data_usage_item, parent, false);
-                    inflater.inflate(R.layout.widget_progress_bar,
-                            (ViewGroup) convertView.findViewById(android.R.id.widget_frame));
-
-                    if (mInsetSide > 0) {
-                        convertView.setPaddingRelative(mInsetSide, 0, mInsetSide, 0);
-                    }
-                }
-
-                final Context context = parent.getContext();
-
-                final TextView summary = (TextView) convertView.findViewById(android.R.id.summary);
-                final ProgressBar progress = (ProgressBar) convertView.findViewById(
-                        android.R.id.progress);
-
-                // kick off async load of app details
-                UidDetailTask.bindView(mProvider, item, convertView);
-
-                if (item.restricted && item.total <= 0) {
-                    summary.setText(R.string.data_usage_app_restricted);
-                    progress.setVisibility(View.GONE);
-                } else {
-                    summary.setText(Formatter.formatFileSize(context, item.total));
-                    progress.setVisibility(View.VISIBLE);
-                }
-
-                final int percentTotal = mLargest != 0 ? (int) (item.total * 100 / mLargest) : 0;
-                progress.setProgress(percentTotal);
-            }
-
-            return convertView;
-        }
-    }
-
-    /**
-     * Empty {@link Fragment} that controls display of UID details in
-     * {@link DataUsageSummary}.
-     */
-    public static class AppDetailsFragment extends Fragment {
-        private static final String EXTRA_APP = "app";
-
-        public static void show(DataUsageSummary parent, AppItem app, CharSequence label) {
-            show(parent, app, label, true);
-        }
-
-        public static void show(DataUsageSummary parent, AppItem app, CharSequence label,
-                boolean addToBack) {
-            if (!parent.isAdded()) return;
-
-            final Bundle args = new Bundle();
-            args.putParcelable(EXTRA_APP, app);
-
-            final AppDetailsFragment fragment = new AppDetailsFragment();
-            fragment.setArguments(args);
-            fragment.setTargetFragment(parent, 0);
-            final FragmentTransaction ft = parent.getFragmentManager().beginTransaction();
-            ft.add(fragment, TAG_APP_DETAILS);
-            if (addToBack) {
-                ft.addToBackStack(TAG_APP_DETAILS);
-            }
-            ft.setBreadCrumbTitle(
-                    parent.getResources().getString(R.string.data_usage_app_summary_title));
-            ft.commitAllowingStateLoss();
-        }
-
-        @Override
-        public void onStart() {
-            super.onStart();
-            final DataUsageSummary target = (DataUsageSummary) getTargetFragment();
-            target.mCurrentApp = getArguments().getParcelable(EXTRA_APP);
-            target.updateBody();
-        }
-
-        @Override
-        public void onStop() {
-            super.onStop();
-            final DataUsageSummary target = (DataUsageSummary) getTargetFragment();
-            target.mCurrentApp = null;
-            target.updateBody();
-        }
-
-        @Override
-        public boolean onOptionsItemSelected(MenuItem item) {
-            switch (item.getItemId()) {
-            case android.R.id.home:
-                getFragmentManager().popBackStack();
-                return true;
-            }
-            return super.onOptionsItemSelected(item);
-        }
-    }
-
-    /**
-     * Dialog to request user confirmation before setting
-     * {@link NetworkPolicy#limitBytes}.
-     */
-    public static class ConfirmLimitFragment extends DialogFragment {
-        private static final String EXTRA_MESSAGE = "message";
-        private static final String EXTRA_LIMIT_BYTES = "limitBytes";
-
-        public static void show(DataUsageSummary parent) {
-            if (!parent.isAdded()) return;
-
-            final NetworkPolicy policy = parent.mPolicyEditor.getPolicy(parent.mTemplate);
-            if (policy == null) return;
-
-            final Resources res = parent.getResources();
-            final CharSequence message;
-            final long minLimitBytes = (long) (policy.warningBytes * 1.2f);
-            final long limitBytes;
-
-            // TODO: customize default limits based on network template
-            final String currentTab = parent.mCurrentTab;
-            if (TAB_3G.equals(currentTab)) {
-                message = res.getString(R.string.data_usage_limit_dialog_mobile);
-                limitBytes = Math.max(5 * GB_IN_BYTES, minLimitBytes);
-            } else if (TAB_4G.equals(currentTab)) {
-                message = res.getString(R.string.data_usage_limit_dialog_mobile);
-                limitBytes = Math.max(5 * GB_IN_BYTES, minLimitBytes);
-            } else if (isMobileTab(currentTab)) {
-                message = res.getString(R.string.data_usage_limit_dialog_mobile);
-                limitBytes = Math.max(5 * GB_IN_BYTES, minLimitBytes);
-            } else {
-                throw new IllegalArgumentException("unknown current tab: " + currentTab);
-            }
-
-            final Bundle args = new Bundle();
-            args.putCharSequence(EXTRA_MESSAGE, message);
-            args.putLong(EXTRA_LIMIT_BYTES, limitBytes);
-
-            final ConfirmLimitFragment dialog = new ConfirmLimitFragment();
-            dialog.setArguments(args);
-            dialog.setTargetFragment(parent, 0);
-            dialog.show(parent.getFragmentManager(), TAG_CONFIRM_LIMIT);
-        }
-
-        @Override
-        public Dialog onCreateDialog(Bundle savedInstanceState) {
-            final Context context = getActivity();
-
-            final CharSequence message = getArguments().getCharSequence(EXTRA_MESSAGE);
-            final long limitBytes = getArguments().getLong(EXTRA_LIMIT_BYTES);
-
-            final AlertDialog.Builder builder = new AlertDialog.Builder(context);
-            builder.setTitle(R.string.data_usage_limit_dialog_title);
-            builder.setMessage(message);
-
-            builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-                @Override
-                public void onClick(DialogInterface dialog, int which) {
-                    final DataUsageSummary target = (DataUsageSummary) getTargetFragment();
-                    if (target != null) {
-                        target.setPolicyLimitBytes(limitBytes);
-                    }
-                }
-            });
-
-            return builder.create();
-        }
-    }
-
-    /**
-     * Dialog to edit {@link NetworkPolicy#cycleDay}.
-     */
-    public static class CycleEditorFragment extends DialogFragment {
-        private static final String EXTRA_TEMPLATE = "template";
-
-        public static void show(DataUsageSummary parent) {
-            if (!parent.isAdded()) return;
-
-            final Bundle args = new Bundle();
-            args.putParcelable(EXTRA_TEMPLATE, parent.mTemplate);
-
-            final CycleEditorFragment dialog = new CycleEditorFragment();
-            dialog.setArguments(args);
-            dialog.setTargetFragment(parent, 0);
-            dialog.show(parent.getFragmentManager(), TAG_CYCLE_EDITOR);
-        }
-
-        @Override
-        public Dialog onCreateDialog(Bundle savedInstanceState) {
-            final Context context = getActivity();
-            final DataUsageSummary target = (DataUsageSummary) getTargetFragment();
-            final NetworkPolicyEditor editor = target.mPolicyEditor;
-
-            final AlertDialog.Builder builder = new AlertDialog.Builder(context);
-            final LayoutInflater dialogInflater = LayoutInflater.from(builder.getContext());
-
-            final View view = dialogInflater.inflate(R.layout.data_usage_cycle_editor, null, false);
-            final NumberPicker cycleDayPicker = (NumberPicker) view.findViewById(R.id.cycle_day);
-
-            final NetworkTemplate template = getArguments().getParcelable(EXTRA_TEMPLATE);
-            final int cycleDay = editor.getPolicyCycleDay(template);
-
-            cycleDayPicker.setMinValue(1);
-            cycleDayPicker.setMaxValue(31);
-            cycleDayPicker.setValue(cycleDay);
-            cycleDayPicker.setWrapSelectorWheel(true);
-
-            builder.setTitle(R.string.data_usage_cycle_editor_title);
-            builder.setView(view);
-
-            builder.setPositiveButton(R.string.data_usage_cycle_editor_positive,
-                    new DialogInterface.OnClickListener() {
-                        @Override
-                        public void onClick(DialogInterface dialog, int which) {
-                            // clear focus to finish pending text edits
-                            cycleDayPicker.clearFocus();
-
-                            final int cycleDay = cycleDayPicker.getValue();
-                            final String cycleTimezone = new Time().timezone;
-                            editor.setPolicyCycleDay(template, cycleDay, cycleTimezone);
-                            target.updatePolicy(true);
-                        }
-                    });
-
-            return builder.create();
-        }
-    }
-
-    /**
-     * Dialog to edit {@link NetworkPolicy#warningBytes}.
-     */
-    public static class WarningEditorFragment extends DialogFragment {
-        private static final String EXTRA_TEMPLATE = "template";
-
-        public static void show(DataUsageSummary parent) {
-            if (!parent.isAdded()) return;
-
-            final Bundle args = new Bundle();
-            args.putParcelable(EXTRA_TEMPLATE, parent.mTemplate);
-
-            final WarningEditorFragment dialog = new WarningEditorFragment();
-            dialog.setArguments(args);
-            dialog.setTargetFragment(parent, 0);
-            dialog.show(parent.getFragmentManager(), TAG_WARNING_EDITOR);
-        }
-
-        @Override
-        public Dialog onCreateDialog(Bundle savedInstanceState) {
-            final Context context = getActivity();
-            final DataUsageSummary target = (DataUsageSummary) getTargetFragment();
-            final NetworkPolicyEditor editor = target.mPolicyEditor;
-
-            final AlertDialog.Builder builder = new AlertDialog.Builder(context);
-            final LayoutInflater dialogInflater = LayoutInflater.from(builder.getContext());
-
-            final View view = dialogInflater.inflate(R.layout.data_usage_bytes_editor, null, false);
-            final NumberPicker bytesPicker = (NumberPicker) view.findViewById(R.id.bytes);
-
-            final NetworkTemplate template = getArguments().getParcelable(EXTRA_TEMPLATE);
-            final long warningBytes = editor.getPolicyWarningBytes(template);
-            final long limitBytes = editor.getPolicyLimitBytes(template);
-
-            bytesPicker.setMinValue(0);
-            if (limitBytes != LIMIT_DISABLED) {
-                bytesPicker.setMaxValue((int) (limitBytes / MB_IN_BYTES) - 1);
-            } else {
-                bytesPicker.setMaxValue(Integer.MAX_VALUE);
-            }
-            bytesPicker.setValue((int) (warningBytes / MB_IN_BYTES));
-            bytesPicker.setWrapSelectorWheel(false);
-
-            builder.setTitle(R.string.data_usage_warning_editor_title);
-            builder.setView(view);
-
-            builder.setPositiveButton(R.string.data_usage_cycle_editor_positive,
-                    new DialogInterface.OnClickListener() {
-                        @Override
-                        public void onClick(DialogInterface dialog, int which) {
-                            // clear focus to finish pending text edits
-                            bytesPicker.clearFocus();
-
-                            final long bytes = bytesPicker.getValue() * MB_IN_BYTES;
-                            editor.setPolicyWarningBytes(template, bytes);
-                            target.updatePolicy(false);
-                        }
-                    });
-
-            return builder.create();
-        }
-    }
-
-    /**
-     * Dialog to edit {@link NetworkPolicy#limitBytes}.
-     */
-    public static class LimitEditorFragment extends DialogFragment {
-        private static final String EXTRA_TEMPLATE = "template";
-
-        public static void show(DataUsageSummary parent) {
-            if (!parent.isAdded()) return;
-
-            final Bundle args = new Bundle();
-            args.putParcelable(EXTRA_TEMPLATE, parent.mTemplate);
-
-            final LimitEditorFragment dialog = new LimitEditorFragment();
-            dialog.setArguments(args);
-            dialog.setTargetFragment(parent, 0);
-            dialog.show(parent.getFragmentManager(), TAG_LIMIT_EDITOR);
-        }
-
-        @Override
-        public Dialog onCreateDialog(Bundle savedInstanceState) {
-            final Context context = getActivity();
-            final DataUsageSummary target = (DataUsageSummary) getTargetFragment();
-            final NetworkPolicyEditor editor = target.mPolicyEditor;
-
-            final AlertDialog.Builder builder = new AlertDialog.Builder(context);
-            final LayoutInflater dialogInflater = LayoutInflater.from(builder.getContext());
-
-            final View view = dialogInflater.inflate(R.layout.data_usage_bytes_editor, null, false);
-            final NumberPicker bytesPicker = (NumberPicker) view.findViewById(R.id.bytes);
-
-            final NetworkTemplate template = getArguments().getParcelable(EXTRA_TEMPLATE);
-            final long warningBytes = editor.getPolicyWarningBytes(template);
-            final long limitBytes = editor.getPolicyLimitBytes(template);
-
-            bytesPicker.setMaxValue(Integer.MAX_VALUE);
-            if (warningBytes != WARNING_DISABLED && limitBytes > 0) {
-                bytesPicker.setMinValue((int) (warningBytes / MB_IN_BYTES) + 1);
-            } else {
-                bytesPicker.setMinValue(0);
-            }
-            bytesPicker.setValue((int) (limitBytes / MB_IN_BYTES));
-            bytesPicker.setWrapSelectorWheel(false);
-
-            builder.setTitle(R.string.data_usage_limit_editor_title);
-            builder.setView(view);
-
-            builder.setPositiveButton(R.string.data_usage_cycle_editor_positive,
-                    new DialogInterface.OnClickListener() {
-                        @Override
-                        public void onClick(DialogInterface dialog, int which) {
-                            // clear focus to finish pending text edits
-                            bytesPicker.clearFocus();
-
-                            final long bytes = bytesPicker.getValue() * MB_IN_BYTES;
-                            editor.setPolicyLimitBytes(template, bytes);
-                            target.updatePolicy(false);
-                        }
-                    });
-
-            return builder.create();
-        }
-    }
-    /**
-     * Dialog to request user confirmation before disabling data.
-     */
-    public static class ConfirmDataDisableFragment extends DialogFragment {
-        static int mSubId;
-        public static void show(DataUsageSummary parent, int subId) {
-            mSubId = subId;
-            if (!parent.isAdded()) return;
-
-            final ConfirmDataDisableFragment dialog = new ConfirmDataDisableFragment();
-            dialog.setTargetFragment(parent, 0);
-            dialog.show(parent.getFragmentManager(), TAG_CONFIRM_DATA_DISABLE);
-        }
-
-        @Override
-        public Dialog onCreateDialog(Bundle savedInstanceState) {
-            final Context context = getActivity();
-
-            final AlertDialog.Builder builder = new AlertDialog.Builder(context);
-            builder.setMessage(R.string.data_usage_disable_mobile);
-
-            builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-                @Override
-                public void onClick(DialogInterface dialog, int which) {
-                    final DataUsageSummary target = (DataUsageSummary) getTargetFragment();
-                    if (target != null) {
-                        // TODO: extend to modify policy enabled flag.
-                        target.setMobileDataEnabled(mSubId, false);
-                    }
-                }
-            });
-            builder.setNegativeButton(android.R.string.cancel, null);
-
-            return builder.create();
-        }
-    }
-
-    /**
-     * Dialog to request user confirmation before setting
-     * {@link INetworkPolicyManager#setRestrictBackground(boolean)}.
-     */
-    public static class ConfirmRestrictFragment extends DialogFragment {
-        public static void show(DataUsageSummary parent) {
-            if (!parent.isAdded()) return;
-
-            final ConfirmRestrictFragment dialog = new ConfirmRestrictFragment();
-            dialog.setTargetFragment(parent, 0);
-            dialog.show(parent.getFragmentManager(), TAG_CONFIRM_RESTRICT);
-        }
-
-        @Override
-        public Dialog onCreateDialog(Bundle savedInstanceState) {
-            final Context context = getActivity();
-
-            final AlertDialog.Builder builder = new AlertDialog.Builder(context);
-            builder.setTitle(R.string.data_usage_restrict_background_title);
-            if (Utils.hasMultipleUsers(context)) {
-                builder.setMessage(R.string.data_usage_restrict_background_multiuser);
-            } else {
-                builder.setMessage(R.string.data_usage_restrict_background);
-            }
-
-            builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-                @Override
-                public void onClick(DialogInterface dialog, int which) {
-                    final DataUsageSummary target = (DataUsageSummary) getTargetFragment();
-                    if (target != null) {
-                        target.setRestrictBackground(true);
-                    }
-                }
-            });
-            builder.setNegativeButton(android.R.string.cancel, null);
-
-            return builder.create();
-        }
-    }
-
-    /**
-     * Dialog to inform user that {@link #POLICY_REJECT_METERED_BACKGROUND}
-     * change has been denied, usually based on
-     * {@link DataUsageSummary#hasLimitedNetworks()}.
-     */
-    public static class DeniedRestrictFragment extends DialogFragment {
-        public static void show(DataUsageSummary parent) {
-            if (!parent.isAdded()) return;
-
-            final DeniedRestrictFragment dialog = new DeniedRestrictFragment();
-            dialog.setTargetFragment(parent, 0);
-            dialog.show(parent.getFragmentManager(), TAG_DENIED_RESTRICT);
-        }
-
-        @Override
-        public Dialog onCreateDialog(Bundle savedInstanceState) {
-            final Context context = getActivity();
-
-            final AlertDialog.Builder builder = new AlertDialog.Builder(context);
-            builder.setTitle(R.string.data_usage_app_restrict_background);
-            builder.setMessage(R.string.data_usage_restrict_denied_dialog);
-            builder.setPositiveButton(android.R.string.ok, null);
-
-            return builder.create();
-        }
-    }
-
-    /**
-     * Dialog to request user confirmation before setting
-     * {@link #POLICY_REJECT_METERED_BACKGROUND}.
-     */
-    public static class ConfirmAppRestrictFragment extends DialogFragment {
-        public static void show(DataUsageSummary parent) {
-            if (!parent.isAdded()) return;
-
-            final ConfirmAppRestrictFragment dialog = new ConfirmAppRestrictFragment();
-            dialog.setTargetFragment(parent, 0);
-            dialog.show(parent.getFragmentManager(), TAG_CONFIRM_APP_RESTRICT);
-        }
-
-        @Override
-        public Dialog onCreateDialog(Bundle savedInstanceState) {
-            final Context context = getActivity();
-
-            final AlertDialog.Builder builder = new AlertDialog.Builder(context);
-            builder.setTitle(R.string.data_usage_app_restrict_dialog_title);
-            builder.setMessage(R.string.data_usage_app_restrict_dialog);
-
-            builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-                @Override
-                public void onClick(DialogInterface dialog, int which) {
-                    final DataUsageSummary target = (DataUsageSummary) getTargetFragment();
-                    if (target != null) {
-                        target.setAppRestrictBackground(true);
-                    }
-                }
-            });
-            builder.setNegativeButton(android.R.string.cancel, null);
-
-            return builder.create();
-        }
-    }
-
-    /**
-     * Compute default tab that should be selected, based on
-     * {@link NetworkPolicyManager#EXTRA_NETWORK_TEMPLATE} extra.
-     */
-    private static String computeTabFromIntent(Intent intent) {
-        final NetworkTemplate template = intent.getParcelableExtra(EXTRA_NETWORK_TEMPLATE);
-        if (template == null) {
-            final int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
-                    SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-            if (SubscriptionManager.isValidSubscriptionId(subId)) {
-                return TAB_MOBILE + String.valueOf(subId);
-            }
-            return null;
-        }
-
-        switch (template.getMatchRule()) {
-            case MATCH_MOBILE_3G_LOWER:
-                return TAB_3G;
-            case MATCH_MOBILE_4G:
-                return TAB_4G;
-            case MATCH_MOBILE_ALL:
-                return TAB_MOBILE;
-            case MATCH_WIFI:
-                return TAB_WIFI;
-            default:
-                return null;
-        }
-    }
-
-    /**
-     * Background task that loads {@link UidDetail}, binding to
-     * {@link DataUsageAdapter} row item when finished.
-     */
-    private static class UidDetailTask extends AsyncTask<Void, Void, UidDetail> {
-        private final UidDetailProvider mProvider;
-        private final AppItem mItem;
-        private final View mTarget;
-
-        private UidDetailTask(UidDetailProvider provider, AppItem item, View target) {
-            mProvider = checkNotNull(provider);
-            mItem = checkNotNull(item);
-            mTarget = checkNotNull(target);
-        }
-
-        public static void bindView(
-                UidDetailProvider provider, AppItem item, View target) {
-            final UidDetailTask existing = (UidDetailTask) target.getTag();
-            if (existing != null) {
-                existing.cancel(false);
-            }
-
-            final UidDetail cachedDetail = provider.getUidDetail(item.key, false);
-            if (cachedDetail != null) {
-                bindView(cachedDetail, target);
-            } else {
-                target.setTag(new UidDetailTask(provider, item, target).executeOnExecutor(
-                        AsyncTask.THREAD_POOL_EXECUTOR));
-            }
-        }
-
-        private static void bindView(UidDetail detail, View target) {
-            final ImageView icon = (ImageView) target.findViewById(android.R.id.icon);
-            final TextView title = (TextView) target.findViewById(android.R.id.title);
-
-            if (detail != null) {
-                icon.setImageDrawable(detail.icon);
-                title.setText(detail.label);
-                title.setContentDescription(detail.contentDescription);
-            } else {
-                icon.setImageDrawable(null);
-                title.setText(null);
-            }
-        }
-
-        @Override
-        protected void onPreExecute() {
-            bindView(null, mTarget);
-        }
-
-        @Override
-        protected UidDetail doInBackground(Void... params) {
-            return mProvider.getUidDetail(mItem.key, true);
-        }
-
-        @Override
-        protected void onPostExecute(UidDetail result) {
-            bindView(result, mTarget);
-        }
-    }
-
-    /**
-     * Test if device has a mobile data radio with SIM in ready state.
-     */
-    public static boolean hasReadyMobileRadio(Context context) {
-        if (TEST_RADIOS) {
-            return SystemProperties.get(TEST_RADIOS_PROP).contains("mobile");
-        }
-
-        final ConnectivityManager conn = ConnectivityManager.from(context);
-        final TelephonyManager tele = TelephonyManager.from(context);
-
-        final List<SubscriptionInfo> subInfoList =
-                SubscriptionManager.from(context).getActiveSubscriptionInfoList();
-        // No activated Subscriptions
-        if (subInfoList == null) {
-            if (LOGD) Log.d(TAG, "hasReadyMobileRadio: subInfoList=null");
-            return false;
-        }
-        // require both supported network and ready SIM
-        boolean isReady = true;
-        for (SubscriptionInfo subInfo : subInfoList) {
-            isReady = isReady & tele.getSimState(subInfo.getSimSlotIndex()) == SIM_STATE_READY;
-            if (LOGD) Log.d(TAG, "hasReadyMobileRadio: subInfo=" + subInfo);
-        }
-        boolean retVal = conn.isNetworkSupported(TYPE_MOBILE) && isReady;
-        if (LOGD) {
-            Log.d(TAG, "hasReadyMobileRadio:"
-                    + " conn.isNetworkSupported(TYPE_MOBILE)="
-                                            + conn.isNetworkSupported(TYPE_MOBILE)
-                    + " isReady=" + isReady);
-        }
-        return retVal;
-    }
-
-    /*
-     * TODO: consider adding to TelephonyManager or SubscritpionManager.
-     */
-    public static boolean hasReadyMobileRadio(Context context, int subId) {
-        if (TEST_RADIOS) {
-            return SystemProperties.get(TEST_RADIOS_PROP).contains("mobile");
-        }
-
-        final ConnectivityManager conn = ConnectivityManager.from(context);
-        final TelephonyManager tele = TelephonyManager.from(context);
-        final int slotId = SubscriptionManager.getSlotId(subId);
-        final boolean isReady = tele.getSimState(slotId) == SIM_STATE_READY;
-
-        boolean retVal =  conn.isNetworkSupported(TYPE_MOBILE) && isReady;
-        if (LOGD) Log.d(TAG, "hasReadyMobileRadio: subId=" + subId
-                + " conn.isNetworkSupported(TYPE_MOBILE)=" + conn.isNetworkSupported(TYPE_MOBILE)
-                + " isReady=" + isReady);
-        return retVal;
-    }
-
-    /**
-     * Test if device has a mobile 4G data radio.
-     */
-    public static boolean hasReadyMobile4gRadio(Context context) {
-        if (!NetworkPolicyEditor.ENABLE_SPLIT_POLICIES) {
-            return false;
-        }
-        if (TEST_RADIOS) {
-            return SystemProperties.get(TEST_RADIOS_PROP).contains("4g");
-        }
-
-        final ConnectivityManager conn = ConnectivityManager.from(context);
-        final TelephonyManager tele = TelephonyManager.from(context);
-
-        final boolean hasWimax = conn.isNetworkSupported(TYPE_WIMAX);
-        final boolean hasLte = (tele.getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_TRUE)
-                && hasReadyMobileRadio(context);
-        return hasWimax || hasLte;
-    }
-
-    /**
-     * Test if device has a Wi-Fi data radio.
-     */
-    public static boolean hasWifiRadio(Context context) {
-        if (TEST_RADIOS) {
-            return SystemProperties.get(TEST_RADIOS_PROP).contains("wifi");
-        }
-
-        final ConnectivityManager conn = ConnectivityManager.from(context);
-        return conn.isNetworkSupported(TYPE_WIFI);
-    }
-
-    /**
-     * Test if device has an ethernet network connection.
-     */
-    public boolean hasEthernet(Context context) {
-        if (TEST_RADIOS) {
-            return SystemProperties.get(TEST_RADIOS_PROP).contains("ethernet");
-        }
-
-        final ConnectivityManager conn = ConnectivityManager.from(context);
-        final boolean hasEthernet = conn.isNetworkSupported(TYPE_ETHERNET);
-
-        final long ethernetBytes;
-        if (mStatsSession != null) {
-            try {
-                ethernetBytes = mStatsSession.getSummaryForNetwork(
-                        NetworkTemplate.buildTemplateEthernet(), Long.MIN_VALUE, Long.MAX_VALUE)
-                        .getTotalBytes();
-            } catch (RemoteException e) {
-                throw new RuntimeException(e);
-            }
-        } else {
-            ethernetBytes = 0;
-        }
-
-        // only show ethernet when both hardware present and traffic has occurred
-        return hasEthernet && ethernetBytes > 0;
-    }
-
-    /**
-     * Inflate a {@link Preference} style layout, adding the given {@link View}
-     * widget into {@link android.R.id#widget_frame}.
-     */
-    private static View inflatePreference(LayoutInflater inflater, ViewGroup root, View widget) {
-        final View view = inflater.inflate(R.layout.preference, root, false);
-        final LinearLayout widgetFrame = (LinearLayout) view.findViewById(
-                android.R.id.widget_frame);
-        widgetFrame.addView(widget, new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
-        return view;
-    }
-
-    /**
-     * Test if any networks are currently limited.
-     */
-    private boolean hasLimitedNetworks() {
-        return !buildLimitedNetworksList().isEmpty();
-    }
-
-    /**
-     * Build string describing currently limited networks, which defines when
-     * background data is restricted.
-     */
-    @Deprecated
-    private CharSequence buildLimitedNetworksString() {
-        final List<CharSequence> limited = buildLimitedNetworksList();
-
-        // handle case where no networks limited
-        if (limited.isEmpty()) {
-            limited.add(getText(R.string.data_usage_list_none));
-        }
-
-        final ICUResourceBundle icuBundle = (ICUResourceBundle) UResourceBundle.
-                getBundleInstance(ICUResourceBundle.ICU_BASE_NAME);
-        final String listMiddlePattern =
-                icuBundle.getStringWithFallback("listPattern/standard/middle");
-        // The returned pattern is something like "{0}, {1}", from which we want
-        // to extract the ", " part.
-        final int firstClosingBrace = listMiddlePattern.indexOf('}');
-        final int lastOpeningBrace = listMiddlePattern.lastIndexOf('{');
-        final CharSequence delimiter = listMiddlePattern.substring(
-                firstClosingBrace+1, lastOpeningBrace);
-
-        return TextUtils.join(delimiter, limited);
-    }
-
-    /**
-     * Build list of currently limited networks, which defines when background
-     * data is restricted.
-     */
-    @Deprecated
-    private List<CharSequence> buildLimitedNetworksList() {
-        final Context context = getActivity();
-
-        // build combined list of all limited networks
-        final ArrayList<CharSequence> limited = Lists.newArrayList();
-
-        final TelephonyManager tele = TelephonyManager.from(context);
-        if (tele.getSimState() == SIM_STATE_READY) {
-            final String subscriberId = getActiveSubscriberId(context);
-            if (mPolicyEditor.hasLimitedPolicy(buildTemplateMobileAll(subscriberId))) {
-                limited.add(getText(R.string.data_usage_list_mobile));
-            }
-            if (mPolicyEditor.hasLimitedPolicy(buildTemplateMobile3gLower(subscriberId))) {
-                limited.add(getText(R.string.data_usage_tab_3g));
-            }
-            if (mPolicyEditor.hasLimitedPolicy(buildTemplateMobile4g(subscriberId))) {
-                limited.add(getText(R.string.data_usage_tab_4g));
-            }
-        }
-
-        if (mPolicyEditor.hasLimitedPolicy(buildTemplateWifiWildcard())) {
-            limited.add(getText(R.string.data_usage_tab_wifi));
-        }
-        if (mPolicyEditor.hasLimitedPolicy(buildTemplateEthernet())) {
-            limited.add(getText(R.string.data_usage_tab_ethernet));
-        }
-
-        return limited;
-    }
-
-    /**
-     * Inset both selector and divider {@link Drawable} on the given
-     * {@link ListView} by the requested dimensions.
-     */
-    private static void insetListViewDrawables(ListView view, int insetSide) {
-        final Drawable selector = view.getSelector();
-        final Drawable divider = view.getDivider();
-
-        // fully unregister these drawables so callbacks can be maintained after
-        // wrapping below.
-        final Drawable stub = new ColorDrawable(Color.TRANSPARENT);
-        view.setSelector(stub);
-        view.setDivider(stub);
-
-        view.setSelector(new InsetBoundsDrawable(selector, insetSide));
-        view.setDivider(new InsetBoundsDrawable(divider, insetSide));
-    }
-
-    /**
-     * Set {@link android.R.id#title} for a preference view inflated with
-     * {@link #inflatePreference(LayoutInflater, ViewGroup, View)}.
-     */
-    private static void setPreferenceTitle(View parent, int resId) {
-        final TextView title = (TextView) parent.findViewById(android.R.id.title);
-        title.setText(resId);
-    }
-
-    /**
-     * Set {@link android.R.id#summary} for a preference view inflated with
-     * {@link #inflatePreference(LayoutInflater, ViewGroup, View)}.
-     */
-    private static void setPreferenceSummary(View parent, CharSequence string) {
-        final TextView summary = (TextView) parent.findViewById(android.R.id.summary);
-        summary.setVisibility(View.VISIBLE);
-        summary.setText(string);
-    }
-
-    private void addMobileTab(Context context, SubscriptionInfo subInfo, boolean isMultiSim) {
-        if (subInfo != null && mMobileTagMap != null) {
-            if (hasReadyMobileRadio(context, subInfo.getSubscriptionId())) {
-                if (isMultiSim) {
-                    mTabHost.addTab(buildTabSpec(mMobileTagMap.get(subInfo.getSubscriptionId()),
-                            subInfo.getDisplayName()));
-                } else {
-                    mTabHost.addTab(buildTabSpec(mMobileTagMap.get(subInfo.getSubscriptionId()),
-                            R.string.data_usage_tab_mobile));
-                }
-            }
-        } else {
-            if (LOGD) Log.d(TAG, "addMobileTab: subInfoList is null");
-        }
-    }
-
-    private SubscriptionInfo getCurrentTabSubInfo(Context context) {
-        if (mSubInfoList != null && mTabHost != null) {
-            final int currentTagIndex = mTabHost.getCurrentTab();
-            int i = 0;
-            for (SubscriptionInfo subInfo : mSubInfoList) {
-                if (hasReadyMobileRadio(context, subInfo.getSubscriptionId())) {
-                    if (i++ == currentTagIndex) {
-                        return subInfo;
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Init a map with subId key and mobile tag name
-     * @param subInfoList The subscription Info List
-     * @return The map or null if no activated subscription
-     */
-    private Map<Integer, String> initMobileTabTag(List<SubscriptionInfo> subInfoList) {
-        Map<Integer, String> map = null;
-        if (subInfoList != null) {
-            String mobileTag;
-            map = new HashMap<Integer, String>();
-            for (SubscriptionInfo subInfo : subInfoList) {
-                mobileTag = TAB_MOBILE + String.valueOf(subInfo.getSubscriptionId());
-                map.put(subInfo.getSubscriptionId(), mobileTag);
-            }
-        }
-        return map;
-    }
-
-    private static boolean isMobileTab(String currentTab) {
-        return currentTab != null ? currentTab.contains(TAB_MOBILE) : false;
-    }
-
-    private int getSubId(String currentTab) {
-        if (mMobileTagMap != null) {
-            Set<Integer> set = mMobileTagMap.keySet();
-            for (Integer subId : set) {
-                if (mMobileTagMap.get(subId).equals(currentTab)) {
-                    return subId;
-                }
-            }
-        }
-        Log.e(TAG, "currentTab = " + currentTab + " non mobile tab called this function");
-        return -1;
-    }
-
-    private boolean isMobileDataAvailable(int subId) {
-        return mSubscriptionManager.getActiveSubscriptionInfo(subId) != null;
-    }
-
-    private static class SummaryProvider
-            implements SummaryLoader.SummaryProvider {
-
-        private final Activity mActivity;
-        private final SummaryLoader mSummaryLoader;
-        private final MobileDataController mDataController;
-
-        public SummaryProvider(Activity activity, SummaryLoader summaryLoader) {
-            mActivity = activity;
-            mSummaryLoader = summaryLoader;
-            mDataController = new MobileDataController(activity);
-        }
-
-        @Override
-        public void setListening(boolean listening) {
-            if (listening) {
-                MobileDataController.DataUsageInfo info = mDataController.getDataUsageInfo();
-                String used;
-                if (info == null) {
-                    used = Formatter.formatFileSize(mActivity, 0);
-                } else if (info.limitLevel <= 0) {
-                    used = Formatter.formatFileSize(mActivity, info.usageLevel);
-                } else {
-                    used = Utils.formatPercentage(info.usageLevel, info.limitLevel);
-                }
-                mSummaryLoader.setSummary(this,
-                        mActivity.getString(R.string.data_usage_summary_format, used));
-            }
-        }
-    }
-
-    public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
-            = new SummaryLoader.SummaryProviderFactory() {
-        @Override
-        public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
-                                                                   SummaryLoader summaryLoader) {
-            return new SummaryProvider(activity, summaryLoader);
-        }
-    };
-
-    /**
-     * For search
-     */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-        new BaseSearchIndexProvider() {
-            @Override
-            public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
-                final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
-
-                final Resources res = context.getResources();
-
-                // Add fragment title
-                SearchIndexableRaw data = new SearchIndexableRaw(context);
-                data.title = res.getString(R.string.data_usage_summary_title);
-                data.screenTitle = res.getString(R.string.data_usage_summary_title);
-                result.add(data);
-
-                // Mobile data
-                data = new SearchIndexableRaw(context);
-                data.key = DATA_USAGE_ENABLE_MOBILE_KEY;
-                data.title = res.getString(R.string.data_usage_enable_mobile);
-                data.screenTitle = res.getString(R.string.data_usage_summary_title);
-                result.add(data);
-
-                // Set mobile data limit
-                data = new SearchIndexableRaw(context);
-                data.key = DATA_USAGE_DISABLE_MOBILE_LIMIT_KEY;
-                data.title = res.getString(R.string.data_usage_disable_mobile_limit);
-                data.screenTitle = res.getString(R.string.data_usage_summary_title);
-                result.add(data);
-
-                // Data usage cycle
-                data = new SearchIndexableRaw(context);
-                data.key = DATA_USAGE_CYCLE_KEY;
-                data.title = res.getString(R.string.data_usage_cycle);
-                data.screenTitle = res.getString(R.string.data_usage_summary_title);
-                result.add(data);
-
-                return result;
-            }
-        };
-}
diff --git a/src/com/android/settings/HighlightingFragment.java b/src/com/android/settings/HighlightingFragment.java
deleted file mode 100644
index 2d305e7..0000000
--- a/src/com/android/settings/HighlightingFragment.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2014 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;
-
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.text.TextUtils;
-import android.view.View;
-import android.view.ViewGroup;
-
-public abstract class HighlightingFragment extends InstrumentedFragment {
-
-    private static final String TAG = "HighlightSettingsFragment";
-
-    private static final int DELAY_HIGHLIGHT_DURATION_MILLIS = 400;
-    private static final String SAVE_HIGHLIGHTED_KEY = "android:view_highlighted";
-
-    private String mViewKey;
-    private boolean mViewHighlighted = false;
-    private Drawable mHighlightDrawable;
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        if (icicle != null) {
-            mViewHighlighted = icicle.getBoolean(SAVE_HIGHLIGHTED_KEY);
-        }
-    }
-
-    @Override
-    public void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-
-        outState.putBoolean(SAVE_HIGHLIGHTED_KEY, mViewHighlighted);
-    }
-
-    @Override
-    public void onActivityCreated(Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-
-        final Bundle args = getArguments();
-        if (args != null) {
-            mViewKey = args.getString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY);
-            highlightViewIfNeeded();
-        }
-    }
-
-    public void highlightViewIfNeeded() {
-        if (!mViewHighlighted &&!TextUtils.isEmpty(mViewKey)) {
-            highlightView(mViewKey);
-        }
-    }
-
-    private Drawable getHighlightDrawable() {
-        if (mHighlightDrawable == null) {
-            mHighlightDrawable = getActivity().getDrawable(R.drawable.preference_highlight);
-        }
-        return mHighlightDrawable;
-    }
-
-    private void highlightView(String key) {
-        final Drawable highlight = getHighlightDrawable();
-
-        // Try locating the View thru its Tag / Key
-        final View view = findViewForKey(getView(), key);
-        if (view != null ) {
-            view.setBackground(highlight);
-
-            getView().postDelayed(new Runnable() {
-                @Override
-                public void run() {
-                    final int centerX = view.getWidth() / 2;
-                    final int centerY = view.getHeight() / 2;
-                    highlight.setHotspot(centerX, centerY);
-                    view.setPressed(true);
-                    view.setPressed(false);
-                }
-            }, DELAY_HIGHLIGHT_DURATION_MILLIS);
-
-            mViewHighlighted = true;
-        }
-    }
-
-    private View findViewForKey(View root, String key) {
-        if (checkTag(root, key)) {
-            return root;
-        }
-        if (root instanceof ViewGroup) {
-            final ViewGroup group = (ViewGroup) root;
-            final int count = group.getChildCount();
-            for (int n = 0; n < count; n++) {
-                final View child = group.getChildAt(n);
-                final View view = findViewForKey(child, key);
-                if (view != null) {
-                    return view;
-                }
-            }
-        }
-        return null;
-    }
-
-    private boolean checkTag(View view, String key) {
-        final Object tag = view.getTag(R.id.preference_highlight_key);
-        if (tag == null || !(tag instanceof String)) {
-            return false;
-        }
-        final String viewKey = (String) tag;
-        return (!TextUtils.isEmpty(viewKey) && viewKey.equals(key));
-    }
-}
diff --git a/src/com/android/settings/InstrumentedFragment.java b/src/com/android/settings/InstrumentedFragment.java
index 2d39961..58b8eb0 100644
--- a/src/com/android/settings/InstrumentedFragment.java
+++ b/src/com/android/settings/InstrumentedFragment.java
@@ -34,6 +34,9 @@
     public static final int CONFIGURE_WIFI = UNDECLARED + 4;
     public static final int DISPLAY_SCREEN_ZOOM = UNDECLARED + 5;
     public static final int ACCESSIBILITY_FONT_SIZE = UNDECLARED + 6;
+    public static final int DATA_USAGE_LIST = UNDECLARED + 7;
+    public static final int BILLING_CYCLE = UNDECLARED + 8;
+    public static final int APP_DATA_USAGE = UNDECLARED + 9;
 
     /**
      * Declare the view of this category.
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index de66aea..dab2cb7 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -68,6 +68,7 @@
 import com.android.settings.bluetooth.BluetoothSettings;
 import com.android.settings.dashboard.DashboardSummary;
 import com.android.settings.dashboard.SearchResultsSummary;
+import com.android.settings.datausage.DataUsageSummary;
 import com.android.settings.deviceinfo.PrivateVolumeForget;
 import com.android.settings.deviceinfo.PrivateVolumeSettings;
 import com.android.settings.deviceinfo.PublicVolumeSettings;
@@ -85,9 +86,9 @@
 import com.android.settings.notification.AppNotificationSettings;
 import com.android.settings.notification.ConfigureNotificationSettings;
 import com.android.settings.notification.NotificationAccessSettings;
-import com.android.settings.notification.SoundSettings;
 import com.android.settings.notification.NotificationStation;
 import com.android.settings.notification.OtherSoundSettings;
+import com.android.settings.notification.SoundSettings;
 import com.android.settings.notification.ZenAccessSettings;
 import com.android.settings.notification.ZenModeAutomationSettings;
 import com.android.settings.notification.ZenModeEventRuleSettings;
diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java
index f79def9..2ba49ce 100644
--- a/src/com/android/settings/SettingsPreferenceFragment.java
+++ b/src/com/android/settings/SettingsPreferenceFragment.java
@@ -24,7 +24,6 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.pm.PackageManager;
-import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceGroup;
@@ -187,6 +186,11 @@
         setEmptyView(loading);
     }
 
+    public void setLoading(boolean loading, boolean animate) {
+        View loading_container = getView().findViewById(R.id.loading_container);
+        Utils.handleLoadingContainer(loading_container, getListView(), !loading, animate);
+    }
+
     public void registerObserverIfNeeded() {
         if (!mIsDataSetObserverRegistered) {
             if (mCurrentRootAdapter != null) {
diff --git a/src/com/android/settings/SummaryPreference.java b/src/com/android/settings/SummaryPreference.java
new file mode 100644
index 0000000..0943a2b
--- /dev/null
+++ b/src/com/android/settings/SummaryPreference.java
@@ -0,0 +1,99 @@
+/*
+ * 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;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.TextView;
+import com.android.settings.applications.LinearColorBar;
+
+/**
+ * Provides a summary of a setting page in a preference.  Such as memory or data usage.
+ */
+public class SummaryPreference extends Preference {
+
+    private static final String TAG = "SummaryPreference";
+    private String mAmount;
+    private String mUnits;
+
+    private int mLeft, mMiddle, mRight;
+    private float mLeftRatio, mMiddleRatio, mRightRatio;
+    private String mStartLabel;
+    private String mEndLabel;
+
+    public SummaryPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        setLayoutResource(R.layout.settings_summary_preference);
+        mLeft = context.getColor(R.color.summary_default_start);
+        mRight = context.getColor(R.color.summary_default_end);
+    }
+
+    public void setAmount(String amount) {
+        mAmount = amount;
+        if (mAmount != null && mUnits != null) {
+            setTitle(TextUtils.expandTemplate(getContext().getText(R.string.storage_size_large),
+                    mAmount, mUnits));
+        }
+    }
+
+    public void setUnits(String units) {
+        mUnits = units;
+        if (mAmount != null && mUnits != null) {
+            setTitle(TextUtils.expandTemplate(getContext().getText(R.string.storage_size_large),
+                    mAmount, mUnits));
+        }
+    }
+
+    public void setLabels(String start, String end) {
+        mStartLabel = start;
+        mEndLabel = end;
+        notifyChanged();
+    }
+
+    public void setRatios(float left, float middle, float right) {
+        mLeftRatio = left;
+        mMiddleRatio = middle;
+        mRightRatio = right;
+        notifyChanged();
+    }
+
+    public void setColors(int left, int middle, int right) {
+        mLeft = left;
+        mMiddle = middle;
+        mRight = right;
+        notifyChanged();
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+
+        LinearColorBar colorBar = (LinearColorBar) holder.itemView.findViewById(R.id.color_bar);
+        colorBar.setRatios(mLeftRatio, mMiddleRatio, mRightRatio);
+        colorBar.setColors(mLeft, mMiddle, mRight);
+
+        if (!TextUtils.isEmpty(mStartLabel) || !TextUtils.isEmpty(mEndLabel)) {
+            holder.findViewById(R.id.label_bar).setVisibility(View.VISIBLE);
+            ((TextView) holder.findViewById(android.R.id.text1)).setText(mStartLabel);
+            ((TextView) holder.findViewById(android.R.id.text2)).setText(mEndLabel);
+        } else {
+            holder.findViewById(R.id.label_bar).setVisibility(View.GONE);
+        }
+    }
+}
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 4afa1d9..96d0a37 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -67,6 +67,7 @@
 import android.text.Spannable;
 import android.text.SpannableString;
 import android.text.TextUtils;
+import android.text.format.DateUtils;
 import android.text.style.TtsSpan;
 import android.util.ArraySet;
 import android.util.Log;
@@ -81,6 +82,7 @@
 import android.widget.ListView;
 import android.widget.TabWidget;
 import com.android.internal.util.UserIcons;
+import com.android.settings.datausage.DataUsageList;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -91,6 +93,8 @@
 import java.util.Locale;
 
 import static android.content.Intent.EXTRA_USER;
+import static android.text.format.DateUtils.FORMAT_ABBREV_MONTH;
+import static android.text.format.DateUtils.FORMAT_SHOW_DATE;
 
 public final class Utils extends com.android.settingslib.Utils {
 
@@ -978,5 +982,19 @@
         context.getTheme().resolveAttribute(attr, value, true);
         return value.resourceId;
     }
+
+    private static final StringBuilder sBuilder = new StringBuilder(50);
+    private static final java.util.Formatter sFormatter = new java.util.Formatter(
+            sBuilder, Locale.getDefault());
+
+    public static String formatDateRange(Context context, long start, long end) {
+        final int flags = FORMAT_SHOW_DATE | FORMAT_ABBREV_MONTH;
+
+        synchronized (sBuilder) {
+            sBuilder.setLength(0);
+            return DateUtils.formatDateRange(context, sFormatter, start, end, flags, null)
+                    .toString();
+        }
+    }
 }
 
diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java
index 7d8a7f0..42d8e46 100755
--- a/src/com/android/settings/applications/InstalledAppDetails.java
+++ b/src/com/android/settings/applications/InstalledAppDetails.java
@@ -21,7 +21,6 @@
 import android.app.AlertDialog;
 import android.app.LoaderManager.LoaderCallbacks;
 import android.app.admin.DevicePolicyManager;
-import android.icu.text.ListFormatter;
 import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -37,6 +36,7 @@
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
+import android.icu.text.ListFormatter;
 import android.net.INetworkStatsService;
 import android.net.INetworkStatsSession;
 import android.net.NetworkTemplate;
@@ -63,16 +63,17 @@
 import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.TextView;
-
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.os.BatterySipper;
 import com.android.internal.os.BatteryStatsHelper;
 import com.android.settings.AppHeader;
-import com.android.settings.DataUsageSummary;
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.Utils;
 import com.android.settings.applications.PermissionsSummaryHelper.PermissionsResultCallback;
+import com.android.settings.datausage.AppDataUsage;
+import com.android.settings.datausage.DataUsageList;
+import com.android.settings.datausage.DataUsageSummary;
 import com.android.settings.fuelgauge.BatteryEntry;
 import com.android.settings.fuelgauge.PowerUsageDetail;
 import com.android.settings.notification.AppNotificationSettings;
@@ -753,13 +754,7 @@
             ProcessStatsBase.launchMemoryDetail((SettingsActivity) getActivity(),
                     mStatsManager.getMemInfo(), mStats, false);
         } else if (preference == mDataPreference) {
-            Bundle args = new Bundle();
-            args.putString(DataUsageSummary.EXTRA_SHOW_APP_IMMEDIATE_PKG,
-                    mAppEntry.info.packageName);
-
-            SettingsActivity sa = (SettingsActivity) getActivity();
-            sa.startPreferencePanel(DataUsageSummary.class.getName(), args, -1,
-                    getString(R.string.app_data_usage), this, SUB_INFO_FRAGMENT);
+            startAppInfoFragment(AppDataUsage.class, getString(R.string.app_data_usage));
         } else if (preference == mBatteryPreference) {
             BatteryEntry entry = new BatteryEntry(getActivity(), null, mUserManager, mSipper);
             PowerUsageDetail.startBatteryDetailPage((SettingsActivity) getActivity(),
@@ -794,7 +789,7 @@
     }
 
     public static NetworkTemplate getTemplate(Context context) {
-        if (DataUsageSummary.hasReadyMobileRadio(context)) {
+        if (DataUsageList.hasReadyMobileRadio(context)) {
             return NetworkTemplate.buildTemplateMobileWildcard();
         }
         if (DataUsageSummary.hasWifiRadio(context)) {
diff --git a/src/com/android/settings/applications/ProcessStatsDetail.java b/src/com/android/settings/applications/ProcessStatsDetail.java
index 9db79bc..4ad480e 100644
--- a/src/com/android/settings/applications/ProcessStatsDetail.java
+++ b/src/com/android/settings/applications/ProcessStatsDetail.java
@@ -40,14 +40,13 @@
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
-import android.widget.TextView;
-
 import com.android.internal.logging.MetricsLogger;
 import com.android.settings.AppHeader;
 import com.android.settings.CancellablePreference;
 import com.android.settings.CancellablePreference.OnCancelListener;
 import com.android.settings.R;
 import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.SummaryPreference;
 import com.android.settings.applications.ProcStatsEntry.Service;
 
 import java.util.ArrayList;
@@ -87,8 +86,6 @@
     private long mTotalTime;
     private long mOnePercentTime;
 
-    private LinearColorBar mColorBar;
-
     private double mMaxMemoryUsage;
 
     private double mTotalScale;
@@ -177,20 +174,19 @@
         mProcGroup = (PreferenceCategory) findPreference(KEY_PROCS);
         fillProcessesSection();
 
-        LayoutPreference headerLayout = (LayoutPreference) findPreference(KEY_DETAILS_HEADER);
+        SummaryPreference summaryPreference = (SummaryPreference) findPreference(KEY_DETAILS_HEADER);
 
         // TODO: Find way to share this code with ProcessStatsPreference.
         boolean statsForeground = mApp.mRunWeight > mApp.mBgWeight;
         double avgRam = (statsForeground ? mApp.mRunWeight : mApp.mBgWeight) * mWeightToRam;
         float avgRatio = (float) (avgRam / mMaxMemoryUsage);
         float remainingRatio = 1 - avgRatio;
-        mColorBar = (LinearColorBar) headerLayout.findViewById(R.id.color_bar);
         Context context = getActivity();
-        mColorBar.setColors( context.getColor(R.color.memory_max_use), 0,
-                context.getColor(R.color.memory_remaining));
-        mColorBar.setRatios(avgRatio, 0, remainingRatio);
-        ((TextView) headerLayout.findViewById(R.id.memory_state)).setText(
-                Formatter.formatShortFileSize(getContext(), (long) avgRam));
+        summaryPreference.setRatios(avgRatio, 0, remainingRatio);
+        Formatter.BytesResult usedResult = Formatter.formatBytes(context.getResources(),
+                (long) avgRam, Formatter.FLAG_SHORTER);
+        summaryPreference.setAmount(usedResult.value);
+        summaryPreference.setUnits(usedResult.units);
 
         long duration = Math.max(mApp.mRunDuration, mApp.mBgDuration);
         CharSequence frequency = ProcStatsPackageEntry.getFrequency(duration
diff --git a/src/com/android/settings/applications/ProcessStatsSummary.java b/src/com/android/settings/applications/ProcessStatsSummary.java
index 09fea89..28917c8 100644
--- a/src/com/android/settings/applications/ProcessStatsSummary.java
+++ b/src/com/android/settings/applications/ProcessStatsSummary.java
@@ -16,18 +16,15 @@
 package com.android.settings.applications;
 
 import android.app.Activity;
-import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.os.Bundle;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.Preference.OnPreferenceClickListener;
-import android.text.TextUtils;
 import android.text.format.Formatter;
 import android.text.format.Formatter.BytesResult;
-import android.widget.TextView;
-
 import com.android.internal.logging.MetricsLogger;
 import com.android.settings.R;
+import com.android.settings.SummaryPreference;
 import com.android.settings.Utils;
 import com.android.settings.applications.ProcStatsData.MemInfo;
 import com.android.settings.dashboard.SummaryLoader;
@@ -42,9 +39,7 @@
     private static final String KEY_FREE = "free";
     private static final String KEY_APP_LIST = "apps_list";
 
-    private LinearColorBar mColors;
-    private LayoutPreference mHeader;
-    private TextView mMemStatus;
+    private SummaryPreference mSummaryPref;
 
     private Preference mPerformance;
     private Preference mTotalMemory;
@@ -57,9 +52,10 @@
         super.onCreate(icicle);
 
         addPreferencesFromResource(R.xml.process_stats_summary);
-        mHeader = (LayoutPreference) findPreference(KEY_STATUS_HEADER);
-        mMemStatus = (TextView) mHeader.findViewById(R.id.memory_state);
-        mColors = (LinearColorBar) mHeader.findViewById(R.id.color_bar);
+        mSummaryPref = (SummaryPreference) findPreference(KEY_STATUS_HEADER);
+        int memColor = getContext().getColor(R.color.running_processes_apps_ram);
+        mSummaryPref.setColors(memColor, memColor,
+                getContext().getColor(R.color.running_processes_free_ram));
 
         mPerformance = findPreference(KEY_PERFORMANCE);
         mTotalMemory = findPreference(KEY_TOTAL_MEMORY);
@@ -72,8 +68,6 @@
     @Override
     public void refreshUi() {
         Context context = getContext();
-        int memColor = context.getColor(R.color.running_processes_apps_ram);
-        mColors.setColors(memColor, memColor, context.getColor(R.color.running_processes_free_ram));
 
         MemInfo memInfo = mStatsManager.getMemInfo();
 
@@ -92,10 +86,10 @@
         } else {
             memString = memStatesStr[memStatesStr.length - 1];
         }
-        mMemStatus.setText(TextUtils.expandTemplate(getText(R.string.storage_size_large),
-                usedResult.value, usedResult.units));
+        mSummaryPref.setAmount(usedResult.value);
+        mSummaryPref.setUnits(usedResult.units);
         float usedRatio = (float)(usedRam / (freeRam + usedRam));
-        mColors.setRatios(usedRatio, 0, 1 - usedRatio);
+        mSummaryPref.setRatios(usedRatio, 0, 1 - usedRatio);
 
         mPerformance.setSummary(memString);
         mTotalMemory.setSummary(totalString);
diff --git a/src/com/android/settings/datausage/AppDataUsage.java b/src/com/android/settings/datausage/AppDataUsage.java
new file mode 100644
index 0000000..9ca066f
--- /dev/null
+++ b/src/com/android/settings/datausage/AppDataUsage.java
@@ -0,0 +1,343 @@
+/*
+ * 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 com.android.settings.AppHeader;
+import com.android.settings.InstrumentedFragment;
+import com.android.settings.R;
+import com.android.settings.applications.AppInfoBase;
+import com.android.settingslib.AppItem;
+import com.android.settingslib.net.ChartData;
+import com.android.settingslib.net.ChartDataLoader;
+
+import android.app.LoaderManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.Loader;
+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.AsyncTask;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceCategory;
+import android.text.format.Formatter;
+import android.util.ArraySet;
+import android.util.Log;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.Spinner;
+
+import static android.net.NetworkPolicyManager.POLICY_NONE;
+import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
+
+public class AppDataUsage extends DataUsageBase implements Preference.OnPreferenceChangeListener {
+
+    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 int LOADER_CHART_DATA = 2;
+
+    private final ArraySet<String> mPackages = new ArraySet<>();
+    private Preference mTotalUsage;
+    private Preference mForegroundUsage;
+    private Preference mBackgroundUsage;
+    private Preference mAppSettings;
+    private SwitchPreference mRestrictBackground;
+    private PreferenceCategory mAppList;
+
+    private Drawable mIcon;
+    private CharSequence mLabel;
+    private INetworkStatsSession mStatsSession;
+    private Spinner mCycleSpinner;
+    private CycleAdapter mCycleAdapter;
+
+    private long mStart;
+    private long mEnd;
+    private ChartData mChartData;
+    private NetworkTemplate mTemplate;
+    private NetworkPolicy mPolicy;
+    private AppItem mAppItem;
+    private Intent mAppSettingsIntent;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        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 = DataUsageSummary.getDefaultTemplate(context,
+                    DataUsageSummary.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));
+            }
+        }
+        if (mPackages.size() != 0) {
+            PackageManager pm = getPackageManager();
+            try {
+                ApplicationInfo info = pm.getApplicationInfo(mPackages.valueAt(0), 0);
+                mIcon = info.loadIcon(pm);
+                mLabel = info.loadLabel(pm);
+            } catch (PackageManager.NameNotFoundException e) {
+            }
+        }
+        addPreferencesFromResource(R.xml.app_data_usage);
+
+        mTotalUsage = findPreference(KEY_TOTAL_USAGE);
+        mForegroundUsage = findPreference(KEY_FOREGROUND_USAGE);
+        mBackgroundUsage = findPreference(KEY_BACKGROUND_USAGE);
+
+        if (UserHandle.isApp(mAppItem.key)) {
+            mRestrictBackground = (SwitchPreference) findPreference(KEY_RESTRICT_BACKGROUND);
+            mRestrictBackground.setOnPreferenceChangeListener(this);
+            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);
+                for (int i = 1 ; i < mPackages.size(); i++) {
+                    new AppPrefLoader().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
+                            mPackages.valueAt(i));
+                }
+            } else {
+                removePreference(KEY_APP_LIST);
+            }
+        } else {
+            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();
+        mPolicy = services.mPolicyEditor.getPolicy(mTemplate);
+        getLoaderManager().restartLoader(LOADER_CHART_DATA,
+                ChartDataLoader.buildArgs(mTemplate, mAppItem), mChartDataCallbacks);
+        updatePrefs();
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        if (preference == mRestrictBackground) {
+            setAppRestrictBackground((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);
+    }
+
+    private void updatePrefs() {
+        if (mRestrictBackground != null) {
+            mRestrictBackground.setChecked(getAppRestrictBackground());
+        }
+    }
+
+    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() {
+        if (mChartData == null || mStart == 0) {
+            return;
+        }
+        final Context context = getContext();
+        final long now = System.currentTimeMillis();
+
+        NetworkStatsHistory.Entry entry = null;
+        entry = mChartData.detailDefault.getValues(mStart, mEnd, now, entry);
+        final long backgroundBytes = entry.rxBytes + entry.txBytes;
+        entry = mChartData.detailForeground.getValues(mStart, mEnd, now, entry);
+        final long foregroundBytes = entry.rxBytes + entry.txBytes;
+        final long totalBytes = backgroundBytes + foregroundBytes;
+
+        mTotalUsage.setSummary(Formatter.formatFileSize(context, totalBytes));
+        mForegroundUsage.setSummary(Formatter.formatFileSize(context, foregroundBytes));
+        mBackgroundUsage.setSummary(Formatter.formatFileSize(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 void setAppRestrictBackground(boolean restrictBackground) {
+        final int uid = mAppItem.key;
+        services.mPolicyManager.setUidPolicy(
+                uid, restrictBackground ? POLICY_REJECT_METERED_BACKGROUND : POLICY_NONE);
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+
+        View header = setPinnedHeaderView(R.layout.data_usage_app_header);
+        String pkg = mPackages.size() != 0 ? mPackages.valueAt(0) : null;
+        int uid = 0;
+        try {
+            uid = pkg != null ? getPackageManager().getPackageUid(pkg, 0) : 0;
+        } catch (PackageManager.NameNotFoundException e) {
+        }
+        AppHeader.setupHeaderView(getActivity(), mIcon, mLabel,
+                pkg, uid, AppHeader.includeAppInfo(this), 0, header);
+
+        mCycleSpinner = (Spinner) header.findViewById(R.id.filter_spinner);
+        mCycleAdapter = new CycleAdapter(getContext(), mCycleSpinner, mCycleListener);
+    }
+
+    @Override
+    protected int getMetricsCategory() {
+        return InstrumentedFragment.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) parent.getItemAtPosition(position);
+
+            mStart = cycle.start;
+            mEnd = cycle.end;
+            bindData();
+        }
+
+        @Override
+        public void onNothingSelected(AdapterView<?> parent) {
+            // ignored
+        }
+    };
+
+    private final LoaderManager.LoaderCallbacks<ChartData> mChartDataCallbacks =
+            new LoaderManager.LoaderCallbacks<ChartData>() {
+        @Override
+        public Loader<ChartData> onCreateLoader(int id, Bundle args) {
+            return new ChartDataLoader(getActivity(), mStatsSession, args);
+        }
+
+        @Override
+        public void onLoadFinished(Loader<ChartData> loader, ChartData data) {
+            mChartData = data;
+            mCycleAdapter.updateCycleList(mPolicy, mChartData);
+            bindData();
+        }
+
+        @Override
+        public void onLoaderReset(Loader<ChartData> loader) {
+        }
+    };
+
+    private class AppPrefLoader extends AsyncTask<String, Void, Preference> {
+        @Override
+        protected Preference doInBackground(String... params) {
+            PackageManager pm = getPackageManager();
+            String pkg = params[0];
+            try {
+                ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
+                Preference preference = new Preference(getPrefContext());
+                preference.setIcon(info.loadIcon(pm));
+                preference.setTitle(info.loadLabel(pm));
+                preference.setSelectable(false);
+                return preference;
+            } catch (PackageManager.NameNotFoundException e) {
+            }
+            return null;
+        }
+
+        @Override
+        protected void onPostExecute(Preference pref) {
+            if (pref != null && mAppList != null) {
+                mAppList.addPreference(pref);
+            }
+        }
+    }
+}
diff --git a/src/com/android/settings/datausage/AppDataUsagePreference.java b/src/com/android/settings/datausage/AppDataUsagePreference.java
new file mode 100644
index 0000000..04e2b6d
--- /dev/null
+++ b/src/com/android/settings/datausage/AppDataUsagePreference.java
@@ -0,0 +1,123 @@
+/*
+ * 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 android.content.Context;
+import android.os.AsyncTask;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.text.format.Formatter;
+import android.view.View;
+import android.widget.ProgressBar;
+import com.android.settingslib.AppItem;
+import com.android.settingslib.net.UidDetail;
+import com.android.settingslib.net.UidDetailProvider;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+public class AppDataUsagePreference extends Preference {
+
+    private final AppItem mItem;
+    private final int mPercent;
+
+    public AppDataUsagePreference(Context context, AppItem item, int percent,
+            UidDetailProvider provider) {
+        super(context);
+        mItem = item;
+        mPercent = percent;
+        setLayoutResource(com.android.settings.R.layout.data_usage_item);
+        setWidgetLayoutResource(com.android.settings.R.layout.widget_progress_bar);
+        if (item.restricted && item.total <= 0) {
+            setSummary(com.android.settings.R.string.data_usage_app_restricted);
+        } else {
+            setSummary(Formatter.formatFileSize(context, item.total));
+        }
+
+        // kick off async load of app details
+        UidDetailTask.bindView(provider, item, this);
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+
+        final ProgressBar progress = (ProgressBar) holder.findViewById(
+                android.R.id.progress);
+
+        if (mItem.restricted && mItem.total <= 0) {
+            progress.setVisibility(View.GONE);
+        } else {
+            progress.setVisibility(View.VISIBLE);
+        }
+        progress.setProgress(mPercent);
+    }
+
+    public AppItem getItem() {
+        return mItem;
+    }
+
+    /**
+     * Background task that loads {@link UidDetail}, binding to
+     * {@link DataUsageAdapter} row item when finished.
+     */
+    private static class UidDetailTask extends AsyncTask<Void, Void, UidDetail> {
+        private final UidDetailProvider mProvider;
+        private final AppItem mItem;
+        private final AppDataUsagePreference mTarget;
+
+        private UidDetailTask(UidDetailProvider provider, AppItem item,
+                AppDataUsagePreference target) {
+            mProvider = checkNotNull(provider);
+            mItem = checkNotNull(item);
+            mTarget = checkNotNull(target);
+        }
+
+        public static void bindView(UidDetailProvider provider, AppItem item,
+                AppDataUsagePreference target) {
+            final UidDetail cachedDetail = provider.getUidDetail(item.key, false);
+            if (cachedDetail != null) {
+                bindView(cachedDetail, target);
+            } else {
+                new UidDetailTask(provider, item, target).executeOnExecutor(
+                        AsyncTask.THREAD_POOL_EXECUTOR);
+            }
+        }
+
+        private static void bindView(UidDetail detail, Preference target) {
+            if (detail != null) {
+                target.setIcon(detail.icon);
+                target.setTitle(detail.label);
+            } else {
+                target.setIcon(null);
+                target.setTitle(null);
+            }
+        }
+
+        @Override
+        protected void onPreExecute() {
+            bindView(null, mTarget);
+        }
+
+        @Override
+        protected UidDetail doInBackground(Void... params) {
+            return mProvider.getUidDetail(mItem.key, true);
+        }
+
+        @Override
+        protected void onPostExecute(UidDetail result) {
+            bindView(result, mTarget);
+        }
+    }
+}
diff --git a/src/com/android/settings/datausage/BillingCyclePreference.java b/src/com/android/settings/datausage/BillingCyclePreference.java
new file mode 100644
index 0000000..84eaabb
--- /dev/null
+++ b/src/com/android/settings/datausage/BillingCyclePreference.java
@@ -0,0 +1,90 @@
+/*
+ * 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 android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.NetworkPolicy;
+import android.net.NetworkTemplate;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.support.v7.preference.Preference;
+import android.util.AttributeSet;
+import com.android.settings.R;
+import com.android.settings.Utils;
+
+public class BillingCyclePreference extends Preference implements TemplatePreference {
+
+    private NetworkTemplate mTemplate;
+    private NetworkServices mServices;
+    private NetworkPolicy mPolicy;
+    private int mSubId;
+
+    public BillingCyclePreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    public void onAttached() {
+        super.onAttached();
+        getContext().registerReceiver(mReceiver, new IntentFilter(
+                CellDataPreference.ACTION_DATA_ENABLED_CHANGED));
+    }
+
+    @Override
+    public void onDetached() {
+        getContext().unregisterReceiver(mReceiver);
+        super.onDetached();
+    }
+
+    @Override
+    public void setTemplate(NetworkTemplate template, int subId,
+            NetworkServices services) {
+        mTemplate = template;
+        mSubId = subId;
+        mServices = services;
+        mPolicy = services.mPolicyEditor.getPolicy(mTemplate);
+        setSummary(getContext().getString(R.string.billing_cycle_fragment_summary,
+                mPolicy != null ? mPolicy.cycleDay : 1));
+        setIntent(getIntent());
+    }
+
+    private void updateEnabled() {
+        try {
+            setEnabled(mPolicy != null && mServices.mNetworkService.isBandwidthControlEnabled()
+                    && mServices.mTelephonyManager.getDataEnabled(mSubId)
+                    && mServices.mUserManager.isAdminUser());
+        } catch (RemoteException e) {
+            setEnabled(false);
+        }
+    }
+
+    @Override
+    public Intent getIntent() {
+        Bundle args = new Bundle();
+        args.putParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE, mTemplate);
+        return Utils.onBuildStartFragmentIntent(getContext(), BillingCycleSettings.class.getName(),
+                args, null, 0, getTitle(), false);
+    }
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            updateEnabled();
+        }
+    };
+}
diff --git a/src/com/android/settings/datausage/BillingCycleSettings.java b/src/com/android/settings/datausage/BillingCycleSettings.java
new file mode 100644
index 0000000..5807992
--- /dev/null
+++ b/src/com/android/settings/datausage/BillingCycleSettings.java
@@ -0,0 +1,357 @@
+/*
+ * 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 android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.res.Resources;
+import android.net.NetworkPolicy;
+import android.net.NetworkTemplate;
+import android.os.Bundle;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.text.format.Formatter;
+import android.text.format.Time;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.NumberPicker;
+import com.android.settings.InstrumentedFragment;
+import com.android.settings.R;
+import com.android.settingslib.NetworkPolicyEditor;
+import com.android.settingslib.net.DataUsageController;
+
+import static android.net.NetworkPolicy.LIMIT_DISABLED;
+import static android.net.NetworkPolicy.WARNING_DISABLED;
+import static android.net.TrafficStats.GB_IN_BYTES;
+import static android.net.TrafficStats.MB_IN_BYTES;
+
+public class BillingCycleSettings extends DataUsageBase implements
+        Preference.OnPreferenceChangeListener {
+
+    private static final String TAG = "BillingCycleSettings";
+    private static final boolean LOGD = false;
+
+    private static final String TAG_CONFIRM_LIMIT = "confirmLimit";
+    private static final String TAG_CYCLE_EDITOR = "cycleEditor";
+    private static final String TAG_WARNING_EDITOR = "warningEditor";
+
+    private static final String KEY_BILLING_CYCLE = "billing_cycle";
+    private static final String KEY_DATA_WARNING = "data_warning";
+    private static final String KEY_SET_DATA_LIMIT = "set_data_limit";
+    private static final String KEY_DATA_LIMIT = "data_limit";
+
+    private NetworkTemplate mNetworkTemplate;
+    private Preference mBillingCycle;
+    private Preference mDataWarning;
+    private SwitchPreference mEnableDataLimit;
+    private Preference mDataLimit;
+    private DataUsageController mDataUsageController;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        mDataUsageController = new DataUsageController(getContext());
+
+        Bundle args = getArguments();
+        mNetworkTemplate = args.getParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE);
+
+        addPreferencesFromResource(R.xml.billing_cycle);
+        mBillingCycle = findPreference(KEY_BILLING_CYCLE);
+        mDataWarning = findPreference(KEY_DATA_WARNING);
+        mEnableDataLimit = (SwitchPreference) findPreference(KEY_SET_DATA_LIMIT);
+        mEnableDataLimit.setOnPreferenceChangeListener(this);
+        mDataLimit = findPreference(KEY_DATA_LIMIT);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        updatePrefs();
+    }
+
+    private void updatePrefs() {
+        NetworkPolicy policy = services.mPolicyEditor.getPolicy(mNetworkTemplate);
+        mBillingCycle.setSummary(getString(R.string.billing_cycle_summary, policy != null ?
+                policy.cycleDay : 1));
+        mDataWarning.setSummary(Formatter.formatFileSize(getContext(), policy != null
+                ? policy.warningBytes : DataUsageController.DEFAULT_WARNING_LEVEL));
+        if (policy != null && policy.limitBytes != LIMIT_DISABLED) {
+            mDataLimit.setSummary(Formatter.formatFileSize(getContext(), policy.limitBytes));
+            mDataLimit.setEnabled(true);
+            mEnableDataLimit.setChecked(true);
+        } else {
+            mDataLimit.setSummary(null);
+            mDataLimit.setEnabled(false);
+            mEnableDataLimit.setChecked(false);
+        }
+    }
+
+    @Override
+    public boolean onPreferenceTreeClick(Preference preference) {
+        if (preference == mBillingCycle) {
+            CycleEditorFragment.show(this);
+            return true;
+        } else if (preference == mDataWarning) {
+            BytesEditorFragment.show(this, false);
+            return true;
+        } else if (preference == mDataLimit) {
+            BytesEditorFragment.show(this, true);
+            return true;
+        }
+        return super.onPreferenceTreeClick(preference);
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        if (mEnableDataLimit == preference) {
+            boolean enabled = (Boolean) newValue;
+            if (enabled) {
+                ConfirmLimitFragment.show(this);
+            } else {
+                setPolicyLimitBytes(LIMIT_DISABLED);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    protected int getMetricsCategory() {
+        return InstrumentedFragment.BILLING_CYCLE;
+    }
+
+    private void setPolicyLimitBytes(long limitBytes) {
+        if (LOGD) Log.d(TAG, "setPolicyLimitBytes()");
+        services.mPolicyEditor.setPolicyLimitBytes(mNetworkTemplate, limitBytes);
+        updatePrefs();
+    }
+
+    /**
+     * Dialog to edit {@link NetworkPolicy#warningBytes}.
+     */
+    public static class BytesEditorFragment extends DialogFragment
+            implements DialogInterface.OnClickListener{
+        private static final String EXTRA_TEMPLATE = "template";
+        private static final String EXTRA_LIMIT = "limit";
+        private View mView;
+
+        public static void show(BillingCycleSettings parent, boolean isLimit) {
+            if (!parent.isAdded()) return;
+
+            final Bundle args = new Bundle();
+            args.putParcelable(EXTRA_TEMPLATE, parent.mNetworkTemplate);
+            args.putBoolean(EXTRA_LIMIT, isLimit);
+
+            final BytesEditorFragment dialog = new BytesEditorFragment();
+            dialog.setArguments(args);
+            dialog.setTargetFragment(parent, 0);
+            dialog.show(parent.getFragmentManager(), TAG_WARNING_EDITOR);
+        }
+
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            final Context context = getActivity();
+
+
+            final LayoutInflater dialogInflater = LayoutInflater.from(context);
+            mView = dialogInflater.inflate(R.layout.data_usage_bytes_editor, null, false);
+            setupPicker((NumberPicker) mView.findViewById(R.id.bytes));
+            return new AlertDialog.Builder(context)
+                    .setTitle(R.string.data_usage_warning_editor_title)
+                    .setView(mView)
+                    .setPositiveButton(R.string.data_usage_cycle_editor_positive, this)
+                    .create();
+        }
+
+        private void setupPicker(NumberPicker bytesPicker) {
+            final BillingCycleSettings target = (BillingCycleSettings) getTargetFragment();
+            final NetworkPolicyEditor editor = target.services.mPolicyEditor;
+
+            final NetworkTemplate template = getArguments().getParcelable(EXTRA_TEMPLATE);
+            final boolean isLimit = getArguments().getBoolean(EXTRA_LIMIT);
+            final long warningBytes = editor.getPolicyWarningBytes(template);
+            final long limitBytes = editor.getPolicyLimitBytes(template);
+
+            if (isLimit) {
+                bytesPicker.setMaxValue(Integer.MAX_VALUE);
+                if (warningBytes != WARNING_DISABLED) {
+                    bytesPicker.setMinValue((int) (warningBytes / MB_IN_BYTES) + 1);
+                } else {
+                    bytesPicker.setMinValue(0);
+                }
+            } else {
+                bytesPicker.setMinValue(0);
+                if (limitBytes != LIMIT_DISABLED) {
+                    bytesPicker.setMaxValue((int) (limitBytes / MB_IN_BYTES) - 1);
+                } else {
+                    bytesPicker.setMaxValue(Integer.MAX_VALUE);
+                }
+            }
+            bytesPicker.setValue((int) ((isLimit ? limitBytes : warningBytes) / MB_IN_BYTES));
+            bytesPicker.setWrapSelectorWheel(false);
+        }
+
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            if (which != DialogInterface.BUTTON_POSITIVE) {
+                return;
+            }
+            final BillingCycleSettings target = (BillingCycleSettings) getTargetFragment();
+            final NetworkPolicyEditor editor = target.services.mPolicyEditor;
+
+            final NetworkTemplate template = getArguments().getParcelable(EXTRA_TEMPLATE);
+            final boolean isLimit = getArguments().getBoolean(EXTRA_LIMIT);
+            NumberPicker bytesPicker = (NumberPicker) mView.findViewById(R.id.bytes);
+            // clear focus to finish pending text edits
+            bytesPicker.clearFocus();
+
+            final long bytes = bytesPicker.getValue() * MB_IN_BYTES;
+            if (isLimit) {
+                editor.setPolicyLimitBytes(template, bytes);
+            } else {
+                editor.setPolicyWarningBytes(template, bytes);
+            }
+            target.updatePrefs();
+        }
+    }
+
+    /**
+     * Dialog to edit {@link NetworkPolicy#cycleDay}.
+     */
+    public static class CycleEditorFragment extends DialogFragment implements
+            DialogInterface.OnClickListener{
+        private static final String EXTRA_TEMPLATE = "template";
+        private NumberPicker mCycleDayPicker;
+
+        public static void show(BillingCycleSettings parent) {
+            if (!parent.isAdded()) return;
+
+            final Bundle args = new Bundle();
+            args.putParcelable(EXTRA_TEMPLATE, parent.mNetworkTemplate);
+
+            final CycleEditorFragment dialog = new CycleEditorFragment();
+            dialog.setArguments(args);
+            dialog.setTargetFragment(parent, 0);
+            dialog.show(parent.getFragmentManager(), TAG_CYCLE_EDITOR);
+        }
+
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            final Context context = getActivity();
+            final BillingCycleSettings target = (BillingCycleSettings) getTargetFragment();
+            final NetworkPolicyEditor editor = target.services.mPolicyEditor;
+
+            final AlertDialog.Builder builder = new AlertDialog.Builder(context);
+            final LayoutInflater dialogInflater = LayoutInflater.from(builder.getContext());
+
+            final View view = dialogInflater.inflate(R.layout.data_usage_cycle_editor, null, false);
+            mCycleDayPicker = (NumberPicker) view.findViewById(R.id.cycle_day);
+
+            final NetworkTemplate template = getArguments().getParcelable(EXTRA_TEMPLATE);
+            final int cycleDay = editor.getPolicyCycleDay(template);
+
+            mCycleDayPicker.setMinValue(1);
+            mCycleDayPicker.setMaxValue(31);
+            mCycleDayPicker.setValue(cycleDay);
+            mCycleDayPicker.setWrapSelectorWheel(true);
+
+            return builder.setTitle(R.string.data_usage_cycle_editor_title)
+                    .setView(view)
+                    .setPositiveButton(R.string.data_usage_cycle_editor_positive, this)
+                    .create();
+        }
+
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            final NetworkTemplate template = getArguments().getParcelable(EXTRA_TEMPLATE);
+            final BillingCycleSettings target = (BillingCycleSettings) getTargetFragment();
+            final NetworkPolicyEditor editor = target.services.mPolicyEditor;
+
+            // clear focus to finish pending text edits
+            mCycleDayPicker.clearFocus();
+
+            final int cycleDay = mCycleDayPicker.getValue();
+            final String cycleTimezone = new Time().timezone;
+            editor.setPolicyCycleDay(template, cycleDay, cycleTimezone);
+            target.updatePrefs();
+        }
+    }
+
+    /**
+     * Dialog to request user confirmation before setting
+     * {@link NetworkPolicy#limitBytes}.
+     */
+    public static class ConfirmLimitFragment extends DialogFragment implements
+            DialogInterface.OnClickListener{
+        private static final String EXTRA_MESSAGE = "message";
+        private static final String EXTRA_LIMIT_BYTES = "limitBytes";
+        public static final float FLOAT = 1.2f;
+
+        public static void show(BillingCycleSettings parent) {
+            if (!parent.isAdded()) return;
+
+            final NetworkPolicy policy = parent.services.mPolicyEditor
+                    .getPolicy(parent.mNetworkTemplate);
+            if (policy == null) return;
+
+            final Resources res = parent.getResources();
+            final CharSequence message;
+            final long minLimitBytes = (long) (policy.warningBytes * FLOAT);
+            final long limitBytes;
+
+            // TODO: customize default limits based on network template
+            message = res.getString(R.string.data_usage_limit_dialog_mobile);
+            limitBytes = Math.max(5 * GB_IN_BYTES, minLimitBytes);
+
+            final Bundle args = new Bundle();
+            args.putCharSequence(EXTRA_MESSAGE, message);
+            args.putLong(EXTRA_LIMIT_BYTES, limitBytes);
+
+            final ConfirmLimitFragment dialog = new ConfirmLimitFragment();
+            dialog.setArguments(args);
+            dialog.setTargetFragment(parent, 0);
+            dialog.show(parent.getFragmentManager(), TAG_CONFIRM_LIMIT);
+        }
+
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            final Context context = getActivity();
+
+            final CharSequence message = getArguments().getCharSequence(EXTRA_MESSAGE);
+
+            return new AlertDialog.Builder(context)
+                    .setTitle(R.string.data_usage_limit_dialog_title)
+                    .setMessage(message)
+                    .setPositiveButton(android.R.string.ok, this)
+                    .setNegativeButton(android.R.string.cancel, null)
+                    .create();
+        }
+
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            if (which != DialogInterface.BUTTON_POSITIVE) return;
+            final long limitBytes = getArguments().getLong(EXTRA_LIMIT_BYTES);
+            final BillingCycleSettings target = (BillingCycleSettings) getTargetFragment();
+            if (target != null) {
+                target.setPolicyLimitBytes(limitBytes);
+            }
+        }
+    }
+}
diff --git a/src/com/android/settings/datausage/CellDataPreference.java b/src/com/android/settings/datausage/CellDataPreference.java
new file mode 100644
index 0000000..0a91be2
--- /dev/null
+++ b/src/com/android/settings/datausage/CellDataPreference.java
@@ -0,0 +1,276 @@
+/*
+ * 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 android.app.AlertDialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.NetworkTemplate;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.widget.Checkable;
+import com.android.internal.logging.MetricsLogger;
+import com.android.settings.CustomDialogPreference;
+import com.android.settings.R;
+import com.android.settings.Utils;
+
+import java.util.List;
+
+public class CellDataPreference extends CustomDialogPreference implements TemplatePreference {
+
+    // TODO: Get Telephony to broadcast when this changes, and remove this.
+    static final String ACTION_DATA_ENABLED_CHANGED =
+            "com.android.settings.action.DATA_ENABLED_CHANGED";
+
+    private static final String TAG = "CellDataPreference";
+
+    public int mSubId;
+    public boolean mChecked;
+    public boolean mMultiSimDialog;
+    private TelephonyManager mTelephonyManager;
+    private SubscriptionManager mSubscriptionManager;
+
+    public CellDataPreference(Context context, AttributeSet attrs) {
+        super(context, attrs, android.R.attr.switchPreferenceStyle);
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable s) {
+        CellDataState state = (CellDataState) s;
+        super.onRestoreInstanceState(state.getSuperState());
+        mTelephonyManager = TelephonyManager.from(getContext());
+        mChecked = state.mChecked;
+        mMultiSimDialog = state.mMultiSimDialog;
+        mSubId = state.mSubId;
+        setKey(getKey() + mSubId);
+        notifyChanged();
+    }
+
+    @Override
+    protected Parcelable onSaveInstanceState() {
+        CellDataState state = new CellDataState(super.onSaveInstanceState());
+        state.mChecked = mChecked;
+        state.mMultiSimDialog = mMultiSimDialog;
+        state.mSubId = mSubId;
+        return state;
+    }
+
+    @Override
+    public void onAttached() {
+        super.onAttached();
+        getContext().registerReceiver(mReceiver, new IntentFilter(ACTION_DATA_ENABLED_CHANGED));
+    }
+
+    @Override
+    public void onDetached() {
+        getContext().unregisterReceiver(mReceiver);
+        super.onDetached();
+    }
+
+    @Override
+    public void setTemplate(NetworkTemplate template, int subId, NetworkServices services) {
+        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            throw new IllegalArgumentException("CellDataPreference needs a SubscriptionInfo");
+        }
+        mTelephonyManager = TelephonyManager.from(getContext());
+        if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            mSubId = subId;
+            setKey(getKey() + subId);
+        }
+        updateChecked();
+    }
+
+    private void updateChecked() {
+        setChecked(mTelephonyManager.getDataEnabled(mSubId));
+    }
+
+    @Override
+    protected void performClick(View view) {
+        super.performClick(view);
+        MetricsLogger.action(getContext(), MetricsLogger.ACTION_CELL_DATA_TOGGLE, !mChecked);
+        if (mChecked) {
+            // disabling data; show confirmation dialog which eventually
+            // calls setMobileDataEnabled() once user confirms.
+            mMultiSimDialog = false;
+            super.performClick(view);
+        } else {
+            // If we are showing the Sim Card tile then we are a Multi-Sim device.
+            if (Utils.showSimCardTile(getContext())) {
+                mMultiSimDialog = true;
+                super.performClick(view);
+            } else {
+                setMobileDataEnabled(true);
+            }
+        }
+    }
+
+    private void setMobileDataEnabled(boolean enabled) {
+        if (DataUsageSummary.LOGD) Log.d(TAG, "setMobileDataEnabled()");
+        mTelephonyManager.setDataEnabled(mSubId, enabled);
+        setChecked(enabled);
+        getContext().sendBroadcast(new Intent(ACTION_DATA_ENABLED_CHANGED));
+    }
+
+    private void setChecked(boolean checked) {
+        if (mChecked == checked) return;
+        mChecked = checked;
+        notifyChanged();
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+        View switchView = holder.findViewById(android.R.id.switch_widget);
+        switchView.setClickable(false);
+        ((Checkable) switchView).setChecked(mChecked);
+    }
+
+    @Override
+    protected void onPrepareDialogBuilder(AlertDialog.Builder builder,
+            DialogInterface.OnClickListener listener) {
+        if (mMultiSimDialog) {
+            showMultiSimDialog(builder, listener);
+        } else {
+            showDisableDialog(builder, listener);
+        }
+    }
+
+    private void showDisableDialog(AlertDialog.Builder builder,
+            DialogInterface.OnClickListener listener) {
+        builder.setTitle(null)
+                .setMessage(R.string.data_usage_disable_mobile)
+                .setPositiveButton(android.R.string.ok, listener)
+                .setNegativeButton(android.R.string.cancel, null);
+    }
+
+    private void showMultiSimDialog(AlertDialog.Builder builder,
+            DialogInterface.OnClickListener listener) {
+        mSubscriptionManager = SubscriptionManager.from(getContext());
+        final SubscriptionInfo currentSir = mSubscriptionManager.getActiveSubscriptionInfo(mSubId);
+
+        final SubscriptionInfo nextSir = mSubscriptionManager.getDefaultDataSubscriptionInfo();
+
+        // If the device is single SIM or is enabling data on the active data SIM then forgo
+        // the pop-up.
+        if (!Utils.showSimCardTile(getContext()) ||
+                (nextSir != null && currentSir != null &&
+                currentSir.getSubscriptionId() == nextSir.getSubscriptionId())) {
+            setMobileDataEnabled(true);
+            if (nextSir != null && currentSir != null &&
+                currentSir.getSubscriptionId() == nextSir.getSubscriptionId()) {
+                disableDataForOtherSubscriptions(currentSir);
+            }
+            return;
+        }
+
+        final String previousName = (nextSir == null)
+            ? getContext().getResources().getString(R.string.sim_selection_required_pref)
+            : nextSir.getDisplayName().toString();
+
+        builder.setTitle(R.string.sim_change_data_title);
+        builder.setMessage(getContext().getString(R.string.sim_change_data_message,
+                    currentSir.getDisplayName(), previousName));
+
+        builder.setPositiveButton(R.string.okay, new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int id) {
+                mSubscriptionManager.setDefaultDataSubId(currentSir.getSubscriptionId());
+                setMobileDataEnabled(true);
+                disableDataForOtherSubscriptions(currentSir);
+            }
+        });
+        builder.setNegativeButton(R.string.cancel, null);
+
+        builder.create().show();
+    }
+
+    private void disableDataForOtherSubscriptions(SubscriptionInfo currentSir) {
+        List<SubscriptionInfo> subInfoList = mSubscriptionManager.getActiveSubscriptionInfoList();
+        if (subInfoList != null) {
+            for (SubscriptionInfo subInfo : subInfoList) {
+                if (subInfo.getSubscriptionId() != currentSir.getSubscriptionId()) {
+                    mTelephonyManager.setDataEnabled(subInfo.getSubscriptionId(), false);
+                }
+            }
+        }
+        getContext().sendBroadcast(new Intent(ACTION_DATA_ENABLED_CHANGED));
+    }
+
+    @Override
+    protected void onClick(DialogInterface dialog, int which) {
+        if (which != DialogInterface.BUTTON_POSITIVE) {
+            return;
+        }
+        if (mMultiSimDialog) {
+        } else {
+            // TODO: extend to modify policy enabled flag.
+            setMobileDataEnabled(false);
+        }
+    }
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            updateChecked();
+        }
+    };
+
+    public static class CellDataState extends BaseSavedState {
+        public int mSubId;
+        public boolean mChecked;
+        public boolean mMultiSimDialog;
+
+        public CellDataState(Parcelable base) {
+            super(base);
+        }
+
+        public CellDataState(Parcel source) {
+            super(source);
+            mChecked = source.readByte() != 0;
+            mMultiSimDialog = source.readByte() != 0;
+            mSubId = source.readInt();
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            super.writeToParcel(dest, flags);
+            dest.writeByte((byte) (mChecked ? 1 : 0));
+            dest.writeByte((byte) (mMultiSimDialog ? 1 : 0));
+            dest.writeInt(mSubId);
+        }
+
+        public static final Creator<CellDataState> CREATOR = new Creator<CellDataState>() {
+            @Override
+            public CellDataState createFromParcel(Parcel source) {
+                return new CellDataState(source);
+            }
+
+            @Override
+            public CellDataState[] newArray(int size) {
+                return new CellDataState[size];
+            }
+        };
+    }
+}
diff --git a/src/com/android/settings/datausage/ChartDataUsagePreference.java b/src/com/android/settings/datausage/ChartDataUsagePreference.java
new file mode 100644
index 0000000..f328cf6
--- /dev/null
+++ b/src/com/android/settings/datausage/ChartDataUsagePreference.java
@@ -0,0 +1,82 @@
+/*
+ * 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 android.content.Context;
+import android.graphics.Color;
+import android.net.NetworkPolicy;
+import android.net.NetworkStatsHistory;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.util.AttributeSet;
+import com.android.settings.R;
+import com.android.settings.widget.ChartDataUsageView;
+import com.android.settings.widget.ChartNetworkSeriesView;
+
+public class ChartDataUsagePreference extends Preference {
+
+    private NetworkPolicy mPolicy;
+    private long mStart;
+    private long mEnd;
+    private NetworkStatsHistory mNetwork;
+    private int mSecondaryColor;
+    private int mSeriesColor;
+
+    public ChartDataUsagePreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        setLayoutResource(R.layout.data_usage_chart);
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+        ChartDataUsageView chart = (ChartDataUsageView) holder.itemView;
+        chart.setVisibleRange(mStart, mEnd);
+        chart.bindNetworkPolicy(mPolicy);
+        chart.bindNetworkStats(mNetwork);
+        ChartNetworkSeriesView series = (ChartNetworkSeriesView) holder.findViewById(R.id.series);
+        series.setChartColor(Color.BLACK, mSeriesColor, mSecondaryColor);
+    }
+
+    public void bindNetworkPolicy(NetworkPolicy policy) {
+        mPolicy = policy;
+        notifyChanged();
+    }
+
+    public void setVisibleRange(long start, long end) {
+        mStart = start;
+        mEnd = end;
+        notifyChanged();
+    }
+
+    public long getInspectStart() {
+        return mStart;
+    }
+
+    public long getInspectEnd() {
+        return mEnd;
+    }
+
+    public void bindNetworkStats(NetworkStatsHistory network) {
+        mNetwork = network;
+        notifyChanged();
+    }
+
+    public void setColors(int seriesColor, int secondaryColor) {
+        mSeriesColor = seriesColor;
+        mSecondaryColor = secondaryColor;
+        notifyChanged();
+    }
+}
diff --git a/src/com/android/settings/datausage/CycleAdapter.java b/src/com/android/settings/datausage/CycleAdapter.java
new file mode 100644
index 0000000..682cc8a
--- /dev/null
+++ b/src/com/android/settings/datausage/CycleAdapter.java
@@ -0,0 +1,188 @@
+/*
+ * 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 com.android.settings.Utils;
+import com.android.settingslib.net.ChartData;
+
+import android.content.Context;
+import android.net.NetworkPolicy;
+import android.net.NetworkStatsHistory;
+import android.text.format.DateUtils;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Spinner;
+
+import libcore.util.Objects;
+
+import static android.net.NetworkPolicyManager.computeLastCycleBoundary;
+import static android.net.NetworkPolicyManager.computeNextCycleBoundary;
+
+public class CycleAdapter extends ArrayAdapter<CycleAdapter.CycleItem> {
+
+    private final Spinner mSpinner;
+    private final AdapterView.OnItemSelectedListener mListener;
+
+    public CycleAdapter(Context context, Spinner spinner,
+            AdapterView.OnItemSelectedListener listener) {
+        super(context, com.android.settings.R.layout.filter_spinner_item);
+        setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        mSpinner = spinner;
+        mListener = listener;
+        mSpinner.setAdapter(this);
+        mSpinner.setOnItemSelectedListener(mListener);
+    }
+
+    /**
+     * Find position of {@link CycleItem} in this adapter which is nearest
+     * the given {@link CycleItem}.
+     */
+    public int findNearestPosition(CycleItem target) {
+        if (target != null) {
+            final int count = getCount();
+            for (int i = count - 1; i >= 0; i--) {
+                final CycleItem item = getItem(i);
+                if (item.compareTo(target) >= 0) {
+                    return i;
+                }
+            }
+        }
+        return 0;
+    }
+
+    /**
+     * Rebuild list based on {@link NetworkPolicy#cycleDay}
+     * and available {@link NetworkStatsHistory} data. Always selects the newest
+     * item, updating the inspection range on chartData.
+     */
+     public boolean updateCycleList(NetworkPolicy policy, ChartData chartData) {
+        // stash away currently selected cycle to try restoring below
+        final CycleAdapter.CycleItem previousItem = (CycleAdapter.CycleItem)
+                mSpinner.getSelectedItem();
+        clear();
+
+        final Context context = mSpinner.getContext();
+        NetworkStatsHistory.Entry entry = null;
+
+        long historyStart = Long.MAX_VALUE;
+        long historyEnd = Long.MIN_VALUE;
+        if (chartData != null) {
+            historyStart = chartData.network.getStart();
+            historyEnd = chartData.network.getEnd();
+        }
+
+        final long now = System.currentTimeMillis();
+        if (historyStart == Long.MAX_VALUE) historyStart = now;
+        if (historyEnd == Long.MIN_VALUE) historyEnd = now + 1;
+
+        boolean hasCycles = false;
+        if (policy != null) {
+            // find the next cycle boundary
+            long cycleEnd = computeNextCycleBoundary(historyEnd, policy);
+
+            // walk backwards, generating all valid cycle ranges
+            while (cycleEnd > historyStart) {
+                final long cycleStart = computeLastCycleBoundary(cycleEnd, policy);
+
+                final boolean includeCycle;
+                if (chartData != null) {
+                    entry = chartData.network.getValues(cycleStart, cycleEnd, entry);
+                    includeCycle = (entry.rxBytes + entry.txBytes) > 0;
+                } else {
+                    includeCycle = true;
+                }
+
+                if (includeCycle) {
+                    add(new CycleAdapter.CycleItem(context, cycleStart, cycleEnd));
+                    hasCycles = true;
+                }
+                cycleEnd = cycleStart;
+            }
+        }
+
+        if (!hasCycles) {
+            // no policy defined cycles; show entry for each four-week period
+            long cycleEnd = historyEnd;
+            while (cycleEnd > historyStart) {
+                final long cycleStart = cycleEnd - (DateUtils.WEEK_IN_MILLIS * 4);
+
+                final boolean includeCycle;
+                if (chartData != null) {
+                    entry = chartData.network.getValues(cycleStart, cycleEnd, entry);
+                    includeCycle = (entry.rxBytes + entry.txBytes) > 0;
+                } else {
+                    includeCycle = true;
+                }
+
+                if (includeCycle) {
+                    add(new CycleAdapter.CycleItem(context, cycleStart, cycleEnd));
+                }
+                cycleEnd = cycleStart;
+            }
+        }
+
+        // force pick the current cycle (first item)
+        if (getCount() > 0) {
+            final int position = findNearestPosition(previousItem);
+            mSpinner.setSelection(position);
+
+            // only force-update cycle when changed; skipping preserves any
+            // user-defined inspection region.
+            final CycleAdapter.CycleItem selectedItem = getItem(position);
+            if (!Objects.equal(selectedItem, previousItem)) {
+                mListener.onItemSelected(mSpinner, null, position, 0);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * List item that reflects a specific data usage cycle.
+     */
+    public static class CycleItem implements Comparable<CycleItem> {
+        public CharSequence label;
+        public long start;
+        public long end;
+
+        public CycleItem(CharSequence label) {
+            this.label = label;
+        }
+
+        public CycleItem(Context context, long start, long end) {
+            this.label = Utils.formatDateRange(context, start, end);
+            this.start = start;
+            this.end = end;
+        }
+
+        @Override
+        public String toString() {
+            return label.toString();
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof CycleItem) {
+                final CycleItem another = (CycleItem) o;
+                return start == another.start && end == another.end;
+            }
+            return false;
+        }
+
+        @Override
+        public int compareTo(CycleItem another) {
+            return Long.compare(start, another.start);
+        }
+    }
+}
diff --git a/src/com/android/settings/datausage/DataUsageBase.java b/src/com/android/settings/datausage/DataUsageBase.java
new file mode 100644
index 0000000..ef565a1
--- /dev/null
+++ b/src/com/android/settings/datausage/DataUsageBase.java
@@ -0,0 +1,92 @@
+/*
+ * 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 com.android.settings.SettingsPreferenceFragment;
+import com.android.settingslib.NetworkPolicyEditor;
+
+import android.content.Context;
+import android.net.INetworkStatsService;
+import android.net.NetworkPolicy;
+import android.net.NetworkPolicyManager;
+import android.os.Bundle;
+import android.os.INetworkManagementService;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+public abstract class DataUsageBase extends SettingsPreferenceFragment {
+
+    private static final String TAG = "DataUsageBase";
+
+    protected final TemplatePreference.NetworkServices services =
+            new TemplatePreference.NetworkServices();
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        final Context context = getActivity();
+
+        services.mNetworkService = INetworkManagementService.Stub.asInterface(
+                ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
+        services.mStatsService = INetworkStatsService.Stub.asInterface(
+                ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
+        services.mPolicyManager = NetworkPolicyManager.from(context);
+
+        services.mPolicyEditor = new NetworkPolicyEditor(services.mPolicyManager);
+
+        services.mTelephonyManager = TelephonyManager.from(context);
+        services.mSubscriptionManager = SubscriptionManager.from(context);
+        services.mUserManager = UserManager.get(context);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        services.mPolicyEditor.read();
+    }
+
+    protected boolean isAdmin() {
+        return services.mUserManager.isAdminUser();
+    }
+
+    protected boolean isMobileDataAvailable(int subId) {
+        return services.mSubscriptionManager.getActiveSubscriptionInfo(subId) != null;
+    }
+
+    protected boolean isNetworkPolicyModifiable(NetworkPolicy policy, int subId) {
+        return policy != null && isBandwidthControlEnabled() && services.mUserManager.isAdminUser()
+                && isDataEnabled(subId);
+    }
+
+    private boolean isDataEnabled(int subId) {
+        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            return true;
+        }
+        return services.mTelephonyManager.getDataEnabled(subId);
+    }
+
+    protected boolean isBandwidthControlEnabled() {
+        try {
+            return services.mNetworkService.isBandwidthControlEnabled();
+        } catch (RemoteException e) {
+            Log.w(TAG, "problem talking with INetworkManagementService: " + e);
+            return false;
+        }
+    }
+}
diff --git a/src/com/android/settings/datausage/DataUsageList.java b/src/com/android/settings/datausage/DataUsageList.java
new file mode 100644
index 0000000..4aa52ba
--- /dev/null
+++ b/src/com/android/settings/datausage/DataUsageList.java
@@ -0,0 +1,550 @@
+/*
+ * 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 android.app.ActivityManager;
+import android.app.LoaderManager.LoaderCallbacks;
+import android.content.Context;
+import android.content.Loader;
+import android.content.pm.UserInfo;
+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;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceGroup;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.text.format.DateUtils;
+import android.text.format.Formatter;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.Spinner;
+import com.android.settings.InstrumentedFragment;
+import com.android.settings.R;
+import com.android.settingslib.AppItem;
+import com.android.settingslib.net.ChartData;
+import com.android.settingslib.net.ChartDataLoader;
+import com.android.settingslib.net.SummaryForAllUidLoader;
+import com.android.settingslib.net.UidDetailProvider;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static android.net.ConnectivityManager.TYPE_MOBILE;
+import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
+import static android.net.TrafficStats.UID_REMOVED;
+import static android.net.TrafficStats.UID_TETHERING;
+import static android.telephony.TelephonyManager.SIM_STATE_READY;
+import static com.android.settings.datausage.DataUsageSummary.TEST_RADIOS;
+import static com.android.settings.datausage.DataUsageSummary.TEST_RADIOS_PROP;
+
+/**
+ * Panel showing data usage history across various networks, including options
+ * to inspect based on usage cycle and control through {@link NetworkPolicy}.
+ */
+public class DataUsageList extends DataUsageBase {
+    private static final String TAG = "DataUsage";
+    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;
+    public static final String EXTRA_SUB_ID = "sub_id";
+    public static final String EXTRA_NETWORK_TEMPLATE = "network_template";
+
+    private INetworkStatsSession mStatsSession;
+
+    private ChartDataUsagePreference mChart;
+
+    private NetworkTemplate mTemplate;
+    private int mSubId;
+    private ChartData mChartData;
+
+    /** Flag used to ignore listeners during binding. */
+    private boolean mBinding;
+
+    private UidDetailProvider mUidDetailProvider;
+
+    /**
+     * Local cache of data enabled for subId, used to work around delays.
+     */
+    private final Map<String, Boolean> mMobileDataEnabled = new HashMap<String, Boolean>();
+    private CycleAdapter mCycleAdapter;
+    private Spinner mCycleSpinner;
+    private Preference mUsageAmount;
+    private PreferenceGroup mApps;
+    private View mHeader;
+
+    @Override
+    protected int getMetricsCategory() {
+        return InstrumentedFragment.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);
+
+        addPreferencesFromResource(R.xml.data_usage_list);
+        mUsageAmount = findPreference(KEY_USAGE_AMOUNT);
+        mChart = (ChartDataUsagePreference) findPreference(KEY_CHART_DATA);
+        mApps = (PreferenceGroup) findPreference(KEY_APPS_GROUP);
+
+        final Bundle args = getArguments();
+        mSubId = args.getInt(EXTRA_SUB_ID, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        mTemplate = args.getParcelable(EXTRA_NETWORK_TEMPLATE);
+    }
+
+    @Override
+    public void onViewCreated(View v, Bundle savedInstanceState) {
+        super.onViewCreated(v, savedInstanceState);
+
+        mHeader = setPinnedHeaderView(R.layout.apps_filter_spinner);
+        mCycleSpinner = (Spinner) mHeader.findViewById(R.id.filter_spinner);
+        mCycleAdapter = new CycleAdapter(getContext(), mCycleSpinner, mCycleListener);
+        setLoading(true, false);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+
+        updateBody();
+
+        // kick off background task to update stats
+        new AsyncTask<Void, Void, Void>() {
+            @Override
+            protected Void doInBackground(Void... params) {
+                try {
+                    // wait a few seconds before kicking off
+                    Thread.sleep(2 * DateUtils.SECOND_IN_MILLIS);
+                    services.mStatsService.forceUpdate();
+                } catch (InterruptedException e) {
+                } catch (RemoteException e) {
+                }
+                return null;
+            }
+
+            @Override
+            protected void onPostExecute(Void result) {
+                if (isAdded()) {
+                    updateBody();
+                }
+            }
+        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+    }
+
+    @Override
+    public void onDestroy() {
+        mUidDetailProvider.clearCache();
+        mUidDetailProvider = null;
+
+        TrafficStats.closeQuietly(mStatsSession);
+
+        super.onDestroy();
+    }
+
+    /**
+     * Update body content based on current tab. Loads
+     * {@link NetworkStatsHistory} and {@link NetworkPolicy} from system, and
+     * binds them to visible controls.
+     */
+    private void updateBody() {
+        mBinding = true;
+        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,
+                ChartDataLoader.buildArgs(mTemplate, null), mChartDataCallbacks);
+
+        // detail mode can change visible menus, invalidate
+        getActivity().invalidateOptionsMenu();
+
+        mBinding = false;
+
+        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(boolean refreshCycle) {
+        final NetworkPolicy policy = services.mPolicyEditor.getPolicy(mTemplate);
+        //SUB SELECT
+        if (isNetworkPolicyModifiable(policy, mSubId) && isMobileDataAvailable(mSubId)) {
+            mChart.bindNetworkPolicy(policy);
+            mHeader.findViewById(R.id.filter_settings).setVisibility(View.VISIBLE);
+            mHeader.findViewById(R.id.filter_settings).setOnClickListener(
+                    new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    Bundle args = new Bundle();
+                    args.putParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE, mTemplate);
+                    startFragment(DataUsageList.this, BillingCycleSettings.class.getName(),
+                            R.string.billing_cycle, 0, args);
+                }
+            });
+        } else {
+            // controls are disabled; don't bind warning/limit sweeps
+            mChart.bindNetworkPolicy(null);
+            mHeader.findViewById(R.id.filter_settings).setVisibility(View.GONE);
+        }
+
+        if (refreshCycle) {
+            // 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,
+                SummaryForAllUidLoader.buildArgs(mTemplate, start, end), mSummaryCallbacks);
+
+        final long totalBytes = entry != null ? entry.rxBytes + entry.txBytes : 0;
+        final String totalPhrase = Formatter.formatFileSize(context, totalBytes);
+        mUsageAmount.setTitle(getString(R.string.data_used_template, totalPhrase));
+    }
+
+    /**
+     * Bind the given {@link NetworkStats}, or {@code null} to clear list.
+     */
+    public void bindStats(NetworkStats stats, int[] restrictedUids) {
+        ArrayList<AppItem> items = new ArrayList<>();
+        long largest = 0;
+
+        final int currentUserId = ActivityManager.getCurrentUser();
+        UserManager userManager = UserManager.get(getContext());
+        final List<UserHandle> profiles = userManager.getUserProfiles();
+        final SparseArray<AppItem> knownItems = new SparseArray<AppItem>();
+
+        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) {
+        Bundle args = new Bundle();
+        args.putParcelable(AppDataUsage.ARG_APP_ITEM, item);
+        args.putParcelable(AppDataUsage.ARG_NETWORK_TEMPLATE, mTemplate);
+        startFragment(this, AppDataUsage.class.getName(), R.string.app_data_usage, 0, args);
+    }
+
+    /**
+     * 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 static long accumulate(int collapseKey, final SparseArray<AppItem> knownItems,
+            NetworkStats.Entry entry, int itemCategory, ArrayList<AppItem> 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);
+    }
+
+    /**
+     * Test if device has a mobile data radio with SIM in ready state.
+     */
+    public static boolean hasReadyMobileRadio(Context context) {
+        if (TEST_RADIOS) {
+            return SystemProperties.get(TEST_RADIOS_PROP).contains("mobile");
+        }
+
+        final ConnectivityManager conn = ConnectivityManager.from(context);
+        final TelephonyManager tele = TelephonyManager.from(context);
+
+        final List<SubscriptionInfo> subInfoList =
+                SubscriptionManager.from(context).getActiveSubscriptionInfoList();
+        // No activated Subscriptions
+        if (subInfoList == null) {
+            if (LOGD) Log.d(TAG, "hasReadyMobileRadio: subInfoList=null");
+            return false;
+        }
+        // require both supported network and ready SIM
+        boolean isReady = true;
+        for (SubscriptionInfo subInfo : subInfoList) {
+            isReady = isReady & tele.getSimState(subInfo.getSimSlotIndex()) == SIM_STATE_READY;
+            if (LOGD) Log.d(TAG, "hasReadyMobileRadio: subInfo=" + subInfo);
+        }
+        boolean retVal = conn.isNetworkSupported(TYPE_MOBILE) && isReady;
+        if (LOGD) {
+            Log.d(TAG, "hasReadyMobileRadio:"
+                    + " conn.isNetworkSupported(TYPE_MOBILE)="
+                                            + conn.isNetworkSupported(TYPE_MOBILE)
+                    + " isReady=" + isReady);
+        }
+        return retVal;
+    }
+
+    /*
+     * TODO: consider adding to TelephonyManager or SubscriptionManager.
+     */
+    public static boolean hasReadyMobileRadio(Context context, int subId) {
+        if (TEST_RADIOS) {
+            return SystemProperties.get(TEST_RADIOS_PROP).contains("mobile");
+        }
+
+        final ConnectivityManager conn = ConnectivityManager.from(context);
+        final TelephonyManager tele = TelephonyManager.from(context);
+        final int slotId = SubscriptionManager.getSlotId(subId);
+        final boolean isReady = tele.getSimState(slotId) == SIM_STATE_READY;
+
+        boolean retVal =  conn.isNetworkSupported(TYPE_MOBILE) && isReady;
+        if (LOGD) Log.d(TAG, "hasReadyMobileRadio: subId=" + subId
+                + " conn.isNetworkSupported(TYPE_MOBILE)=" + conn.isNetworkSupported(TYPE_MOBILE)
+                + " isReady=" + isReady);
+        return retVal;
+    }
+
+    private OnItemSelectedListener mCycleListener = new OnItemSelectedListener() {
+        @Override
+        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+            final CycleAdapter.CycleItem cycle = (CycleAdapter.CycleItem)
+                    parent.getItemAtPosition(position);
+
+            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<ChartData> mChartDataCallbacks = new LoaderCallbacks<
+            ChartData>() {
+        @Override
+        public Loader<ChartData> onCreateLoader(int id, Bundle args) {
+            return new ChartDataLoader(getActivity(), mStatsSession, args);
+        }
+
+        @Override
+        public void onLoadFinished(Loader<ChartData> loader, ChartData data) {
+            setLoading(false, true);
+            mChartData = data;
+            mChart.bindNetworkStats(mChartData.network);
+
+            // calcuate policy cycles based on available data
+            updatePolicy(true);
+        }
+
+        @Override
+        public void onLoaderReset(Loader<ChartData> loader) {
+            mChartData = null;
+            mChart.bindNetworkStats(null);
+        }
+    };
+
+    private final LoaderCallbacks<NetworkStats> mSummaryCallbacks = new LoaderCallbacks<
+            NetworkStats>() {
+        @Override
+        public Loader<NetworkStats> onCreateLoader(int id, Bundle args) {
+            return new SummaryForAllUidLoader(getActivity(), mStatsSession, args);
+        }
+
+        @Override
+        public void onLoadFinished(Loader<NetworkStats> loader, NetworkStats data) {
+            final int[] restrictedUids = services.mPolicyManager.getUidsWithPolicy(
+                    POLICY_REJECT_METERED_BACKGROUND);
+            bindStats(data, restrictedUids);
+            updateEmptyVisible();
+        }
+
+        @Override
+        public void onLoaderReset(Loader<NetworkStats> 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/net/DataUsageMeteredSettings.java b/src/com/android/settings/datausage/DataUsageMeteredSettings.java
similarity index 93%
rename from src/com/android/settings/net/DataUsageMeteredSettings.java
rename to src/com/android/settings/datausage/DataUsageMeteredSettings.java
index ef3a705..9790704 100644
--- a/src/com/android/settings/net/DataUsageMeteredSettings.java
+++ b/src/com/android/settings/datausage/DataUsageMeteredSettings.java
@@ -1,20 +1,18 @@
 /*
- * Copyright (C) 2012 The Android Open Source Project
+ * 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
+ * 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.
+ * 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.net;
+package com.android.settings.datausage;
 
 import android.content.Context;
 import android.content.res.Resources;
@@ -42,8 +40,8 @@
 
 import static android.net.NetworkPolicy.LIMIT_DISABLED;
 import static android.net.wifi.WifiInfo.removeDoubleQuotes;
-import static com.android.settings.DataUsageSummary.hasReadyMobileRadio;
-import static com.android.settings.DataUsageSummary.hasWifiRadio;
+import static com.android.settings.datausage.DataUsageList.hasReadyMobileRadio;
+import static com.android.settings.datausage.DataUsageSummary.hasWifiRadio;
 
 /**
  * Panel to configure {@link NetworkPolicy#metered} for networks.
diff --git a/src/com/android/settings/datausage/DataUsagePreference.java b/src/com/android/settings/datausage/DataUsagePreference.java
new file mode 100644
index 0000000..bd865b5
--- /dev/null
+++ b/src/com/android/settings/datausage/DataUsagePreference.java
@@ -0,0 +1,58 @@
+/*
+ * 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 android.content.Context;
+import android.content.Intent;
+import android.net.NetworkTemplate;
+import android.os.Bundle;
+import android.support.v7.preference.Preference;
+import android.telephony.SubscriptionManager;
+import android.text.format.Formatter;
+import android.util.AttributeSet;
+import com.android.settings.Utils;
+import com.android.settingslib.net.DataUsageController;
+import com.android.settings.R;
+
+public class DataUsagePreference extends Preference implements TemplatePreference {
+
+    private NetworkTemplate mTemplate;
+    private int mSubId;
+
+    public DataUsagePreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    public void setTemplate(NetworkTemplate template, int subId,
+            NetworkServices services) {
+        mTemplate = template;
+        mSubId = subId;
+        DataUsageController controller = new DataUsageController(getContext());
+        DataUsageController.DataUsageInfo usageInfo = controller.getDataUsageInfo(mTemplate);
+        setSummary(getContext().getString(R.string.data_usage_template,
+                Formatter.formatFileSize(getContext(), usageInfo.usageLevel), usageInfo.period));
+        setIntent(getIntent());
+    }
+
+    @Override
+    public Intent getIntent() {
+        Bundle args = new Bundle();
+        args.putParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE, mTemplate);
+        args.putInt(DataUsageList.EXTRA_SUB_ID, mSubId);
+        return Utils.onBuildStartFragmentIntent(getContext(), DataUsageList.class.getName(), args,
+                getContext().getPackageName(), 0, getTitle(), false);
+    }
+}
diff --git a/src/com/android/settings/datausage/DataUsageSummary.java b/src/com/android/settings/datausage/DataUsageSummary.java
new file mode 100644
index 0000000..de98008
--- /dev/null
+++ b/src/com/android/settings/datausage/DataUsageSummary.java
@@ -0,0 +1,375 @@
+/*
+ * 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 android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.INetworkStatsSession;
+import android.net.NetworkTemplate;
+import android.net.TrafficStats;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.provider.SearchIndexableResource;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.text.format.Formatter;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import com.android.internal.logging.MetricsLogger;
+import com.android.settings.R;
+import com.android.settings.SummaryPreference;
+import com.android.settings.Utils;
+import com.android.settings.dashboard.SummaryLoader;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
+import com.android.settingslib.net.DataUsageController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static android.net.ConnectivityManager.TYPE_ETHERNET;
+import static android.net.ConnectivityManager.TYPE_WIFI;
+
+public class DataUsageSummary extends DataUsageBase implements Indexable {
+
+    private static final String TAG = "DataUsageSummary";
+    static final boolean LOGD = false;
+
+    public static final boolean TEST_RADIOS = false;
+    public static final String TEST_RADIOS_PROP = "test.radios";
+
+    private static final String KEY_STATUS_HEADER = "status_header";
+    private static final String KEY_LIMIT_SUMMARY = "limit_summary";
+    private static final String KEY_RESTRICT_BACKGROUND = "restrict_background";
+
+    private DataUsageController mDataUsageController;
+    private SummaryPreference mSummaryPreference;
+    private Preference mLimitPreference;
+    private NetworkTemplate mDefaultTemplate;
+    private int mDataUsageTemplate;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        boolean hasMobileData = hasMobileData(getContext());
+        mDataUsageController = new DataUsageController(getContext());
+        addPreferencesFromResource(R.xml.data_usage);
+
+        int defaultSubId = getDefaultSubscriptionId(getContext());
+        mDefaultTemplate = getDefaultTemplate(getContext(), defaultSubId);
+        if (hasMobileData) {
+            mLimitPreference = findPreference(KEY_LIMIT_SUMMARY);
+        } else {
+            removePreference(KEY_LIMIT_SUMMARY);
+        }
+        if (!hasMobileData || !isAdmin()) {
+            removePreference(KEY_RESTRICT_BACKGROUND);
+        }
+        if (hasMobileData) {
+            List<SubscriptionInfo> subscriptions =
+                    services.mSubscriptionManager.getActiveSubscriptionInfoList();
+            if (subscriptions.size() == 0) {
+                addMobileSection(defaultSubId);
+            }
+            for (int i = 0; i < subscriptions.size(); i++) {
+                addMobileSection(subscriptions.get(i).getSubscriptionId());
+            }
+        }
+        boolean hasWifiRadio = hasWifiRadio(getContext());
+        if (hasWifiRadio) {
+            addWifiSection();
+        }
+        if (hasEthernet(getContext())) {
+            addEthernetSection();
+        }
+        mDataUsageTemplate = hasMobileData ? R.string.cell_data_template
+                : hasWifiRadio ? R.string.wifi_data_template
+                : R.string.ethernet_data_template;
+
+        mSummaryPreference = (SummaryPreference) findPreference(KEY_STATUS_HEADER);
+        setHasOptionsMenu(true);
+    }
+
+    @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        inflater.inflate(R.menu.data_usage, menu);
+        super.onCreateOptionsMenu(menu, inflater);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.data_usage_menu_cellular_networks: {
+                final Intent intent = new Intent(Intent.ACTION_MAIN);
+                intent.setComponent(new ComponentName("com.android.phone",
+                        "com.android.phone.MobileNetworkSettings"));
+                startActivity(intent);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void addMobileSection(int subId) {
+        TemplatePreferenceCategory category = (TemplatePreferenceCategory)
+                inflatePreferences(R.xml.data_usage_cellular);
+        category.setTemplate(getNetworkTemplate(subId), subId, services);
+    }
+
+    private void addWifiSection() {
+        TemplatePreferenceCategory category = (TemplatePreferenceCategory)
+                inflatePreferences(R.xml.data_usage_wifi);
+        category.setTemplate(NetworkTemplate.buildTemplateWifiWildcard(), 0, services);
+    }
+
+    private void addEthernetSection() {
+        TemplatePreferenceCategory category = (TemplatePreferenceCategory)
+                inflatePreferences(R.xml.data_usage_ethernet);
+        category.setTemplate(NetworkTemplate.buildTemplateEthernet(), 0, services);
+    }
+
+    private Preference inflatePreferences(int resId) {
+        PreferenceScreen rootPreferences = getPreferenceManager().inflateFromResource(
+                getPrefContext(), resId, null);
+        Preference pref = rootPreferences.getPreference(0);
+        rootPreferences.removeAll();
+
+        PreferenceScreen screen = getPreferenceScreen();
+        pref.setOrder(screen.getPreferenceCount());
+        screen.addPreference(pref);
+
+        return pref;
+    }
+
+    private NetworkTemplate getNetworkTemplate(int subscriptionId) {
+        NetworkTemplate mobileAll = NetworkTemplate.buildTemplateMobileAll(
+                services.mTelephonyManager.getSubscriberId(subscriptionId));
+        return NetworkTemplate.normalize(mobileAll,
+                services.mTelephonyManager.getMergedSubscriberIds());
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        updateState();
+    }
+
+    private void updateState() {
+        DataUsageController.DataUsageInfo info = mDataUsageController.getDataUsageInfo(
+                mDefaultTemplate);
+        Context context = getContext();
+        if (mSummaryPreference != null) {
+            Formatter.BytesResult usedResult = Formatter.formatBytes(context.getResources(),
+                    info.usageLevel, Formatter.FLAG_SHORTER);
+            mSummaryPreference.setAmount(usedResult.value);
+            mSummaryPreference.setUnits(getString(mDataUsageTemplate, usedResult.units));
+            long limit = info.limitLevel;
+            if (limit <= 0) {
+                limit = info.warningLevel;
+            }
+            if (info.usageLevel > limit) {
+                limit = info.usageLevel;
+            }
+            mSummaryPreference.setSummary(info.period);
+            mSummaryPreference.setLabels(Formatter.formatFileSize(context, 0),
+                    Formatter.formatFileSize(context, limit));
+            mSummaryPreference.setRatios(info.usageLevel / (float) limit, 0,
+                    (limit - info.usageLevel) / (float) limit);
+        }
+        if (mLimitPreference != null) {
+            String warning = Formatter.formatFileSize(context, info.warningLevel);
+            String limit = Formatter.formatFileSize(context, info.limitLevel);
+            mLimitPreference.setSummary(getString(info.limitLevel <= 0 ? R.string.cell_warning_only
+                    : R.string.cell_warning_and_limit, warning, limit));
+        }
+
+        PreferenceScreen screen = getPreferenceScreen();
+        for (int i = 1; i < screen.getPreferenceCount(); i++) {
+            ((TemplatePreferenceCategory) screen.getPreference(i)).pushTemplates(services);
+        }
+    }
+
+    @Override
+    protected int getMetricsCategory() {
+        return MetricsLogger.DATA_USAGE_SUMMARY;
+    }
+
+    /**
+     * Test if device has an ethernet network connection.
+     */
+    public boolean hasEthernet(Context context) {
+        if (TEST_RADIOS) {
+            return SystemProperties.get(TEST_RADIOS_PROP).contains("ethernet");
+        }
+
+        final ConnectivityManager conn = ConnectivityManager.from(context);
+        final boolean hasEthernet = conn.isNetworkSupported(TYPE_ETHERNET);
+
+        final long ethernetBytes;
+        try {
+            INetworkStatsSession statsSession = services.mStatsService.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 hasEthernet && ethernetBytes > 0;
+    }
+
+    public static boolean hasMobileData(Context context) {
+        return ConnectivityManager.from(context).isNetworkSupported(
+                ConnectivityManager.TYPE_MOBILE);
+    }
+
+    /**
+     * Test if device has a Wi-Fi data radio.
+     */
+    public static boolean hasWifiRadio(Context context) {
+        if (TEST_RADIOS) {
+            return SystemProperties.get(TEST_RADIOS_PROP).contains("wifi");
+        }
+
+        final ConnectivityManager conn = ConnectivityManager.from(context);
+        return conn.isNetworkSupported(TYPE_WIFI);
+    }
+
+    public static int getDefaultSubscriptionId(Context context) {
+        SubscriptionManager subManager = SubscriptionManager.from(context);
+        if (subManager == null) {
+            return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+        }
+        SubscriptionInfo subscriptionInfo = subManager.getDefaultDataSubscriptionInfo();
+        if (subscriptionInfo == null) {
+            List<SubscriptionInfo> list = subManager.getAllSubscriptionInfoList();
+            if (list.size() == 0) {
+                return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+            }
+            subscriptionInfo = list.get(0);
+        }
+        return subscriptionInfo.getSubscriptionId();
+    }
+
+    public static NetworkTemplate getDefaultTemplate(Context context, int defaultSubId) {
+        if (hasMobileData(context)) {
+            TelephonyManager telephonyManager = TelephonyManager.from(context);
+            NetworkTemplate mobileAll = NetworkTemplate.buildTemplateMobileAll(
+                    telephonyManager.getSubscriberId(defaultSubId));
+            return NetworkTemplate.normalize(mobileAll,
+                    telephonyManager.getMergedSubscriberIds());
+        } else if (hasWifiRadio(context)) {
+            return NetworkTemplate.buildTemplateWifiWildcard();
+        } else {
+            return NetworkTemplate.buildTemplateEthernet();
+        }
+    }
+
+    private static class SummaryProvider
+            implements SummaryLoader.SummaryProvider {
+
+        private final Activity mActivity;
+        private final SummaryLoader mSummaryLoader;
+        private final DataUsageController mDataController;
+
+        public SummaryProvider(Activity activity, SummaryLoader summaryLoader) {
+            mActivity = activity;
+            mSummaryLoader = summaryLoader;
+            mDataController = new DataUsageController(activity);
+        }
+
+        @Override
+        public void setListening(boolean listening) {
+            if (listening) {
+                DataUsageController.DataUsageInfo info = mDataController.getDataUsageInfo();
+                String used;
+                if (info == null) {
+                    used = Formatter.formatFileSize(mActivity, 0);
+                } else if (info.limitLevel <= 0) {
+                    used = Formatter.formatFileSize(mActivity, info.usageLevel);
+                } else {
+                    used = Utils.formatPercentage(info.usageLevel, info.limitLevel);
+                }
+                mSummaryLoader.setSummary(this,
+                        mActivity.getString(R.string.data_usage_summary_format, used));
+            }
+        }
+    }
+
+    public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
+            = new SummaryLoader.SummaryProviderFactory() {
+        @Override
+        public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
+                                                                   SummaryLoader summaryLoader) {
+            return new SummaryProvider(activity, summaryLoader);
+        }
+    };
+
+    /**
+     * For search
+     */
+    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+        new BaseSearchIndexProvider() {
+
+            @Override
+            public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
+                    boolean enabled) {
+                ArrayList<SearchIndexableResource> resources = new ArrayList<>();
+                SearchIndexableResource resource = new SearchIndexableResource(context);
+                resource.xmlResId = R.xml.data_usage;
+                resources.add(resource);
+
+                if (hasMobileData(context)) {
+                    resource = new SearchIndexableResource(context);
+                    resource.xmlResId = R.xml.data_usage_cellular;
+                    resources.add(resource);
+                }
+                if (hasWifiRadio(context)) {
+                    resource = new SearchIndexableResource(context);
+                    resource.xmlResId = R.xml.data_usage_wifi;
+                    resources.add(resource);
+                }
+                return resources;
+            }
+
+            @Override
+            public List<String> getNonIndexableKeys(Context context) {
+                ArrayList<String> keys = new ArrayList<>();
+                boolean hasMobileData = ConnectivityManager.from(context).isNetworkSupported(
+                        ConnectivityManager.TYPE_MOBILE);
+
+                if (hasMobileData) {
+                    keys.add(KEY_RESTRICT_BACKGROUND);
+                }
+
+                return keys;
+            }
+        };
+}
diff --git a/src/com/android/settings/datausage/NetworkRestrictionsPreference.java b/src/com/android/settings/datausage/NetworkRestrictionsPreference.java
new file mode 100644
index 0000000..e2e9d1e
--- /dev/null
+++ b/src/com/android/settings/datausage/NetworkRestrictionsPreference.java
@@ -0,0 +1,33 @@
+/*
+ * 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 android.content.Context;
+import android.net.NetworkTemplate;
+import android.support.v7.preference.Preference;
+import android.util.AttributeSet;
+
+public class NetworkRestrictionsPreference extends Preference implements TemplatePreference {
+
+    public NetworkRestrictionsPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    public void setTemplate(NetworkTemplate template, int subId,
+            NetworkServices services) {
+        // TODO: Summary
+    }
+}
diff --git a/src/com/android/settings/datausage/RestrictBackgroundDataPreference.java b/src/com/android/settings/datausage/RestrictBackgroundDataPreference.java
new file mode 100644
index 0000000..67bce03
--- /dev/null
+++ b/src/com/android/settings/datausage/RestrictBackgroundDataPreference.java
@@ -0,0 +1,99 @@
+/*
+ * 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 android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.net.NetworkPolicyManager;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.Checkable;
+import com.android.settings.CustomDialogPreference;
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.dashboard.conditional.BackgroundDataCondition;
+import com.android.settings.dashboard.conditional.ConditionManager;
+
+public class RestrictBackgroundDataPreference extends CustomDialogPreference {
+
+    private NetworkPolicyManager mPolicyManager;
+    private boolean mChecked;
+
+    public RestrictBackgroundDataPreference(Context context, AttributeSet attrs) {
+        super(context, attrs, android.R.attr.switchPreferenceStyle);
+    }
+
+    @Override
+    public void onAttached() {
+        super.onAttached();
+        mPolicyManager = NetworkPolicyManager.from(getContext());
+        setChecked(mPolicyManager.getRestrictBackground());
+    }
+
+    public void setRestrictBackground(boolean restrictBackground) {
+        mPolicyManager.setRestrictBackground(restrictBackground);
+        setChecked(restrictBackground);
+        ConditionManager.get(getContext()).getCondition(BackgroundDataCondition.class)
+                .refreshState();
+    }
+
+    private void setChecked(boolean checked) {
+        if (mChecked == checked) return;
+        mChecked = checked;
+        notifyChanged();
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+        View switchView = holder.findViewById(android.R.id.switch_widget);
+        switchView.setClickable(false);
+        ((Checkable) switchView).setChecked(mChecked);
+    }
+
+    @Override
+    protected void performClick(View view) {
+        if (mChecked) {
+            setRestrictBackground(false);
+        } else {
+            super.performClick(view);
+        }
+    }
+
+    @Override
+    protected void onPrepareDialogBuilder(AlertDialog.Builder builder,
+            DialogInterface.OnClickListener listener) {
+        super.onPrepareDialogBuilder(builder, listener);
+        builder.setTitle(R.string.data_usage_restrict_background_title);
+        if (Utils.hasMultipleUsers(getContext())) {
+            builder.setMessage(R.string.data_usage_restrict_background_multiuser);
+        } else {
+            builder.setMessage(R.string.data_usage_restrict_background);
+        }
+
+        builder.setPositiveButton(android.R.string.ok, listener);
+        builder.setNegativeButton(android.R.string.cancel, null);
+    }
+
+    @Override
+    protected void onClick(DialogInterface dialog, int which) {
+        if (which != DialogInterface.BUTTON_POSITIVE) {
+            return;
+        }
+        setRestrictBackground(true);
+    }
+}
diff --git a/src/com/android/settings/datausage/TemplatePreference.java b/src/com/android/settings/datausage/TemplatePreference.java
new file mode 100644
index 0000000..4b1cd0c
--- /dev/null
+++ b/src/com/android/settings/datausage/TemplatePreference.java
@@ -0,0 +1,41 @@
+/*
+ * 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 android.net.INetworkStatsService;
+import android.net.NetworkPolicyManager;
+import android.net.NetworkTemplate;
+import android.os.INetworkManagementService;
+import android.os.UserManager;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import com.android.settingslib.NetworkPolicyEditor;
+
+public interface TemplatePreference {
+
+    void setTemplate(NetworkTemplate template, int subId, NetworkServices services);
+
+    class NetworkServices {
+        INetworkManagementService mNetworkService;
+        INetworkStatsService mStatsService;
+        NetworkPolicyManager mPolicyManager;
+        TelephonyManager mTelephonyManager;
+        SubscriptionManager mSubscriptionManager;
+        UserManager mUserManager;
+        NetworkPolicyEditor mPolicyEditor;
+    }
+
+}
diff --git a/src/com/android/settings/datausage/TemplatePreferenceCategory.java b/src/com/android/settings/datausage/TemplatePreferenceCategory.java
new file mode 100644
index 0000000..0be5c73
--- /dev/null
+++ b/src/com/android/settings/datausage/TemplatePreferenceCategory.java
@@ -0,0 +1,57 @@
+/*
+ * 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 android.content.Context;
+import android.net.NetworkTemplate;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceCategory;
+import android.util.AttributeSet;
+
+public class TemplatePreferenceCategory extends PreferenceCategory implements TemplatePreference {
+
+    private NetworkTemplate mTemplate;
+    private int mSubId;
+
+    public TemplatePreferenceCategory(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    public void setTemplate(NetworkTemplate template, int subId,
+            NetworkServices services) {
+        mTemplate = template;
+        mSubId = subId;
+    }
+
+    @Override
+    public boolean addPreference(Preference preference) {
+        if (!(preference instanceof TemplatePreference)) {
+            throw new IllegalArgumentException(
+                    "TemplatePreferenceCategories can only hold TemplatePreferences");
+        }
+        return super.addPreference(preference);
+    }
+
+    public void pushTemplates(NetworkServices services) {
+        if (mTemplate == null) {
+            throw new RuntimeException("null mTemplate for " + getKey());
+        }
+        for (int i = 0; i < getPreferenceCount(); i++) {
+            ((TemplatePreference) getPreference(i)).setTemplate(mTemplate, mSubId, services);
+        }
+    }
+
+}
diff --git a/src/com/android/settings/search/Ranking.java b/src/com/android/settings/search/Ranking.java
index 3d5ff35..59f83ec 100644
--- a/src/com/android/settings/search/Ranking.java
+++ b/src/com/android/settings/search/Ranking.java
@@ -17,7 +17,6 @@
 package com.android.settings.search;
 
 import com.android.settings.ChooseLockGeneric;
-import com.android.settings.DataUsageSummary;
 import com.android.settings.DateTimeSettings;
 import com.android.settings.DevelopmentSettings;
 import com.android.settings.DeviceInfoSettings;
@@ -35,6 +34,8 @@
 import com.android.settings.applications.AdvancedAppSettings;
 import com.android.settings.applications.ManageDefaultApps;
 import com.android.settings.bluetooth.BluetoothSettings;
+import com.android.settings.datausage.DataUsageMeteredSettings;
+import com.android.settings.datausage.DataUsageSummary;
 import com.android.settings.deviceinfo.StorageSettings;
 import com.android.settings.display.ScreenZoomSettings;
 import com.android.settings.fuelgauge.BatterySaverSettings;
@@ -42,7 +43,6 @@
 import com.android.settings.inputmethod.InputMethodAndLanguageSettings;
 import com.android.settings.location.LocationSettings;
 import com.android.settings.location.ScanningSettings;
-import com.android.settings.net.DataUsageMeteredSettings;
 import com.android.settings.notification.ConfigureNotificationSettings;
 import com.android.settings.notification.OtherSoundSettings;
 import com.android.settings.notification.SoundSettings;
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index f15ff63..1d55b55 100644
--- a/src/com/android/settings/search/SearchIndexableResources.java
+++ b/src/com/android/settings/search/SearchIndexableResources.java
@@ -16,9 +16,6 @@
 
 package com.android.settings.search;
 
-import android.provider.SearchIndexableResource;
-
-import com.android.settings.DataUsageSummary;
 import com.android.settings.DateTimeSettings;
 import com.android.settings.DevelopmentSettings;
 import com.android.settings.DeviceInfoSettings;
@@ -37,6 +34,8 @@
 import com.android.settings.applications.AdvancedAppSettings;
 import com.android.settings.applications.ManageDefaultApps;
 import com.android.settings.bluetooth.BluetoothSettings;
+import com.android.settings.datausage.DataUsageMeteredSettings;
+import com.android.settings.datausage.DataUsageSummary;
 import com.android.settings.deviceinfo.StorageSettings;
 import com.android.settings.display.ScreenZoomSettings;
 import com.android.settings.fuelgauge.BatterySaverSettings;
@@ -44,7 +43,6 @@
 import com.android.settings.inputmethod.InputMethodAndLanguageSettings;
 import com.android.settings.location.LocationSettings;
 import com.android.settings.location.ScanningSettings;
-import com.android.settings.net.DataUsageMeteredSettings;
 import com.android.settings.notification.ConfigureNotificationSettings;
 import com.android.settings.notification.OtherSoundSettings;
 import com.android.settings.notification.SoundSettings;
@@ -58,6 +56,8 @@
 import com.android.settings.wifi.SavedAccessPointsWifiSettings;
 import com.android.settings.wifi.WifiSettings;
 
+import android.provider.SearchIndexableResource;
+
 import java.util.Collection;
 import java.util.HashMap;
 
diff --git a/src/com/android/settings/widget/ChartGridView.java b/src/com/android/settings/widget/ChartGridView.java
index c85d4fc..2091719 100644
--- a/src/com/android/settings/widget/ChartGridView.java
+++ b/src/com/android/settings/widget/ChartGridView.java
@@ -32,7 +32,7 @@
 import com.android.internal.util.Preconditions;
 import com.android.settings.R;
 
-import static com.android.settings.DataUsageSummary.formatDateRange;
+import static com.android.settings.Utils.formatDateRange;
 
 /**
  * Background of {@link ChartView} that renders grid lines as requested by
diff --git a/src/com/android/settings/widget/ChartSweepView.java b/src/com/android/settings/widget/ChartSweepView.java
index e8e24aa..cdcd0a7 100644
--- a/src/com/android/settings/widget/ChartSweepView.java
+++ b/src/com/android/settings/widget/ChartSweepView.java
@@ -143,7 +143,6 @@
         a.recycle();
 
         setClickable(true);
-        setFocusable(true);
         setOnClickListener(mClickListener);
 
         setWillNotDraw(false);
