Merge changes Iced0fa59,Ic354ac91,I0b4cb6ca,I9c1d3761 into sc-dev
* changes:
Add footer to app usage page
Update app usage page with 3 radio button control
Add 3 controller for app usage page radio buttons
Add utils class for app usage operation
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 8a5539b..4059b80 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2425,6 +2425,7 @@
<activity android:name="Settings$ChooseAccountActivity"
android:label="@string/header_add_an_account"
+ android:theme="@style/Theme.SubSettings"
android:configChanges="orientation|keyboardHidden|screenSize">
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.accounts.ChooseAccountFragment" />
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2a20727..16c7e18 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -11814,9 +11814,9 @@
<string name="storage_percent_full">used</string>
<!-- Summary of a single storage volume used space. [CHAR LIMIT=24] -->
- <string name="storage_usage_summary"><xliff:g id="number" example="128">%1$s</xliff:g> <xliff:g id="unit" example="KB">%2$s</xliff:g></string>
+ <string name="storage_usage_summary"><xliff:g id="number" example="128">%1$s</xliff:g> <xliff:g id="unit" example="KB">%2$s</xliff:g> used</string>
<!-- Summary of a single storage volume total space. [CHAR LIMIT=24] -->
- <string name="storage_total_summary"><xliff:g id="percentage" example="54%">%1$s</xliff:g> used of <xliff:g id="number" example="128">%2$s</xliff:g> <xliff:g id="unit" example="KB">%3$s</xliff:g></string>
+ <string name="storage_total_summary"><xliff:g id="number" example="128">%1$s</xliff:g> <xliff:g id="unit" example="KB">%2$s</xliff:g> total</string>
<!-- Label for button allow user to remove the instant app from the device. -->
<string name="clear_instant_app_data">Clear app</string>
diff --git a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
index 03a7b97..e7f5ba6 100644
--- a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
+++ b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
@@ -336,8 +336,7 @@
final Activity activity = getActivity();
EntityHeaderController.newInstance(activity, this /*fragment*/,
null /* header view */)
- .setRecyclerView(getListView(), getSettingsLifecycle())
- .styleActionBar(activity);
+ .setRecyclerView(getListView(), getSettingsLifecycle());
}
@Override
diff --git a/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceController.java
index ec51db6..6b06daf 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceController.java
@@ -26,7 +26,6 @@
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
-import com.android.settings.Utils;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.utils.ThreadUtils;
import com.android.settingslib.widget.UsageProgressBarPreference;
@@ -108,23 +107,16 @@
@Override
public void updateState(Preference preference) {
- final Formatter.BytesResult usedResult = getBytesResult(mUsedBytes);
mUsageProgressBarPreference.setUsageSummary(
- mContext.getString(R.string.storage_usage_summary,
- usedResult.value, usedResult.units));
-
- final String percentageString = mTotalBytes == 0L
- ? Utils.formatPercentage(0)
- : Utils.formatPercentage((mUsedBytes * 100) / mTotalBytes, true /* round */);
- final Formatter.BytesResult totalResult = getBytesResult(mTotalBytes);
+ getStorageSummary(R.string.storage_usage_summary, mUsedBytes));
mUsageProgressBarPreference.setTotalSummary(
- mContext.getString(R.string.storage_total_summary, percentageString,
- totalResult.value, totalResult.units));
-
+ getStorageSummary(R.string.storage_total_summary, mTotalBytes));
mUsageProgressBarPreference.setPercent(mUsedBytes, mTotalBytes);
}
- private Formatter.BytesResult getBytesResult(long bytes) {
- return Formatter.formatBytes(mContext.getResources(), bytes, Formatter.FLAG_SHORTER);
+ private String getStorageSummary(int resId, long bytes) {
+ final Formatter.BytesResult result = Formatter.formatBytes(mContext.getResources(),
+ bytes, Formatter.FLAG_SHORTER);
+ return mContext.getString(resId, result.value, result.units);
}
}
diff --git a/src/com/android/settings/fuelgauge/BatteryChartPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryChartPreferenceController.java
index cc7f8455..eca2bf3 100644
--- a/src/com/android/settings/fuelgauge/BatteryChartPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BatteryChartPreferenceController.java
@@ -18,6 +18,10 @@
package com.android.settings.fuelgauge;
import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Looper;
+import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.VisibleForTesting;
@@ -38,6 +42,7 @@
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -63,6 +68,11 @@
private final String mPreferenceKey;
private final SettingsActivity mActivity;
private final InstrumentedPreferenceFragment mFragment;
+ private final Handler mHandler = new Handler(Looper.getMainLooper());
+
+ // Preference cache to avoid create new instance each time.
+ @VisibleForTesting
+ final Map<String, Preference> mPreferenceCache = new HashMap<>();
public BatteryChartPreferenceController(
Context context, String preferenceKey,
@@ -86,6 +96,8 @@
if (mActivity.isChangingConfigurations()) {
BatteryDiffEntry.clearCache();
}
+ mHandler.removeCallbacksAndMessages(/*token=*/ null);
+ mPreferenceCache.clear();
}
@Override
@@ -93,6 +105,7 @@
super.displayPreference(screen);
mPrefContext = screen.getContext();
mAppListPrefGroup = screen.findPreference(mPreferenceKey);
+ mAppListPrefGroup.setOrderingAsAdded(false);
}
@Override
@@ -116,7 +129,13 @@
refreshUi(trapezoidIndex, /*isForce=*/ false);
}
- void setBatteryHistoryMap(Map<Long, List<BatteryHistEntry>> batteryHistoryMap) {
+ void setBatteryHistoryMap(
+ final Map<Long, List<BatteryHistEntry>> batteryHistoryMap) {
+ mHandler.post(() -> setBatteryHistoryMapInner(batteryHistoryMap));
+ }
+
+ private void setBatteryHistoryMapInner(
+ final Map<Long, List<BatteryHistEntry>> batteryHistoryMap) {
// Resets all battery history data relative variables.
if (batteryHistoryMap == null) {
mBatteryIndexedMap = null;
@@ -163,7 +182,11 @@
Arrays.toString(mBatteryHistoryLevels)));
}
- void setBatteryChartView(BatteryChartView batteryChartView) {
+ void setBatteryChartView(final BatteryChartView batteryChartView) {
+ mHandler.post(() -> setBatteryChartViewInner(batteryChartView));
+ }
+
+ private void setBatteryChartViewInner(final BatteryChartView batteryChartView) {
mBatteryChartView = batteryChartView;
mBatteryChartView.setOnSelectListener(this);
forceRefreshUi();
@@ -174,6 +197,9 @@
mTrapezoidIndex == BatteryChartView.SELECTED_INDEX_INVALID
? BatteryChartView.SELECTED_INDEX_ALL
: mTrapezoidIndex;
+ if (mBatteryChartView != null) {
+ mBatteryChartView.setLevels(mBatteryHistoryLevels);
+ }
refreshUi(refreshIndex, /*isForce=*/ true);
}
@@ -185,12 +211,89 @@
|| (mTrapezoidIndex == trapezoidIndex && !isForce)) {
return false;
}
- mTrapezoidIndex = trapezoidIndex;
Log.d(TAG, String.format("refreshUi: index=%d batteryIndexedMap.size=%d",
mTrapezoidIndex, mBatteryIndexedMap.size()));
+
+ mTrapezoidIndex = trapezoidIndex;
+ mHandler.post(() -> {
+ removeAndCacheAllPrefs();
+ addAllPreferences();
+ });
return true;
}
+ private void addAllPreferences() {
+ final List<BatteryDiffEntry> entries =
+ mBatteryIndexedMap.get(Integer.valueOf(mTrapezoidIndex));
+ if (entries == null) {
+ Log.w(TAG, "cannot find BatteryDiffEntry for:" + mTrapezoidIndex);
+ return;
+ }
+ // Separates data into two groups and sort them individually.
+ final List<BatteryDiffEntry> appEntries = new ArrayList<>();
+ final List<BatteryDiffEntry> systemEntries = new ArrayList<>();
+ entries.forEach(entry -> {
+ if (entry.isSystemEntry()) {
+ systemEntries.add(entry);
+ } else {
+ appEntries.add(entry);
+ }
+ });
+ Collections.sort(appEntries, BatteryDiffEntry.COMPARATOR);
+ Collections.sort(systemEntries, BatteryDiffEntry.COMPARATOR);
+ Log.d(TAG, String.format("addAllPreferences() app=%d system=%d",
+ appEntries.size(), systemEntries.size()));
+ addPreferenceToScreen(appEntries);
+ addPreferenceToScreen(systemEntries);
+ }
+
+ @VisibleForTesting
+ void addPreferenceToScreen(List<BatteryDiffEntry> entries) {
+ if (mAppListPrefGroup == null || entries.isEmpty()) {
+ return;
+ }
+ int prefIndex = mAppListPrefGroup.getPreferenceCount();
+ for (BatteryDiffEntry entry : entries) {
+ final String appLabel = entry.getAppLabel();
+ final Drawable appIcon = entry.getAppIcon();
+ if (TextUtils.isEmpty(appLabel) || appIcon == null) {
+ Log.w(TAG, "cannot find app resource:" + entry.mBatteryHistEntry);
+ continue;
+ }
+ final String prefKey = entry.mBatteryHistEntry.getKey();
+ PowerGaugePreference pref =
+ (PowerGaugePreference) mPreferenceCache.get(prefKey);
+ // Creates new innstance if cached preference is not found.
+ if (pref == null) {
+ pref = new PowerGaugePreference(mPrefContext);
+ pref.setKey(prefKey);
+ mPreferenceCache.put(prefKey, pref);
+ }
+ pref.setIcon(appIcon);
+ pref.setTitle(appLabel);
+ pref.setOrder(prefIndex);
+ pref.setPercent(entry.getPercentOfTotal());
+ mAppListPrefGroup.addPreference(pref);
+ prefIndex++;
+ }
+ }
+
+ private void removeAndCacheAllPrefs() {
+ if (mAppListPrefGroup == null
+ || mAppListPrefGroup.getPreferenceCount() == 0) {
+ return;
+ }
+ final int prefsCount = mAppListPrefGroup.getPreferenceCount();
+ for (int index = 0; index < prefsCount; index++) {
+ final Preference pref = mAppListPrefGroup.getPreference(index);
+ if (TextUtils.isEmpty(pref.getKey())) {
+ continue;
+ }
+ mPreferenceCache.put(pref.getKey(), pref);
+ }
+ mAppListPrefGroup.removeAll();
+ }
+
private static String utcToLocalTime(long[] timestamps) {
final StringBuilder builder = new StringBuilder();
for (int index = 0; index < timestamps.length; index++) {
diff --git a/src/com/android/settings/fuelgauge/BatteryDiffEntry.java b/src/com/android/settings/fuelgauge/BatteryDiffEntry.java
index 7c27d7d..652b54c 100644
--- a/src/com/android/settings/fuelgauge/BatteryDiffEntry.java
+++ b/src/com/android/settings/fuelgauge/BatteryDiffEntry.java
@@ -34,7 +34,7 @@
import java.util.Map;
/** A container class to carry battery data in a specific time slot. */
-public final class BatteryDiffEntry {
+public class BatteryDiffEntry {
private static final String TAG = "BatteryDiffEntry";
static Locale sCurrentLocale = null;
diff --git a/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java
index 5a92f53..e895e9a 100644
--- a/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java
@@ -105,8 +105,7 @@
@Override
public void onStart() {
EntityHeaderController.newInstance(mActivity, mHost, null /* header view */)
- .setRecyclerView(mHost.getListView(), mLifecycle)
- .styleActionBar(mActivity);
+ .setRecyclerView(mHost.getListView(), mLifecycle);
}
private CharSequence generateLabel(BatteryInfo info) {
diff --git a/src/com/android/settings/fuelgauge/BatteryHistEntry.java b/src/com/android/settings/fuelgauge/BatteryHistEntry.java
index 9611de1..41fd55f 100644
--- a/src/com/android/settings/fuelgauge/BatteryHistEntry.java
+++ b/src/com/android/settings/fuelgauge/BatteryHistEntry.java
@@ -21,7 +21,7 @@
import java.util.TimeZone;
/** A container class to carry data from {@link ContentValues}. */
-public final class BatteryHistEntry {
+public class BatteryHistEntry {
private static final String TAG = "BatteryHistEntry";
/** Keys for accessing {@link ContentValues} or {@link Cursor}. */
diff --git a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java
index 96e5011..99a72ab 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java
@@ -57,6 +57,7 @@
final BatteryHistoryLoaderCallbacks mBatteryHistoryLoaderCallbacks =
new BatteryHistoryLoaderCallbacks();
+ private boolean mIsChartDataLoaded = false;
private boolean mIsChartGraphEnabled = false;
private PowerUsageFeatureProvider mPowerUsageFeatureProvider;
private BatteryChartPreferenceController mBatteryChartPreferenceController;
@@ -145,10 +146,11 @@
final Bundle bundle = new Bundle();
bundle.putInt(KEY_REFRESH_TYPE, refreshType);
// Uses customized battery history loader if chart design is enabled.
- if (mIsChartGraphEnabled) {
+ if (mIsChartGraphEnabled && !mIsChartDataLoaded) {
+ mIsChartDataLoaded = true;
getLoaderManager().restartLoader(LOADER_BATTERY_USAGE_STATS, bundle,
- mBatteryHistoryLoaderCallbacks);
- } else {
+ mBatteryHistoryLoaderCallbacks);
+ } else if (!mIsChartGraphEnabled) {
super.restartBatteryStatsLoader(refreshType);
}
}
diff --git a/src/com/android/settings/network/SubscriptionsChangeListener.java b/src/com/android/settings/network/SubscriptionsChangeListener.java
index 192ee53..e13f85c 100644
--- a/src/com/android/settings/network/SubscriptionsChangeListener.java
+++ b/src/com/android/settings/network/SubscriptionsChangeListener.java
@@ -27,12 +27,15 @@
import android.provider.Settings;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
+import android.util.Log;
import com.android.internal.telephony.TelephonyIntents;
/** Helper class for listening to changes in availability of telephony subscriptions */
public class SubscriptionsChangeListener extends ContentObserver {
+ private static final String TAG = "SubscriptionsChangeListener";
+
public interface SubscriptionsChangeListenerClient {
void onAirplaneModeChanged(boolean airplaneModeEnabled);
void onSubscriptionsChanged();
@@ -44,6 +47,7 @@
private OnSubscriptionsChangedListener mSubscriptionsChangedListener;
private Uri mAirplaneModeSettingUri;
private BroadcastReceiver mBroadcastReceiver;
+ private boolean mRunning = false;
public SubscriptionsChangeListener(Context context, SubscriptionsChangeListenerClient client) {
super(new Handler(Looper.getMainLooper()));
@@ -75,12 +79,19 @@
final IntentFilter radioTechnologyChangedFilter = new IntentFilter(
TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED);
mContext.registerReceiver(mBroadcastReceiver, radioTechnologyChangedFilter);
+ mRunning = true;
}
public void stop() {
- mSubscriptionManager.removeOnSubscriptionsChangedListener(mSubscriptionsChangedListener);
- mContext.getContentResolver().unregisterContentObserver(this);
- mContext.unregisterReceiver(mBroadcastReceiver);
+ if (mRunning) {
+ mSubscriptionManager.removeOnSubscriptionsChangedListener(
+ mSubscriptionsChangedListener);
+ mContext.getContentResolver().unregisterContentObserver(this);
+ mContext.unregisterReceiver(mBroadcastReceiver);
+ mRunning = false;
+ } else {
+ Log.d(TAG, "Stop has been called without associated Start.");
+ }
}
public boolean isAirplaneModeOn() {
diff --git a/src/com/android/settings/vpn2/ConfigDialog.java b/src/com/android/settings/vpn2/ConfigDialog.java
index a88be03..cd6b4ff 100644
--- a/src/com/android/settings/vpn2/ConfigDialog.java
+++ b/src/com/android/settings/vpn2/ConfigDialog.java
@@ -26,6 +26,7 @@
import android.os.SystemProperties;
import android.text.Editable;
import android.text.TextWatcher;
+import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
@@ -40,6 +41,7 @@
import com.android.internal.net.VpnProfile;
import com.android.net.module.util.ProxyUtils;
import com.android.settings.R;
+import com.android.settings.Utils;
import com.android.settings.utils.AndroidKeystoreAliasLoader;
import java.net.InetAddress;
@@ -64,6 +66,8 @@
private boolean mEditing;
private boolean mExists;
+ private List<String> mTotalTypes;
+ private List<String> mAllowedTypes;
private View mView;
@@ -134,7 +138,13 @@
// Second, copy values from the profile.
mName.setText(mProfile.name);
setTypesByFeature(mType);
- mType.setSelection(mProfile.type);
+ // Not all types will be available to the user. Find the index corresponding to the
+ // string of the profile's type.
+ if (mAllowedTypes != null && mTotalTypes != null) {
+ mType.setSelection(mAllowedTypes.indexOf(mTotalTypes.get(mProfile.type)));
+ } else {
+ Log.w(TAG, "Allowed or Total vpn types not initialized when setting initial selection");
+ }
mServer.setText(mProfile.server);
if (mProfile.saveLogin) {
mUsername.setText(mProfile.username);
@@ -276,7 +286,10 @@
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (parent == mType) {
- changeType(position);
+ // Because the spinner may not display all available types,
+ // convert the selected position into the actual vpn profile type integer.
+ final int profileType = convertAllowedIndexToProfileType(position);
+ changeType(profileType);
} else if (parent == mProxySettings) {
updateProxyFieldsVisibility(position);
}
@@ -371,7 +384,7 @@
// Configure networking option visibility
// TODO(b/149070123): Add ability for platform VPNs to support DNS & routes
final int visibility =
- isLegacyType(mType.getSelectedItemPosition()) ? View.VISIBLE : View.GONE;
+ isLegacyType(getSelectedVpnType()) ? View.VISIBLE : View.GONE;
mView.findViewById(R.id.network_options).setVisibility(visibility);
} else {
mView.findViewById(R.id.options).setVisibility(View.GONE);
@@ -431,7 +444,7 @@
return false;
}
- final int type = mType.getSelectedItemPosition();
+ final int type = getSelectedVpnType();
if (!editing && requiresUsernamePassword(type)) {
return mUsername.getText().length() != 0 && mPassword.getText().length() != 0;
}
@@ -503,6 +516,8 @@
private void setTypesByFeature(Spinner typeSpinner) {
String[] types = getContext().getResources().getStringArray(R.array.vpn_types);
+ mTotalTypes = new ArrayList<>(Arrays.asList(types));
+ mAllowedTypes = new ArrayList<>(Arrays.asList(types));
if (!getContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_IPSEC_TUNNELS)) {
final List<String> typesList = new ArrayList<>(Arrays.asList(types));
@@ -513,6 +528,26 @@
typesList.remove(VpnProfile.TYPE_IKEV2_IPSEC_USER_PASS);
types = typesList.toArray(new String[0]);
+ } else if (Utils.isProviderModelEnabled(getContext())) {
+ // If the provider mode is enabled and the vpn is new or is not already a legacy type,
+ // don't allow the user to set the type to a legacy option.
+
+ // Set the mProfile.type to TYPE_IKEV2_IPSEC_USER_PASS if the VPN not exist
+ if (!mExists) {
+ mProfile.type = VpnProfile.TYPE_IKEV2_IPSEC_USER_PASS;
+ }
+
+ // Remove all types which are legacy types from the typesList
+ if (!VpnProfile.isLegacyType(mProfile.type)) {
+ for (int i = mAllowedTypes.size() - 1; i >= 0; i--) {
+ // This must be removed from back to front in order to ensure index consistency
+ if (VpnProfile.isLegacyType(i)) {
+ mAllowedTypes.remove(i);
+ }
+ }
+
+ types = mAllowedTypes.toArray(new String[0]);
+ }
}
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(
getContext(), android.R.layout.simple_spinner_item, types);
@@ -577,7 +612,7 @@
// First, save common fields.
VpnProfile profile = new VpnProfile(mProfile.key);
profile.name = mName.getText().toString();
- profile.type = mType.getSelectedItemPosition();
+ profile.type = getSelectedVpnType();
profile.server = mServer.getText().toString().trim();
profile.username = mUsername.getText().toString();
profile.password = mPassword.getText().toString();
@@ -652,4 +687,19 @@
return ProxyUtils.validate(host, port, "") == ProxyUtils.PROXY_VALID;
}
+ private int getSelectedVpnType() {
+ return convertAllowedIndexToProfileType(mType.getSelectedItemPosition());
+ }
+
+ private int convertAllowedIndexToProfileType(int allowedSelectedPosition) {
+ if (mAllowedTypes != null && mTotalTypes != null) {
+ final String typeString = mAllowedTypes.get(allowedSelectedPosition);
+ final int profileType = mTotalTypes.indexOf(typeString);
+ return profileType;
+ } else {
+ Log.w(TAG, "Allowed or Total vpn types not initialized when converting protileType");
+ return allowedSelectedPosition;
+ }
+ }
+
}
diff --git a/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetailsTest.java b/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetailsTest.java
index 197fdff..c5ea21f 100644
--- a/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetailsTest.java
+++ b/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetailsTest.java
@@ -34,7 +34,6 @@
import com.google.common.collect.ImmutableList;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@@ -80,7 +79,6 @@
}
@Test
- @Ignore
public void getPreferenceSummary_appOpNotAllowed_returnsNotAllowed() {
shadowOf(mUserManager).addUser(
PERSONAL_PROFILE_ID, "personal-profile"/* name */, 0/* flags */);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryChartPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryChartPreferenceControllerTest.java
index 7d64960..66ef2d2 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryChartPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryChartPreferenceControllerTest.java
@@ -18,14 +18,18 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.ContentValues;
import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
import androidx.preference.PreferenceGroup;
@@ -55,9 +59,13 @@
@Mock private SettingsActivity mSettingsActivity;
@Mock private PreferenceGroup mAppListGroup;
@Mock private PackageManager mPackageManager;
+ @Mock private Drawable mDrawable;
+ @Mock private BatteryHistEntry mBatteryHistEntry;
@Mock private BatteryChartView mBatteryChartView;
+ @Mock private PowerGaugePreference mPowerGaugePreference;
private Context mContext;
+ private BatteryDiffEntry mBatteryDiffEntry;
private BatteryChartPreferenceController mBatteryChartPreferenceController;
@Before
@@ -71,6 +79,13 @@
mBatteryChartPreferenceController.mPrefContext = mContext;
mBatteryChartPreferenceController.mAppListPrefGroup = mAppListGroup;
mBatteryChartPreferenceController.mBatteryChartView = mBatteryChartView;
+ mBatteryDiffEntry = new BatteryDiffEntry(
+ mContext,
+ /*foregroundUsageTimeInMs=*/ 1,
+ /*backgroundUsageTimeInMs=*/ 2,
+ /*consumePower=*/ 3,
+ mBatteryHistEntry);
+ mBatteryDiffEntry = spy(mBatteryDiffEntry);
// Adds fake testing data.
BatteryDiffEntry.sResourceCache.put(
"fakeBatteryDiffEntryKey",
@@ -100,6 +115,19 @@
}
@Test
+ public void testOnDestroy_clearPreferenceCache() {
+ final String prefKey = "preference fake key";
+ // Ensures the testing environment is correct.
+ mBatteryChartPreferenceController.mPreferenceCache.put(
+ prefKey, mPowerGaugePreference);
+ assertThat(mBatteryChartPreferenceController.mPreferenceCache).hasSize(1);
+
+ mBatteryChartPreferenceController.onDestroy();
+ // Verifies the result after onDestroy.
+ assertThat(mBatteryChartPreferenceController.mPreferenceCache).isEmpty();
+ }
+
+ @Test
public void testSetBatteryHistoryMap_createExpectedKeysAndLevels() {
mBatteryChartPreferenceController.setBatteryHistoryMap(
createBatteryHistoryMap(/*size=*/ 5));
@@ -176,11 +204,70 @@
mBatteryChartPreferenceController.setBatteryHistoryMap(
createBatteryHistoryMap(/*size=*/ 25));
-
assertThat(mBatteryChartPreferenceController.mTrapezoidIndex)
.isEqualTo(BatteryChartView.SELECTED_INDEX_ALL);
}
+ @Test
+ public void testRemoveAndCacheAllPrefs_emptyContent_ignoreRemoveAll() {
+ final int trapezoidIndex = 1;
+ doReturn(0).when(mAppListGroup).getPreferenceCount();
+
+ mBatteryChartPreferenceController.refreshUi(
+ trapezoidIndex, /*isForce=*/ true);
+ verify(mAppListGroup, never()).removeAll();
+ }
+
+ @Test
+ public void testRemoveAndCacheAllPrefs_buildCacheAndRemoveAllPreference() {
+ final int trapezoidIndex = 1;
+ final String prefKey = "preference fake key";
+ doReturn(1).when(mAppListGroup).getPreferenceCount();
+ doReturn(mPowerGaugePreference).when(mAppListGroup).getPreference(0);
+ doReturn(prefKey).when(mPowerGaugePreference).getKey();
+ // Ensures the testing data is correct.
+ assertThat(mBatteryChartPreferenceController.mPreferenceCache).isEmpty();
+
+ mBatteryChartPreferenceController.refreshUi(
+ trapezoidIndex, /*isForce=*/ true);
+
+ assertThat(mBatteryChartPreferenceController.mPreferenceCache.get(prefKey))
+ .isEqualTo(mPowerGaugePreference);
+ verify(mAppListGroup).removeAll();
+ }
+
+ @Test
+ public void testAddPreferenceToScreen_emptyContent_ignoreAddPreference() {
+ mBatteryChartPreferenceController.addPreferenceToScreen(
+ new ArrayList<BatteryDiffEntry>());
+ verify(mAppListGroup, never()).addPreference(any());
+ }
+
+ @Test
+ public void testAddPreferenceToScreen_addPreferenceIntoScreen() {
+ final String prefKey = "preference fake key";
+ final String appLabel = "fake app label";
+ doReturn(1).when(mAppListGroup).getPreferenceCount();
+ doReturn(mDrawable).when(mBatteryDiffEntry).getAppIcon();
+ doReturn(appLabel).when(mBatteryDiffEntry).getAppLabel();
+ doReturn(prefKey).when(mBatteryHistEntry).getKey();
+
+ mBatteryChartPreferenceController.addPreferenceToScreen(
+ Arrays.asList(mBatteryDiffEntry));
+
+ // Verifies the preference cache.
+ final PowerGaugePreference pref =
+ (PowerGaugePreference) mBatteryChartPreferenceController.mPreferenceCache
+ .get(prefKey);
+ assertThat(pref).isNotNull();
+ // Verifies the added preference configuration.
+ verify(mAppListGroup).addPreference(pref);
+ assertThat(pref.getKey()).isEqualTo(prefKey);
+ assertThat(pref.getTitle()).isEqualTo(appLabel);
+ assertThat(pref.getIcon()).isEqualTo(mDrawable);
+ assertThat(pref.getOrder()).isEqualTo(1);
+ }
+
private Map<Long, List<BatteryHistEntry>> createBatteryHistoryMap(int size) {
final Map<Long, List<BatteryHistEntry>> batteryHistoryMap = new HashMap<>();
for (int index = 0; index < size; index++) {