diff --git a/res/xml/power_usage_advanced.xml b/res/xml/power_usage_advanced.xml index f2c3d878e19..3258b7b9ca2 100644 --- a/res/xml/power_usage_advanced.xml +++ b/res/xml/power_usage_advanced.xml @@ -59,16 +59,15 @@ - + diff --git a/src/com/android/settings/fuelgauge/batteryusage/AnomalyAppItemPreference.java b/src/com/android/settings/fuelgauge/batteryusage/AnomalyAppItemPreference.java index 2f139ecaabc..592d30833ed 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/AnomalyAppItemPreference.java +++ b/src/com/android/settings/fuelgauge/batteryusage/AnomalyAppItemPreference.java @@ -16,6 +16,7 @@ package com.android.settings.fuelgauge.batteryusage; +import android.annotation.Nullable; import android.content.Context; import android.text.TextUtils; import android.view.View; @@ -37,7 +38,7 @@ class AnomalyAppItemPreference extends PowerGaugePreference { setLayoutResource(R.layout.anomaly_app_item_preference); } - void setAnomalyHint(CharSequence anomalyHintText) { + void setAnomalyHint(@Nullable CharSequence anomalyHintText) { if (!TextUtils.equals(mAnomalyHintText, anomalyHintText)) { mAnomalyHintText = anomalyHintText; notifyChanged(); diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownController.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownController.java index 09940b3d7f5..6fd4eb5449f 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownController.java +++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownController.java @@ -31,7 +31,6 @@ import android.view.View; import android.widget.AdapterView; import androidx.preference.Preference; -import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceGroup; import androidx.preference.PreferenceScreen; @@ -68,11 +67,11 @@ public class BatteryUsageBreakdownController extends BasePreferenceController private static final String ROOT_PREFERENCE_KEY = "battery_usage_breakdown"; private static final String FOOTER_PREFERENCE_KEY = "battery_usage_footer"; private static final String SPINNER_PREFERENCE_KEY = "battery_usage_spinner"; - private static final String APP_LIST_PREFERENCE_KEY = "app_list"; private static final String PACKAGE_NAME_NONE = "none"; private static final String SLOT_TIMESTAMP = "slot_timestamp"; private static final String ANOMALY_KEY = "anomaly_key"; private static final String KEY_SPINNER_POSITION = "spinner_position"; + private static final int ENTRY_PREF_ORDER_OFFSET = 100; private static final List EMPTY_ENTRY_LIST = new ArrayList<>(); private static int sUiMode = Configuration.UI_MODE_NIGHT_UNDEFINED; @@ -89,8 +88,7 @@ public class BatteryUsageBreakdownController extends BasePreferenceController private SettingsSpinnerAdapter mSpinnerAdapter; @VisibleForTesting Context mPrefContext; - @VisibleForTesting PreferenceCategory mRootPreference; - @VisibleForTesting PreferenceGroup mAppListPreferenceGroup; + @VisibleForTesting PreferenceGroup mRootPreferenceGroup; @VisibleForTesting FooterPreference mFooterPreference; @VisibleForTesting BatteryDiffData mBatteryDiffData; @VisibleForTesting String mBatteryUsageBreakdownTitleLastFullChargeText; @@ -143,7 +141,7 @@ public class BatteryUsageBreakdownController extends BasePreferenceController public void onDestroy() { mHandler.removeCallbacksAndMessages(/* token= */ null); mPreferenceCache.clear(); - mAppListPreferenceGroup.removeAll(); + mRootPreferenceGroup.removeAll(); } @Override @@ -226,9 +224,8 @@ public class BatteryUsageBreakdownController extends BasePreferenceController public void displayPreference(PreferenceScreen screen) { super.displayPreference(screen); mPrefContext = screen.getContext(); - mRootPreference = screen.findPreference(ROOT_PREFERENCE_KEY); + mRootPreferenceGroup = screen.findPreference(ROOT_PREFERENCE_KEY); mSpinnerPreference = screen.findPreference(SPINNER_PREFERENCE_KEY); - mAppListPreferenceGroup = screen.findPreference(APP_LIST_PREFERENCE_KEY); mFooterPreference = screen.findPreference(FOOTER_PREFERENCE_KEY); mBatteryUsageBreakdownTitleLastFullChargeText = mPrefContext.getString( @@ -242,7 +239,7 @@ public class BatteryUsageBreakdownController extends BasePreferenceController R.string.battery_usage_less_than_percent_content_description, formatPercentage); - mAppListPreferenceGroup.setOrderingAsAdded(false); + mRootPreferenceGroup.setOrderingAsAdded(false); mSpinnerAdapter = new SettingsSpinnerAdapter<>(mPrefContext); mSpinnerAdapter.addAll( new String[] { @@ -328,8 +325,9 @@ public class BatteryUsageBreakdownController extends BasePreferenceController : mPrefContext.getString( R.string.battery_usage_breakdown_title_for_slot, accessibilitySlotTimestamp); - mRootPreference.setTitle(Utils.createAccessibleSequence(displayTitle, accessibilityTitle)); - mRootPreference.setVisible(true); + mRootPreferenceGroup.setTitle( + Utils.createAccessibleSequence(displayTitle, accessibilityTitle)); + mRootPreferenceGroup.setVisible(true); } private void showFooterPreference(boolean isAllBatteryUsageEmpty) { @@ -350,7 +348,6 @@ public class BatteryUsageBreakdownController extends BasePreferenceController return; } mSpinnerPreference.setVisible(true); - mAppListPreferenceGroup.setVisible(true); mHandler.post( () -> { removeAndCacheAllUnusedPreferences(); @@ -374,7 +371,7 @@ public class BatteryUsageBreakdownController extends BasePreferenceController } final long start = System.currentTimeMillis(); final List entries = getBatteryDiffEntries(); - int prefIndex = mAppListPreferenceGroup.getPreferenceCount(); + int preferenceOrder = ENTRY_PREF_ORDER_OFFSET; for (BatteryDiffEntry entry : entries) { boolean isAdded = false; final String appLabel = entry.getAppLabel(); @@ -384,33 +381,32 @@ public class BatteryUsageBreakdownController extends BasePreferenceController continue; } final String prefKey = entry.getKey(); - AnomalyAppItemPreference pref = mAppListPreferenceGroup.findPreference(prefKey); - if (pref != null) { + AnomalyAppItemPreference preference = mRootPreferenceGroup.findPreference(prefKey); + if (preference != null) { isAdded = true; } else { - pref = (AnomalyAppItemPreference) mPreferenceCache.get(prefKey); + preference = (AnomalyAppItemPreference) mPreferenceCache.get(prefKey); } // Creates new instance if cached preference is not found. - if (pref == null) { - pref = new AnomalyAppItemPreference(mPrefContext); - pref.setKey(prefKey); - mPreferenceCache.put(prefKey, pref); + if (preference == null) { + preference = new AnomalyAppItemPreference(mPrefContext); + preference.setKey(prefKey); + mPreferenceCache.put(prefKey, preference); } - pref.setIcon(appIcon); - pref.setTitle(appLabel); - pref.setOrder(prefIndex); - pref.setSingleLineTitle(true); + preference.setIcon(appIcon); + preference.setTitle(appLabel); + preference.setOrder(++preferenceOrder); + preference.setSingleLineTitle(true); // Updates App item preference style - pref.setAnomalyHint(isAnomalyBatteryDiffEntry(entry) ? mAnomalyHintString : null); + preference.setAnomalyHint(isAnomalyBatteryDiffEntry(entry) ? mAnomalyHintString : null); // Sets the BatteryDiffEntry to preference for launching detailed page. - pref.setBatteryDiffEntry(entry); - pref.setSelectable(entry.validForRestriction()); - setPreferencePercentage(pref, entry); - setPreferenceSummary(pref, entry); + preference.setBatteryDiffEntry(entry); + preference.setSelectable(entry.validForRestriction()); + setPreferencePercentage(preference, entry); + setPreferenceSummary(preference, entry); if (!isAdded) { - mAppListPreferenceGroup.addPreference(pref); + mRootPreferenceGroup.addPreference(preference); } - prefIndex++; } Log.d( TAG, @@ -424,17 +420,22 @@ public class BatteryUsageBreakdownController extends BasePreferenceController List entries = getBatteryDiffEntries(); Set entryKeySet = new ArraySet<>(entries.size()); entries.forEach(entry -> entryKeySet.add(entry.getKey())); - final int prefsCount = mAppListPreferenceGroup.getPreferenceCount(); - for (int index = prefsCount - 1; index >= 0; index--) { - final Preference pref = mAppListPreferenceGroup.getPreference(index); - if (entryKeySet.contains(pref.getKey())) { - // The pref is still used, don't remove. + final int preferenceCount = mRootPreferenceGroup.getPreferenceCount(); + for (int index = preferenceCount - 1; index >= 0; index--) { + final Preference preference = mRootPreferenceGroup.getPreference(index); + if ((preference instanceof SettingsSpinnerPreference) + || (preference instanceof FooterPreference)) { + // Consider the app preference only and skip others continue; } - if (!TextUtils.isEmpty(pref.getKey())) { - mPreferenceCache.put(pref.getKey(), pref); + if (entryKeySet.contains(preference.getKey())) { + // Don't remove the preference if it is still in use + continue; } - mAppListPreferenceGroup.removePreference(pref); + if (!TextUtils.isEmpty(preference.getKey())) { + mPreferenceCache.put(preference.getKey(), preference); + } + mRootPreferenceGroup.removePreference(preference); } } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownControllerTest.java index 85fc6e210ce..c4cbb988ae6 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownControllerTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownControllerTest.java @@ -59,11 +59,12 @@ public final class BatteryUsageBreakdownControllerTest { private static final String PREF_KEY2 = "pref_key2"; private static final String PREF_SUMMARY = "fake preference summary"; private static final String KEY_SPINNER_POSITION = "spinner_position"; - private static final long TIME_LESS_THAN_HALF_MINUTE = DateUtils.MINUTE_IN_MILLIS / 2 - 1; + private static final int ENTRY_PREF_ORDER_OFFSET = 100; + private static final long TIME_LESS_THAN_HALF_MINUTE = DateUtils.MINUTE_IN_MILLIS / 2 - 1; @Mock private InstrumentedPreferenceFragment mFragment; @Mock private SettingsActivity mSettingsActivity; - @Mock private PreferenceGroup mAppListPreferenceGroup; + @Mock private PreferenceGroup mRootPreferenceGroup; @Mock private Drawable mDrawable; @Mock private BatteryHistEntry mBatteryHistEntry; @Mock private AnomalyAppItemPreference mAnomalyAppItemPreference; @@ -90,7 +91,7 @@ public final class BatteryUsageBreakdownControllerTest { .when(mFeatureFactory.powerUsageFeatureProvider) .getHideApplicationSet(); mBatteryUsageBreakdownController = createController(); - mBatteryUsageBreakdownController.mAppListPreferenceGroup = mAppListPreferenceGroup; + mBatteryUsageBreakdownController.mRootPreferenceGroup = mRootPreferenceGroup; mBatteryDiffEntry = new BatteryDiffEntry( mContext, @@ -130,7 +131,7 @@ public final class BatteryUsageBreakdownControllerTest { BatteryDiffEntry.sResourceCache.put( "fakeBatteryDiffEntryKey", new BatteryEntry.NameAndIcon("fakeName", /* icon= */ null, /* iconId= */ 1)); - doReturn(mAnomalyAppItemPreference).when(mAppListPreferenceGroup).findPreference(PREF_KEY); + doReturn(mAnomalyAppItemPreference).when(mRootPreferenceGroup).findPreference(PREF_KEY); } @Test @@ -147,7 +148,7 @@ public final class BatteryUsageBreakdownControllerTest { @Test public void onDestroy_removeAllPreferenceFromPreferenceGroup() { mBatteryUsageBreakdownController.onDestroy(); - verify(mAppListPreferenceGroup).removeAll(); + verify(mRootPreferenceGroup).removeAll(); } @Test @@ -162,11 +163,11 @@ public final class BatteryUsageBreakdownControllerTest { @Test public void addAllPreferences_addAllPreferences() { final String appLabel = "fake app label"; - doReturn(1).when(mAppListPreferenceGroup).getPreferenceCount(); + doReturn(1).when(mRootPreferenceGroup).getPreferenceCount(); doReturn(mDrawable).when(mBatteryDiffEntry).getAppIcon(); doReturn(appLabel).when(mBatteryDiffEntry).getAppLabel(); doReturn(PREF_KEY).when(mBatteryDiffEntry).getKey(); - doReturn(null).when(mAppListPreferenceGroup).findPreference(PREF_KEY); + doReturn(null).when(mRootPreferenceGroup).findPreference(PREF_KEY); doReturn(false).when(mBatteryDiffEntry).validForRestriction(); mBatteryUsageBreakdownController.addAllPreferences(); @@ -177,11 +178,11 @@ public final class BatteryUsageBreakdownControllerTest { mBatteryUsageBreakdownController.mPreferenceCache.get(PREF_KEY); assertThat(pref).isNotNull(); // Verifies the added preference configuration. - verify(mAppListPreferenceGroup).addPreference(pref); + verify(mRootPreferenceGroup).addPreference(pref); assertThat(pref.getKey()).isEqualTo(PREF_KEY); assertThat(pref.getTitle().toString()).isEqualTo(appLabel); assertThat(pref.getIcon()).isEqualTo(mDrawable); - assertThat(pref.getOrder()).isEqualTo(1); + assertThat(pref.getOrder()).isEqualTo(ENTRY_PREF_ORDER_OFFSET + 1); assertThat(pref.getBatteryDiffEntry()).isSameInstanceAs(mBatteryDiffEntry); assertThat(pref.isSingleLineTitle()).isTrue(); assertThat(pref.isSelectable()).isFalse(); @@ -190,20 +191,20 @@ public final class BatteryUsageBreakdownControllerTest { @Test public void addPreferenceToScreen_alreadyInScreen_notAddPreferenceAgain() { final String appLabel = "fake app label"; - doReturn(1).when(mAppListPreferenceGroup).getPreferenceCount(); + doReturn(1).when(mRootPreferenceGroup).getPreferenceCount(); doReturn(mDrawable).when(mBatteryDiffEntry).getAppIcon(); doReturn(appLabel).when(mBatteryDiffEntry).getAppLabel(); doReturn(PREF_KEY).when(mBatteryDiffEntry).getKey(); mBatteryUsageBreakdownController.addAllPreferences(); - verify(mAppListPreferenceGroup, never()).addPreference(any()); + verify(mRootPreferenceGroup, never()).addPreference(any()); } @Test public void removeAndCacheAllUnusedPreferences_removePref_buildCacheAndRemoveAllPreference() { - doReturn(1).when(mAppListPreferenceGroup).getPreferenceCount(); - doReturn(mAnomalyAppItemPreference).when(mAppListPreferenceGroup).getPreference(0); + doReturn(1).when(mRootPreferenceGroup).getPreferenceCount(); + doReturn(mAnomalyAppItemPreference).when(mRootPreferenceGroup).getPreference(0); doReturn(PREF_KEY2).when(mBatteryHistEntry).getKey(); doReturn(PREF_KEY).when(mAnomalyAppItemPreference).getKey(); // Ensures the testing data is correct. @@ -213,13 +214,13 @@ public final class BatteryUsageBreakdownControllerTest { assertThat(mBatteryUsageBreakdownController.mPreferenceCache.get(PREF_KEY)) .isEqualTo(mAnomalyAppItemPreference); - verify(mAppListPreferenceGroup).removePreference(mAnomalyAppItemPreference); + verify(mRootPreferenceGroup).removePreference(mAnomalyAppItemPreference); } @Test public void removeAndCacheAllUnusedPreferences_keepPref_KeepAllPreference() { - doReturn(1).when(mAppListPreferenceGroup).getPreferenceCount(); - doReturn(mAnomalyAppItemPreference).when(mAppListPreferenceGroup).getPreference(0); + doReturn(1).when(mRootPreferenceGroup).getPreferenceCount(); + doReturn(mAnomalyAppItemPreference).when(mRootPreferenceGroup).getPreference(0); doReturn(PREF_KEY).when(mBatteryDiffEntry).getKey(); doReturn(PREF_KEY).when(mAnomalyAppItemPreference).getKey(); // Ensures the testing data is correct. @@ -227,15 +228,13 @@ public final class BatteryUsageBreakdownControllerTest { mBatteryUsageBreakdownController.removeAndCacheAllUnusedPreferences(); - verify(mAppListPreferenceGroup, never()).removePreference(any()); + verify(mRootPreferenceGroup, never()).removePreference(any()); assertThat(mBatteryUsageBreakdownController.mPreferenceCache).isEmpty(); } @Test public void handlePreferenceTreeClick_notPowerGaugePreference_returnFalse() { - assertThat( - mBatteryUsageBreakdownController.handlePreferenceTreeClick( - mAppListPreferenceGroup)) + assertThat(mBatteryUsageBreakdownController.handlePreferenceTreeClick(mRootPreferenceGroup)) .isFalse(); verify(mMetricsFeatureProvider, never())