Merge "Show app usage data for the correct cycle."
This commit is contained in:
committed by
Android (Google) Code Review
commit
cfe5635df0
@@ -52,6 +52,7 @@ import com.android.settingslib.net.NetworkCycleDataForUidLoader;
|
||||
import com.android.settingslib.net.UidDetail;
|
||||
import com.android.settingslib.net.UidDetailProvider;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceChangeListener,
|
||||
@@ -59,8 +60,10 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC
|
||||
|
||||
private static final String TAG = "AppDataUsage";
|
||||
|
||||
public static final String ARG_APP_ITEM = "app_item";
|
||||
public static final String ARG_NETWORK_TEMPLATE = "network_template";
|
||||
static final String ARG_APP_ITEM = "app_item";
|
||||
static final String ARG_NETWORK_TEMPLATE = "network_template";
|
||||
static final String ARG_NETWORK_CYCLES = "network_cycles";
|
||||
static final String ARG_SELECTED_CYCLE = "selected_cycle";
|
||||
|
||||
private static final String KEY_TOTAL_USAGE = "total_usage";
|
||||
private static final String KEY_FOREGROUND_USAGE = "foreground_usage";
|
||||
@@ -99,6 +102,8 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC
|
||||
private RestrictedSwitchPreference mUnrestrictedData;
|
||||
private DataSaverBackend mDataSaverBackend;
|
||||
private Context mContext;
|
||||
private ArrayList<Long> mCycles;
|
||||
private long mSelectedCycle;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
@@ -110,6 +115,10 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC
|
||||
mAppItem = (args != null) ? (AppItem) args.getParcelable(ARG_APP_ITEM) : null;
|
||||
mTemplate = (args != null) ? (NetworkTemplate) args.getParcelable(ARG_NETWORK_TEMPLATE)
|
||||
: null;
|
||||
mCycles = (args != null) ? (ArrayList) args.getSerializable(ARG_NETWORK_CYCLES)
|
||||
: null;
|
||||
mSelectedCycle = (args != null) ? args.getLong(ARG_SELECTED_CYCLE) : 0L;
|
||||
|
||||
if (mTemplate == null) {
|
||||
mTemplate = DataUsageUtils.getDefaultTemplate(mContext,
|
||||
SubscriptionManager.getDefaultDataSubscriptionId());
|
||||
@@ -393,6 +402,9 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC
|
||||
} else {
|
||||
builder.addUid(mAppItem.key);
|
||||
}
|
||||
if (mCycles != null) {
|
||||
builder.setCycles(mCycles);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@@ -401,7 +413,23 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC
|
||||
List<NetworkCycleDataForUid> data) {
|
||||
mUsageData = data;
|
||||
mCycleAdapter.updateCycleList(data);
|
||||
bindData(0 /* position */);
|
||||
if (mSelectedCycle > 0L) {
|
||||
final int numCycles = data.size();
|
||||
int position = 0;
|
||||
for (int i = 0; i < numCycles; i++) {
|
||||
final NetworkCycleDataForUid cycleData = data.get(i);
|
||||
if (cycleData.getEndTime() == mSelectedCycle) {
|
||||
position = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (position > 0) {
|
||||
mCycle.setSelection(position);
|
||||
}
|
||||
bindData(position);
|
||||
} else {
|
||||
bindData(0 /* position */);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -109,6 +109,7 @@ public class DataUsageList extends DataUsageBaseFragment {
|
||||
@VisibleForTesting
|
||||
int mNetworkType;
|
||||
private List<NetworkCycleChartData> mCycleData;
|
||||
private ArrayList<Long> mCycles;
|
||||
|
||||
private LoadingViewController mLoadingViewController;
|
||||
private UidDetailProvider mUidDetailProvider;
|
||||
@@ -411,10 +412,23 @@ public class DataUsageList extends DataUsageBaseFragment {
|
||||
}
|
||||
}
|
||||
|
||||
private void startAppDataUsage(AppItem item) {
|
||||
@VisibleForTesting
|
||||
void startAppDataUsage(AppItem item) {
|
||||
final Bundle args = new Bundle();
|
||||
args.putParcelable(AppDataUsage.ARG_APP_ITEM, item);
|
||||
args.putParcelable(AppDataUsage.ARG_NETWORK_TEMPLATE, mTemplate);
|
||||
if (mCycles == null) {
|
||||
mCycles = new ArrayList<>();
|
||||
for (NetworkCycleChartData data : mCycleData) {
|
||||
if (mCycles.isEmpty()) {
|
||||
mCycles.add(data.getEndTime());
|
||||
}
|
||||
mCycles.add(data.getStartTime());
|
||||
}
|
||||
}
|
||||
args.putSerializable(AppDataUsage.ARG_NETWORK_CYCLES, mCycles);
|
||||
args.putLong(AppDataUsage.ARG_SELECTED_CYCLE,
|
||||
mCycleData.get(mCycleSpinner.getSelectedItemPosition()).getEndTime());
|
||||
|
||||
new SubSettingLauncher(getContext())
|
||||
.setDestination(AppDataUsage.class.getName())
|
||||
|
@@ -345,6 +345,70 @@ public class AppDataUsageTest {
|
||||
assertThat(uids.get(2)).isEqualTo(789);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreateLoader_hasCyclesSpecified_shouldQueryDataUsageForSpecifiedCycles() {
|
||||
final long startTime = 1521583200000L;
|
||||
final long endTime = 1521676800000L;
|
||||
ArrayList<Long> testCycles = new ArrayList<>();
|
||||
testCycles.add(endTime);
|
||||
testCycles.add(startTime);
|
||||
final int uid = 123;
|
||||
final AppItem appItem = new AppItem(uid);
|
||||
appItem.category = AppItem.CATEGORY_APP;
|
||||
appItem.addUid(uid);
|
||||
|
||||
mFragment = new AppDataUsage();
|
||||
ReflectionHelpers.setField(mFragment, "mContext", RuntimeEnvironment.application);
|
||||
ReflectionHelpers.setField(mFragment, "mCycles", testCycles);
|
||||
ReflectionHelpers.setField(mFragment, "mAppItem", appItem);
|
||||
ReflectionHelpers.setField(mFragment, "mTemplate",
|
||||
NetworkTemplate.buildTemplateWifiWildcard());
|
||||
|
||||
final NetworkCycleDataForUidLoader loader = (NetworkCycleDataForUidLoader)
|
||||
mFragment.mUidDataCallbacks.onCreateLoader(0 /* id */, Bundle.EMPTY /* args */);
|
||||
|
||||
final ArrayList<Long> cycles = loader.getCycles();
|
||||
assertThat(cycles).hasSize(2);
|
||||
assertThat(cycles.get(0)).isEqualTo(endTime);
|
||||
assertThat(cycles.get(1)).isEqualTo(startTime);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onLoadFinished_hasSelectedCycleSpecified_shouldSelectSpecifiedCycle() {
|
||||
final long now = System.currentTimeMillis();
|
||||
final long tenDaysAgo = now - (DateUtils.DAY_IN_MILLIS * 10);
|
||||
final long twentyDaysAgo = now - (DateUtils.DAY_IN_MILLIS * 20);
|
||||
final long thirtyDaysAgo = now - (DateUtils.DAY_IN_MILLIS * 30);
|
||||
final List<NetworkCycleDataForUid> data = new ArrayList<>();
|
||||
NetworkCycleDataForUid.Builder builder = new NetworkCycleDataForUid.Builder();
|
||||
builder.setStartTime(thirtyDaysAgo).setEndTime(twentyDaysAgo).setTotalUsage(9876L);
|
||||
data.add(builder.build());
|
||||
builder = new NetworkCycleDataForUid.Builder();
|
||||
builder.setStartTime(twentyDaysAgo).setEndTime(tenDaysAgo).setTotalUsage(5678L);
|
||||
data.add(builder.build());
|
||||
builder = new NetworkCycleDataForUid.Builder();
|
||||
builder.setStartTime(tenDaysAgo).setEndTime(now).setTotalUsage(1234L);
|
||||
data.add(builder.build());
|
||||
|
||||
mFragment = new AppDataUsage();
|
||||
ReflectionHelpers.setField(mFragment, "mContext", RuntimeEnvironment.application);
|
||||
ReflectionHelpers.setField(mFragment, "mCycleAdapter", mock(CycleAdapter.class));
|
||||
ReflectionHelpers.setField(mFragment, "mSelectedCycle", tenDaysAgo);
|
||||
final Preference backgroundPref = mock(Preference.class);
|
||||
ReflectionHelpers.setField(mFragment, "mBackgroundUsage", backgroundPref);
|
||||
final Preference foregroundPref = mock(Preference.class);
|
||||
ReflectionHelpers.setField(mFragment, "mForegroundUsage", foregroundPref);
|
||||
final Preference totalPref = mock(Preference.class);
|
||||
ReflectionHelpers.setField(mFragment, "mTotalUsage", totalPref);
|
||||
final SpinnerPreference cycle = mock(SpinnerPreference.class);
|
||||
ReflectionHelpers.setField(mFragment, "mCycle", cycle);
|
||||
|
||||
mFragment.mUidDataCallbacks.onLoadFinished(null /* loader */, data);
|
||||
|
||||
verify(cycle).setSelection(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = {ShadowDataUsageUtils.class, ShadowSubscriptionManager.class})
|
||||
public void onCreate_noNetworkTemplateAndInvalidDataSubscription_shouldUseWifiTemplate() {
|
||||
ShadowDataUsageUtils.IS_MOBILE_DATA_SUPPORTED = true;
|
||||
@@ -355,6 +419,10 @@ public class AppDataUsageTest {
|
||||
mFragment = spy(new AppDataUsage());
|
||||
doReturn(Robolectric.setupActivity(FragmentActivity.class)).when(mFragment).getActivity();
|
||||
doReturn(RuntimeEnvironment.application).when(mFragment).getContext();
|
||||
final UidDetailProvider uidDetailProvider = mock(UidDetailProvider.class);
|
||||
doReturn(uidDetailProvider).when(mFragment).getUidDetailProvider();
|
||||
doReturn(new UidDetail()).when(uidDetailProvider).getUidDetail(anyInt(), anyBoolean());
|
||||
|
||||
ReflectionHelpers.setField(mFragment, "mDashboardFeatureProvider",
|
||||
FakeFeatureFactory.setupForTest().dashboardFeatureProvider);
|
||||
final Bundle args = new Bundle();
|
||||
|
@@ -30,19 +30,27 @@ import android.net.ConnectivityManager;
|
||||
import android.net.NetworkTemplate;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settingslib.AppItem;
|
||||
import com.android.settingslib.NetworkPolicyEditor;
|
||||
import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
|
||||
import com.android.settingslib.net.NetworkCycleChartData;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
@@ -124,4 +132,32 @@ public class DataUsageListTest {
|
||||
assertThat(mDataUsageList.mTemplate).isNotNull();
|
||||
assertThat(mDataUsageList.mSubId).isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startAppDataUsage_shouldAddCyclesInfoToLaunchArguments() {
|
||||
final long startTime = 1521583200000L;
|
||||
final long endTime = 1521676800000L;
|
||||
final List<NetworkCycleChartData> data = new ArrayList<>();
|
||||
final NetworkCycleChartData.Builder builder = new NetworkCycleChartData.Builder();
|
||||
builder.setStartTime(startTime)
|
||||
.setEndTime(endTime);
|
||||
data.add(builder.build());
|
||||
ReflectionHelpers.setField(mDataUsageList, "mCycleData", data);
|
||||
final Spinner spinner = mock(Spinner.class);
|
||||
when(spinner.getSelectedItemPosition()).thenReturn(0);
|
||||
ReflectionHelpers.setField(mDataUsageList, "mCycleSpinner", spinner);
|
||||
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
|
||||
|
||||
mDataUsageList.startAppDataUsage(new AppItem());
|
||||
|
||||
verify(mContext).startActivity(intent.capture());
|
||||
final Bundle arguments =
|
||||
intent.getValue().getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS);
|
||||
assertThat(arguments.getLong(AppDataUsage.ARG_SELECTED_CYCLE)).isEqualTo(endTime);
|
||||
final ArrayList<Long> cycles =
|
||||
(ArrayList) arguments.getSerializable(AppDataUsage.ARG_NETWORK_CYCLES);
|
||||
assertThat(cycles).hasSize(2);
|
||||
assertThat(cycles.get(0)).isEqualTo(endTime);
|
||||
assertThat(cycles.get(1)).isEqualTo(startTime);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user