Impl dismiss action in battery tips cards.
- Use SharedPreferences to record and filter the already dimissed anomaly. Bug: 291689623 Test: manual Change-Id: I4fd4a39066591a4a201857f9586b6595b7d5c43b
This commit is contained in:
@@ -52,10 +52,10 @@ import com.google.common.base.Objects;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@@ -397,12 +397,23 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
|
||||
return true;
|
||||
}
|
||||
|
||||
private PowerAnomalyEvent getHighestScoreAnomalyEvent(PowerAnomalyEventList anomalyEventList) {
|
||||
@VisibleForTesting
|
||||
PowerAnomalyEvent getHighestScoreAnomalyEvent(PowerAnomalyEventList anomalyEventList) {
|
||||
if (anomalyEventList == null || anomalyEventList.getPowerAnomalyEventsCount() == 0) {
|
||||
return null;
|
||||
}
|
||||
return Collections.max(anomalyEventList.getPowerAnomalyEventsList(),
|
||||
Comparator.comparing(PowerAnomalyEvent::getScore));
|
||||
final Set<String> dismissedPowerAnomalyKeys =
|
||||
DatabaseUtils.getDismissedPowerAnomalyKeys(mContext);
|
||||
Log.d(TAG, "dismissedPowerAnomalyKeys = " + dismissedPowerAnomalyKeys);
|
||||
|
||||
final PowerAnomalyEvent highestScoreEvent = anomalyEventList.getPowerAnomalyEventsList()
|
||||
.stream()
|
||||
.filter(event -> event.hasKey()
|
||||
&& !dismissedPowerAnomalyKeys.contains(event.getKey().name()))
|
||||
.max(Comparator.comparing(PowerAnomalyEvent::getScore))
|
||||
.orElse(null);
|
||||
Log.d(TAG, "highestScoreAnomalyEvent = " + highestScoreEvent);
|
||||
return highestScoreEvent;
|
||||
}
|
||||
|
||||
private boolean refreshUiWithNoLevelDataCase() {
|
||||
|
@@ -50,6 +50,7 @@ public class BatteryTipsCardPreference extends Preference implements View.OnClic
|
||||
private final MetricsFeatureProvider mMetricsFeatureProvider;
|
||||
|
||||
private String mAnomalyEventId;
|
||||
private PowerAnomalyKey mPowerAnomalyKey;
|
||||
|
||||
@VisibleForTesting
|
||||
CharSequence mMainButtonLabel;
|
||||
@@ -69,6 +70,7 @@ public class BatteryTipsCardPreference extends Preference implements View.OnClic
|
||||
final FeatureFactory featureFactory = FeatureFactory.getFeatureFactory();
|
||||
mPowerUsageFeatureProvider = featureFactory.getPowerUsageFeatureProvider();
|
||||
mMetricsFeatureProvider = featureFactory.getMetricsFeatureProvider();
|
||||
mPowerAnomalyKey = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,6 +100,13 @@ public class BatteryTipsCardPreference extends Preference implements View.OnClic
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the power anomaly key of battery tips card.
|
||||
*/
|
||||
public void setPowerAnomalyKey(final PowerAnomalyKey powerAnomalyKey) {
|
||||
mPowerAnomalyKey = powerAnomalyKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the info of target fragment launched by main button.
|
||||
*/
|
||||
@@ -133,6 +142,9 @@ public class BatteryTipsCardPreference extends Preference implements View.OnClic
|
||||
setVisible(false);
|
||||
mMetricsFeatureProvider.action(
|
||||
getContext(), SettingsEnums.ACTION_BATTERY_TIPS_CARD_DISMISS, mAnomalyEventId);
|
||||
if (mPowerAnomalyKey != null) {
|
||||
DatabaseUtils.setDismissedPowerAnomalyKeys(getContext(), mPowerAnomalyKey.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -108,8 +108,9 @@ public class BatteryTipsController extends BasePreferenceController {
|
||||
}
|
||||
|
||||
// Get card preference strings and navigate fragment info
|
||||
final int resourceIndex = powerAnomalyEvent.hasKey()
|
||||
? powerAnomalyEvent.getKey().getNumber() : -1;
|
||||
final PowerAnomalyKey powerAnomalyKey = powerAnomalyEvent.hasKey()
|
||||
? powerAnomalyEvent.getKey() : null;
|
||||
final int resourceIndex = powerAnomalyKey != null ? powerAnomalyKey.getNumber() : -1;
|
||||
|
||||
String titleString = getString(powerAnomalyEvent, WarningBannerInfo::getTitleString,
|
||||
WarningItemInfo::getTitleString, R.array.power_anomaly_titles, resourceIndex);
|
||||
@@ -134,6 +135,7 @@ public class BatteryTipsController extends BasePreferenceController {
|
||||
|
||||
// Updated card preference and main button fragment launcher
|
||||
mCardPreference.setAnomalyEventId(powerAnomalyEvent.getEventId());
|
||||
mCardPreference.setPowerAnomalyKey(powerAnomalyKey);
|
||||
mCardPreference.setTitle(titleString);
|
||||
mCardPreference.setMainButtonLabel(mainBtnString);
|
||||
mCardPreference.setDismissButtonLabel(dismissBtnString);
|
||||
|
@@ -74,6 +74,7 @@ public final class BatteryUsageDataLoader {
|
||||
context, DatabaseUtils.KEY_LAST_LOAD_FULL_CHARGE_TIME);
|
||||
DatabaseUtils.sendBatteryEventData(context, ConvertUtils.convertToBatteryEvent(
|
||||
currentTime, BatteryEventType.FULL_CHARGED, 100));
|
||||
DatabaseUtils.removeDismissedPowerAnomalyKeys(context);
|
||||
}
|
||||
|
||||
// Uploads the BatteryEntry data into database.
|
||||
|
@@ -35,6 +35,7 @@ import android.os.Looper;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserManager;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
@@ -53,6 +54,7 @@ import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -69,6 +71,7 @@ public final class DatabaseUtils {
|
||||
static final String KEY_LAST_LOAD_FULL_CHARGE_TIME = "last_load_full_charge_time";
|
||||
static final String KEY_LAST_UPLOAD_FULL_CHARGE_TIME = "last_upload_full_charge_time";
|
||||
static final String KEY_LAST_USAGE_SOURCE = "last_usage_source";
|
||||
static final String KEY_DISMISSED_POWER_ANOMALY_KEYS = "dismissed_power_anomaly_keys";
|
||||
|
||||
/** An authority name of the battery content provider. */
|
||||
public static final String AUTHORITY = "com.android.settings.battery.usage.provider";
|
||||
@@ -636,6 +639,8 @@ public final class DatabaseUtils {
|
||||
KEY_LAST_LOAD_FULL_CHARGE_TIME);
|
||||
writeString(context, writer, "LastUploadFullChargeTime",
|
||||
KEY_LAST_UPLOAD_FULL_CHARGE_TIME);
|
||||
writeString(context, writer, "DismissedPowerAnomalyKeys",
|
||||
KEY_DISMISSED_POWER_ANOMALY_KEYS);
|
||||
}
|
||||
|
||||
static SharedPreferences getSharedPreferences(Context context) {
|
||||
@@ -674,6 +679,32 @@ public final class DatabaseUtils {
|
||||
return usageSource;
|
||||
}
|
||||
|
||||
static void removeDismissedPowerAnomalyKeys(Context context) {
|
||||
final SharedPreferences sharedPreferences = getSharedPreferences(context);
|
||||
if (sharedPreferences != null
|
||||
&& sharedPreferences.contains(KEY_DISMISSED_POWER_ANOMALY_KEYS)) {
|
||||
sharedPreferences.edit().remove(KEY_DISMISSED_POWER_ANOMALY_KEYS).apply();
|
||||
}
|
||||
}
|
||||
|
||||
static Set<String> getDismissedPowerAnomalyKeys(Context context) {
|
||||
final SharedPreferences sharedPreferences = getSharedPreferences(context);
|
||||
return sharedPreferences != null
|
||||
? sharedPreferences.getStringSet(KEY_DISMISSED_POWER_ANOMALY_KEYS, new ArraySet<>())
|
||||
: new ArraySet<>();
|
||||
}
|
||||
|
||||
static void setDismissedPowerAnomalyKeys(Context context, String dismissedPowerAnomalyKey) {
|
||||
final SharedPreferences sharedPreferences = getSharedPreferences(context);
|
||||
if (sharedPreferences != null) {
|
||||
final Set<String> dismissedPowerAnomalyKeys = getDismissedPowerAnomalyKeys(context);
|
||||
dismissedPowerAnomalyKeys.add(dismissedPowerAnomalyKey);
|
||||
sharedPreferences.edit()
|
||||
.putStringSet(KEY_DISMISSED_POWER_ANOMALY_KEYS, dismissedPowerAnomalyKeys)
|
||||
.apply();
|
||||
}
|
||||
}
|
||||
|
||||
static void recordDateTime(Context context, String preferenceKey) {
|
||||
final SharedPreferences sharedPreferences = getSharedPreferences(context);
|
||||
if (sharedPreferences != null) {
|
||||
|
@@ -46,6 +46,7 @@ import android.view.ViewPropertyAnimator;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.testutils.BatteryTestUtils;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -407,6 +408,57 @@ public final class BatteryChartPreferenceControllerTest {
|
||||
assertThat(totalHour).isEqualTo(59);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getHighestScoreAnomalyEvent_withEmptyOrNullList_getNull() {
|
||||
assertThat(mBatteryChartPreferenceController.getHighestScoreAnomalyEvent(null))
|
||||
.isEqualTo(null);
|
||||
assertThat(mBatteryChartPreferenceController.getHighestScoreAnomalyEvent(
|
||||
BatteryTestUtils.createEmptyPowerAnomalyEventList()))
|
||||
.isEqualTo(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getHighestScoreAnomalyEvent_withoutDismissed_getHighestScoreEvent() {
|
||||
final PowerAnomalyEventList eventList =
|
||||
BatteryTestUtils.createNonEmptyPowerAnomalyEventList();
|
||||
|
||||
final PowerAnomalyEvent highestScoreEvent =
|
||||
mBatteryChartPreferenceController.getHighestScoreAnomalyEvent(eventList);
|
||||
|
||||
assertThat(highestScoreEvent)
|
||||
.isEqualTo(BatteryTestUtils.createAdaptiveBrightnessAnomalyEvent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getHighestScoreAnomalyEvent_withBrightnessDismissed_getScreenTimeout() {
|
||||
final PowerAnomalyEventList eventList =
|
||||
BatteryTestUtils.createNonEmptyPowerAnomalyEventList();
|
||||
DatabaseUtils.removeDismissedPowerAnomalyKeys(mContext);
|
||||
DatabaseUtils.setDismissedPowerAnomalyKeys(mContext, PowerAnomalyKey.KEY_BRIGHTNESS.name());
|
||||
|
||||
final PowerAnomalyEvent highestScoreEvent =
|
||||
mBatteryChartPreferenceController.getHighestScoreAnomalyEvent(eventList);
|
||||
|
||||
assertThat(highestScoreEvent)
|
||||
.isEqualTo(BatteryTestUtils.createScreenTimeoutAnomalyEvent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getHighestScoreAnomalyEvent_withAllDismissed_getNull() {
|
||||
final PowerAnomalyEventList eventList =
|
||||
BatteryTestUtils.createNonEmptyPowerAnomalyEventList();
|
||||
DatabaseUtils.removeDismissedPowerAnomalyKeys(mContext);
|
||||
for (PowerAnomalyKey key : PowerAnomalyKey.values()) {
|
||||
DatabaseUtils.setDismissedPowerAnomalyKeys(mContext, key.name());
|
||||
}
|
||||
|
||||
final PowerAnomalyEvent highestScoreEvent =
|
||||
mBatteryChartPreferenceController.getHighestScoreAnomalyEvent(eventList);
|
||||
|
||||
assertThat(highestScoreEvent).isEqualTo(null);
|
||||
}
|
||||
|
||||
|
||||
private static Long generateTimestamp(int index) {
|
||||
// "2021-04-23 07:00:00 UTC" + index hours
|
||||
return 1619247600000L + index * DateUtils.HOUR_IN_MILLIS;
|
||||
|
@@ -83,6 +83,7 @@ public final class BatteryTipsCardPreferenceTest {
|
||||
mBatteryTipsController.handleBatteryTipsCardUpdated(adaptiveBrightnessAnomaly);
|
||||
mBatteryTipsCardPreference.onClick(mFakeView);
|
||||
|
||||
assertThat(mBatteryTipsCardPreference.isVisible()).isEqualTo(false);
|
||||
verify(mContext).startActivity(any(Intent.class));
|
||||
final Intent intent = captor.getValue();
|
||||
assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
|
||||
@@ -94,15 +95,21 @@ public final class BatteryTipsCardPreferenceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onClick_dismissBtn_metricsLogged() {
|
||||
public void onClick_dismissBtn_cardDismissAndLogged() {
|
||||
PowerAnomalyEvent screenTimeoutAnomaly =
|
||||
BatteryTestUtils.createScreenTimeoutAnomalyEvent();
|
||||
DatabaseUtils.removeDismissedPowerAnomalyKeys(mContext);
|
||||
when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
|
||||
when(mFakeView.getId()).thenReturn(R.id.dismiss_button);
|
||||
|
||||
mBatteryTipsController.handleBatteryTipsCardUpdated(screenTimeoutAnomaly);
|
||||
mBatteryTipsCardPreference.onClick(mFakeView);
|
||||
|
||||
assertThat(mBatteryTipsCardPreference.isVisible()).isEqualTo(false);
|
||||
assertThat(DatabaseUtils.getDismissedPowerAnomalyKeys(mContext).size())
|
||||
.isEqualTo(1);
|
||||
assertThat(DatabaseUtils.getDismissedPowerAnomalyKeys(mContext))
|
||||
.contains(PowerAnomalyKey.KEY_SCREEN_TIMEOUT.name());
|
||||
verify(mFeatureFactory.metricsFeatureProvider).action(
|
||||
mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_DISMISS, "ScreenTimeoutAnomaly");
|
||||
}
|
||||
|
@@ -208,12 +208,21 @@ public class BatteryTestUtils {
|
||||
return PowerAnomalyEventList.getDefaultInstance();
|
||||
}
|
||||
|
||||
/** Create an non-empty power anomaly event list proto. */
|
||||
public static PowerAnomalyEventList createNonEmptyPowerAnomalyEventList() {
|
||||
return PowerAnomalyEventList.newBuilder()
|
||||
.addPowerAnomalyEvents(0, createAdaptiveBrightnessAnomalyEvent())
|
||||
.addPowerAnomalyEvents(1, createScreenTimeoutAnomalyEvent())
|
||||
.build();
|
||||
}
|
||||
|
||||
/** Create a power anomaly event proto of adaptive brightness. */
|
||||
public static PowerAnomalyEvent createAdaptiveBrightnessAnomalyEvent() {
|
||||
return PowerAnomalyEvent.newBuilder()
|
||||
.setEventId("BrightnessAnomaly")
|
||||
.setType(PowerAnomalyType.TYPE_SETTINGS_BANNER)
|
||||
.setKey(PowerAnomalyKey.KEY_BRIGHTNESS)
|
||||
.setScore(1.2f)
|
||||
.setWarningBannerInfo(WarningBannerInfo.newBuilder()
|
||||
.setMainButtonDestination(DisplaySettings.class.getName())
|
||||
.setMainButtonSourceMetricsCategory(SettingsEnums.DISPLAY)
|
||||
@@ -228,6 +237,7 @@ public class BatteryTestUtils {
|
||||
.setEventId("ScreenTimeoutAnomaly")
|
||||
.setType(PowerAnomalyType.TYPE_SETTINGS_BANNER)
|
||||
.setKey(PowerAnomalyKey.KEY_SCREEN_TIMEOUT)
|
||||
.setScore(1.1f)
|
||||
.setWarningBannerInfo(WarningBannerInfo.newBuilder()
|
||||
.setMainButtonDestination(ScreenTimeoutSettings.class.getName())
|
||||
.setMainButtonSourceMetricsCategory(SettingsEnums.SCREEN_TIMEOUT)
|
||||
|
Reference in New Issue
Block a user