Update DataUsageSummary to include carrier provided information.

This CL augments the existing data usage display with carrier provided
information about data usage and plans when available from the new
frameworks API.

Test: manual
Test: make RunSettingsRoboTests
Bug: 70950124

Change-Id: Idde1ff786e8c5dbc04e58ffbcc0fd18789682699
This commit is contained in:
Jan Nordqvist
2018-01-22 14:43:43 -08:00
committed by Eric Schwarzenbach
parent 525d757c09
commit 4fbe0f8354
9 changed files with 929 additions and 83 deletions

View File

@@ -0,0 +1,175 @@
/*
* Copyright (C) 2018 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 com.android.settings.R;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.NetworkPolicyEditor;
import com.android.settingslib.net.DataUsageController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import java.util.concurrent.TimeUnit;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class DataUsageSummaryPreferenceControllerTest {
private static final long UPDATE_BACKOFF_MS = TimeUnit.MINUTES.toMillis(13);
private static final long CYCLE_BACKOFF_MS = TimeUnit.DAYS.toMillis(6);
private static final long CYCLE_LENGTH_MS = TimeUnit.DAYS.toMillis(30);
private static final long USAGE1 = 373000000L;
private static final long LIMIT1 = 1000000000L;
private static final String CARRIER_NAME = "z-mobile";
private static final String PERIOD = "Feb";
@Mock
private DataUsageController mDataUsageController;
@Mock
private DataUsageInfoController mDataInfoController;
@Mock
private DataUsageSummaryPreference mSummaryPreference;
@Mock
private NetworkPolicyEditor mPolicyEditor;
@Mock
private NetworkTemplate mNetworkTemplate;
private Context mContext;
private DataUsageSummaryPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mController = new DataUsageSummaryPreferenceController(
mContext,
mDataUsageController,
mDataInfoController,
mNetworkTemplate,
mPolicyEditor,
R.string.cell_data_template,
true,
null);
}
@Test
public void testSummaryUpdate_onePlan_basic() {
final long now = System.currentTimeMillis();
final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
final Intent intent = new Intent();
when(mDataUsageController.getDataUsageInfo()).thenReturn(info);
mController.setPlanValues(1 /* dataPlanCount */, LIMIT1, USAGE1);
mController.setCarrierValues(CARRIER_NAME, now - UPDATE_BACKOFF_MS, info.cycleEnd, intent);
mController.updateState(mSummaryPreference);
verify(mSummaryPreference).setLimitInfo(null);
verify(mSummaryPreference).setUsageInfo(info.cycleEnd, now - UPDATE_BACKOFF_MS,
CARRIER_NAME, 1 /* numPlans */, intent);
verify(mSummaryPreference).setChartEnabled(true);
}
@Test
public void testSummaryUpdate_noPlan_basic() {
final long now = System.currentTimeMillis();
final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
final Intent intent = new Intent();
when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info);
mController.setPlanValues(0 /* dataPlanCount */, LIMIT1, USAGE1);
mController.setCarrierValues(CARRIER_NAME, now - UPDATE_BACKOFF_MS, info.cycleEnd, intent);
mController.updateState(mSummaryPreference);
verify(mSummaryPreference).setLimitInfo("500 MB Data warning / 1.00 GB Data limit");
verify(mSummaryPreference).setUsageInfo(info.cycleEnd, now - UPDATE_BACKOFF_MS,
CARRIER_NAME, 0 /* numPlans */, intent);
verify(mSummaryPreference).setChartEnabled(true);
}
@Test
public void testSummaryUpdate_noCarrier_basic() {
final long now = System.currentTimeMillis();
final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info);
mController.setPlanValues(0 /* dataPlanCount */, LIMIT1, USAGE1);
mController.setCarrierValues(null /* carrierName */, -1L /* snapshotTime */,
info.cycleEnd, null /* intent */);
mController.updateState(mSummaryPreference);
verify(mSummaryPreference).setLimitInfo("500 MB Data warning / 1.00 GB Data limit");
verify(mSummaryPreference).setUsageInfo(
info.cycleEnd,
-1L /* snapshotTime */,
null /* carrierName */,
0 /* numPlans */,
null /* launchIntent */);
verify(mSummaryPreference).setChartEnabled(true);
}
@Test
public void testSummaryUpdate_noPlanData_basic() {
final long now = System.currentTimeMillis();
final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info);
mController.setPlanValues(0 /* dataPlanCount */, -1L /* dataPlanSize */, USAGE1);
mController.setCarrierValues(null /* carrierName */, -1L /* snapshotTime */,
info.cycleEnd, null /* intent */);
mController.updateState(mSummaryPreference);
verify(mSummaryPreference).setLimitInfo("500 MB Data warning / 1.00 GB Data limit");
verify(mSummaryPreference).setUsageInfo(
info.cycleEnd,
-1L /* snapshotTime */,
null /* carrierName */,
0 /* numPlans */,
null /* launchIntent */);
verify(mSummaryPreference).setChartEnabled(false);
}
private DataUsageController.DataUsageInfo createTestDataUsageInfo(long now) {
DataUsageController.DataUsageInfo info = new DataUsageController.DataUsageInfo();
info.carrier = CARRIER_NAME;
info.period = PERIOD;
info.startDate = now;
info.limitLevel = LIMIT1;
info.warningLevel = LIMIT1 >> 1;
info.usageLevel = USAGE1;
info.cycleStart = now - CYCLE_BACKOFF_MS;
info.cycleEnd = info.cycleStart + CYCLE_LENGTH_MS;
return info;
}
}

View File

@@ -0,0 +1,172 @@
/*
* Copyright (C) 2018 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.support.v7.preference.PreferenceViewHolder;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.android.settings.R;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResourcesImpl;
import com.android.settingslib.utils.StringUtil;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, shadows =
SettingsShadowResourcesImpl.class)
public class DataUsageSummaryPreferenceTest {
private static final long CYCLE_DURATION_MILLIS = 1000000000L;
private static final long UPDATE_LAG_MILLIS = 10000000L;
private static final String DUMMY_CARRIER = "z-mobile";
private Context mContext;
private PreferenceViewHolder mHolder;
private DataUsageSummaryPreference mSummaryPreference;
private TextView mUsageTitle;
private TextView mCycleTime;
private TextView mCarrierInfo;
private TextView mDataLimits;
private Button mLaunchButton;
private long mCycleEnd;
private long mUpdateTime;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
mSummaryPreference = new DataUsageSummaryPreference(mContext, null /* attrs */);
LayoutInflater inflater = LayoutInflater.from(mContext);
View view = inflater.inflate(mSummaryPreference.getLayoutResource(), null /* root */,
false /* attachToRoot */);
mHolder = PreferenceViewHolder.createInstanceForTests(view);
final long now = System.currentTimeMillis();
mCycleEnd = now + CYCLE_DURATION_MILLIS;
mUpdateTime = now - UPDATE_LAG_MILLIS;
}
@Test
public void testSetUsageInfo_withLaunchIntent_launchButtonShown() {
mSummaryPreference.setUsageInfo(mCycleEnd, mUpdateTime, DUMMY_CARRIER, 0 /* numPlans */,
new Intent());
bindViewHolder();
assertThat(mLaunchButton.getVisibility()).isEqualTo(View.VISIBLE);
}
@Test
public void testSetUsageInfo_withoutLaunchIntent_launchButtonNotShown() {
mSummaryPreference.setUsageInfo(mCycleEnd, mUpdateTime, DUMMY_CARRIER, 0 /* numPlans */,
null /* launchIntent */);
bindViewHolder();
assertThat(mLaunchButton.getVisibility()).isEqualTo(View.GONE);
}
@Test
public void testSetUsageInfo_withDataPlans_carrierInfoShown() {
mSummaryPreference.setUsageInfo(mCycleEnd, mUpdateTime, DUMMY_CARRIER, 1 /* numPlans */,
new Intent());
bindViewHolder();
assertThat(mCarrierInfo.getVisibility()).isEqualTo(View.VISIBLE);
}
@Test
public void testSetUsageInfo_withNoDataPlans_carrierInfoNotShown() {
mSummaryPreference.setUsageInfo(mCycleEnd, mUpdateTime, DUMMY_CARRIER, 0 /* numPlans */,
new Intent());
bindViewHolder();
assertThat(mCarrierInfo.getVisibility()).isEqualTo(View.GONE);
}
@Test
public void testSetUsageInfo_withNoDataPlans_usageTitleNotShown() {
mSummaryPreference.setUsageInfo(mCycleEnd, mUpdateTime, DUMMY_CARRIER, 0 /* numPlans */,
new Intent());
bindViewHolder();
assertThat(mUsageTitle.getVisibility()).isEqualTo(View.GONE);
}
@Test
public void testSetUsageInfo_withMultipleDataPlans_usageTitleShown() {
mSummaryPreference.setUsageInfo(mCycleEnd, mUpdateTime, DUMMY_CARRIER, 2 /* numPlans */,
new Intent());
bindViewHolder();
assertThat(mUsageTitle.getVisibility()).isEqualTo(View.VISIBLE);
}
@Test
public void testSetUsageInfo_cycleRemainingTimeShown() {
mSummaryPreference.setUsageInfo(mCycleEnd, mUpdateTime, DUMMY_CARRIER, 0 /* numPlans */,
new Intent());
String cyclePrefix = StringUtil.formatElapsedTime(mContext, CYCLE_DURATION_MILLIS,
false /* withSeconds */).toString();
String text = mContext.getString(R.string.cycle_left_time_text, cyclePrefix);
bindViewHolder();
assertThat(mCycleTime.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(mCycleTime.getText()).isEqualTo(text);
}
@Test
public void testSetLimitInfo_withLimitInfo_dataLimitsShown() {
final String limitText = "test limit text";
mSummaryPreference.setLimitInfo(limitText);
bindViewHolder();
assertThat(mDataLimits.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(mDataLimits.getText()).isEqualTo(limitText);
}
@Test
public void testSetLimitInfo_withNullLimitInfo_dataLimitsNotShown() {
mSummaryPreference.setLimitInfo(null);
bindViewHolder();
assertThat(mDataLimits.getVisibility()).isEqualTo(View.GONE);
}
private void bindViewHolder() {
mSummaryPreference.onBindViewHolder(mHolder);
mUsageTitle = (TextView) mHolder.findViewById(R.id.usage_title);
mCycleTime = (TextView) mHolder.findViewById(R.id.cycle_left_time);
mCarrierInfo = (TextView) mHolder.findViewById(R.id.carrier_and_update);
mDataLimits = (TextView) mHolder.findViewById(R.id.data_limits);
mLaunchButton = (Button) mHolder.findViewById(R.id.launch_mdp_app_button);
}
}

View File

@@ -137,7 +137,6 @@ public class BaseSearchIndexProviderTest {
final List<String> nonIndexableKeys = provider
.getNonIndexableKeys(RuntimeEnvironment.application);
assertThat(nonIndexableKeys).containsAllOf("status_header", "limit_summary",
"restrict_background");
assertThat(nonIndexableKeys).contains("status_header");
}
}