Merge "update navigation mode settings string" into udc-qpr-dev
diff --git a/res/layout/battery_chart_graph.xml b/res/layout/battery_chart_graph.xml
index f116c8e..9e816ed 100644
--- a/res/layout/battery_chart_graph.xml
+++ b/res/layout/battery_chart_graph.xml
@@ -27,6 +27,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="16dp"
+ android:textAlignment="viewStart"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"
android:text="@string/battery_usage_chart_graph_hint_last_full_charge" />
@@ -40,7 +41,7 @@
<com.android.settings.fuelgauge.batteryusage.BatteryChartView
android:id="@+id/daily_battery_chart"
android:layout_width="match_parent"
- android:layout_height="170dp"
+ android:layout_height="@dimen/chartview_layout_height"
android:layout_marginBottom="16dp"
android:visibility="gone"
android:contentDescription="@string/daily_battery_usage_chart"
@@ -50,7 +51,7 @@
<com.android.settings.fuelgauge.batteryusage.BatteryChartView
android:id="@+id/hourly_battery_chart"
android:layout_width="match_parent"
- android:layout_height="170dp"
+ android:layout_height="@dimen/chartview_layout_height"
android:layout_marginBottom="16dp"
android:visibility="visible"
android:contentDescription="@string/hourly_battery_usage_chart"
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index fd582de..4ae140e 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -369,6 +369,12 @@
<dimen name="chartview_text_padding">6dp</dimen>
<dimen name="chartview_divider_width">1dp</dimen>
<dimen name="chartview_divider_height">4dp</dimen>
+ <dimen name="chartview_transom_width">4dp</dimen>
+ <dimen name="chartview_transom_radius">4dp</dimen>
+ <dimen name="chartview_transom_icon_size">12dp</dimen>
+ <dimen name="chartview_transom_padding_top">2dp</dimen>
+ <dimen name="chartview_transom_layout_height">12dp</dimen>
+ <dimen name="chartview_layout_height">182dp</dimen>
<dimen name="chartview_trapezoid_radius">5dp</dimen>
<dimen name="chartview_trapezoid_margin_start">1dp</dimen>
<dimen name="chartview_trapezoid_margin_bottom">2dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 545e784..aef86a6 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -12144,11 +12144,13 @@
<!-- [CHAR LIMIT=60] Aspect ratio title setting to choose app aspect ratio -->
<string name="aspect_ratio_title">Aspect ratio</string>
<!-- [CHAR LIMIT=NONE] Aspect ratio setting summary to choose aspect ratio for apps unoptimized for device -->
- <string name="aspect_ratio_summary">Choose an aspect ratio to view this app if it hasn\'t been designed to fit your <xliff:g id="device_name">%1$s</xliff:g></string>
+ <string name="aspect_ratio_summary">Try a new aspect ratio to view this app if it hasn\'t been designed to fit your <xliff:g id="device_name">%1$s</xliff:g></string>
+ <!-- [CHAR LIMIT=NONE] Aspect ratio setting main summary on page to choose aspect ratio for apps unoptimized for device -->
+ <string name="aspect_ratio_main_summary">Try a new aspect ratio to view this app if it hasn\'t been designed to fit your <xliff:g id="device_name">%1$s</xliff:g>. Some apps may not be optimized for certain aspect ratios.</string>
<!-- [CHAR LIMIT=NONE] Aspect ratio suggested apps filter label -->
<string name="user_aspect_ratio_suggested_apps_label">Suggested apps</string>
- <!-- [CHAR LIMIT=NONE] Filter label for apps that have user aspect ratio override applied -->
- <string name="user_aspect_ratio_overridden_apps_label">Apps you have overridden</string>
+ <!-- [CHAR LIMIT=14] Filter label for apps that have user aspect ratio changed -->
+ <string name="user_aspect_ratio_changed_apps_label">Changed apps</string>
<!-- [CHAR LIMIT=NONE] App default aspect ratio entry -->
<string name="user_aspect_ratio_app_default">App default</string>
<!-- [CHAR LIMIT=NONE] Fullscreen aspect ratio entry -->
@@ -12164,7 +12166,7 @@
<!-- [CHAR LIMIT=NONE] 4:3 aspect ratio entry -->
<string name="user_aspect_ratio_4_3">4:3</string>
<!-- [CHAR LIMIT=NONE] Warning description for app info aspect ratio page -->
- <string name="app_aspect_ratio_footer">The app will restart when you change aspect ratio. You may lose unsaved changes.</string>
+ <string name="app_aspect_ratio_footer">The app will restart when you change aspect ratio. You may lose unsaved changes. Some apps may not be optimized for certain aspect ratios.</string>
<!-- Accessibility label for fingerprint sensor [CHAR LIMIT=NONE] -->
diff --git a/res/xml/apps.xml b/res/xml/apps.xml
index 651ed9b..db46a1a 100644
--- a/res/xml/apps.xml
+++ b/res/xml/apps.xml
@@ -80,18 +80,6 @@
android:order="10"/>
<Preference
- android:key="aspect_ratio_apps"
- android:title="@string/aspect_ratio_title"
- android:summary="@string/summary_placeholder"
- android:order="14"
- settings:controller="com.android.settings.applications.appcompat.UserAspectRatioAppsPreferenceController"
- android:fragment="com.android.settings.applications.manageapplications.ManageApplications">
- <extra android:name="classname"
- android:value="com.android.settings.Settings$UserAspectRatioAppListActivity"/>
- <intent android:action="android.settings.MANAGE_USER_ASPECT_RATIO_SETTINGS"/>
- </Preference>
-
- <Preference
android:key="hibernated_apps"
android:title="@string/unused_apps"
android:summary="@string/summary_placeholder"
@@ -119,4 +107,23 @@
android:title="@string/special_access"
android:order="20"/>
+ <PreferenceCategory
+ android:key="advanced_category"
+ android:title="@string/advanced_apps"
+ android:order="21"
+ android:visibility="gone"
+ settings:searchable="false"/>
+
+ <Preference
+ android:key="aspect_ratio_apps"
+ android:title="@string/aspect_ratio_title"
+ android:summary="@string/summary_placeholder"
+ android:order="22"
+ settings:controller="com.android.settings.applications.appcompat.UserAspectRatioAppsPreferenceController"
+ android:fragment="com.android.settings.applications.manageapplications.ManageApplications">
+ <extra android:name="classname"
+ android:value="com.android.settings.Settings$UserAspectRatioAppListActivity"/>
+ <intent android:action="android.settings.MANAGE_USER_ASPECT_RATIO_SETTINGS"/>
+ </Preference>
+
</PreferenceScreen>
diff --git a/res/xml/reset_dashboard_fragment.xml b/res/xml/reset_dashboard_fragment.xml
index 3bd7a13..08852c9 100644
--- a/res/xml/reset_dashboard_fragment.xml
+++ b/res/xml/reset_dashboard_fragment.xml
@@ -57,5 +57,13 @@
settings:keywords="@string/keywords_factory_data_reset"
settings:userRestriction="no_factory_reset"
settings:useAdminDisabledSummary="true"
+ settings:controller="com.android.settings.system.FactoryResetPreferenceController"
+ android:fragment="com.android.settings.MainClear" />
+
+ <Preference
+ android:key="factory_reset_demo_user"
+ android:title="@string/main_clear_title"
+ settings:keywords="@string/keywords_factory_data_reset"
+ settings:controller="com.android.settings.system.FactoryResetDemoUserPreferenceController"
android:fragment="com.android.settings.MainClear" />
</PreferenceScreen>
diff --git a/src/com/android/settings/MainClear.java b/src/com/android/settings/MainClear.java
index f706c78..8a441e2 100644
--- a/src/com/android/settings/MainClear.java
+++ b/src/com/android/settings/MainClear.java
@@ -569,7 +569,7 @@
UserHandle.myUserId());
if (disallow && !Utils.isDemoUser(context)) {
return inflater.inflate(R.layout.main_clear_disallowed_screen, null);
- } else if (admin != null) {
+ } else if (admin != null && !Utils.isDemoUser(context)) {
new ActionDisabledByAdminDialogHelper(getActivity())
.prepareDialogBuilder(UserManager.DISALLOW_FACTORY_RESET, admin)
.setOnDismissListener(__ -> getActivity().finish())
diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
index 30eabfa..4253ca6 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
@@ -44,11 +44,6 @@
boolean isBatteryTipsEnabled();
/**
- * Check whether the feedback card is enabled in the battery tips card
- */
- boolean isBatteryTipsFeedbackEnabled();
-
- /**
* Returns a threshold (in milliseconds) for the minimal screen on time in battery usage list
*/
double getBatteryUsageListScreenOnTimeThresholdInMs();
diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
index 127178a..5931e206 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
@@ -81,11 +81,6 @@
}
@Override
- public boolean isBatteryTipsFeedbackEnabled() {
- return false;
- }
-
- @Override
public double getBatteryUsageListScreenOnTimeThresholdInMs() {
return 0;
}
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java
index 1720f0d..1893096 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java
@@ -36,7 +36,6 @@
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -44,7 +43,6 @@
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnCreate;
import com.android.settingslib.core.lifecycle.events.OnDestroy;
-import com.android.settingslib.core.lifecycle.events.OnPause;
import com.android.settingslib.core.lifecycle.events.OnResume;
import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
@@ -52,17 +50,12 @@
import java.util.ArrayList;
import java.util.Calendar;
-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;
/** Controls the update for chart graph and the list items. */
public class BatteryChartPreferenceController extends AbstractPreferenceController
- implements PreferenceControllerMixin, LifecycleObserver, OnCreate, OnDestroy, OnPause,
+ implements PreferenceControllerMixin, LifecycleObserver, OnCreate, OnDestroy,
OnSaveInstanceState, OnResume {
private static final String TAG = "BatteryChartPreferenceController";
private static final String PREFERENCE_KEY = "battery_chart";
@@ -74,53 +67,17 @@
private static final String KEY_DAILY_CHART_INDEX = "daily_chart_index";
private static final String KEY_HOURLY_CHART_INDEX = "hourly_chart_index";
- /**
- * A callback listener for battery usage is updated.
- * This happens when battery usage data is ready or the selected index is changed.
- */
- public interface OnBatteryUsageUpdatedListener {
- /**
- * The callback function for battery usage is updated.
- * @param slotUsageData The battery usage diff data for the selected slot. This is used in
- * the app list.
- * @param slotTimestamp The selected slot timestamp information. This is used in the battery
- * usage breakdown category.
- * @param isAllUsageDataEmpty Whether all the battery usage data is null or empty. This is
- * used when showing the footer.
- */
- void onBatteryUsageUpdated(
- BatteryDiffData slotUsageData, String slotTimestamp, boolean isAllUsageDataEmpty);
+ /** A callback listener for the selected index is updated. */
+ interface OnSelectedIndexUpdatedListener {
+ /** The callback function for the selected index is updated. */
+ void onSelectedIndexUpdated();
}
- /**
- * A callback listener for the device screen on time is updated.
- * This happens when screen on time data is ready or the selected index is changed.
- */
- public interface OnScreenOnTimeUpdatedListener {
- /**
- * The callback function for the device screen on time is updated.
- * @param screenOnTime The selected slot device screen on time.
- * @param slotTimestamp The selected slot timestamp information.
- */
- void onScreenOnTimeUpdated(Long screenOnTime, String slotTimestamp);
- }
-
- /**
- * A callback listener for the battery tips card is updated.
- * This happens when battery tips card is ready.
- */
- public interface OnBatteryTipsUpdatedListener {
- /**
- * The callback function for the battery tips card is updated.
- * @param powerAnomalyEvent the power anomaly event with highest score
- */
- void onBatteryTipsUpdated(PowerAnomalyEvent powerAnomalyEvent);
- }
-
-
@VisibleForTesting
Context mPrefContext;
@VisibleForTesting
+ TextView mChartSummaryTextView;
+ @VisibleForTesting
BatteryChartView mDailyChartView;
@VisibleForTesting
BatteryChartView mHourlyChartView;
@@ -129,27 +86,23 @@
@VisibleForTesting
int mHourlyChartIndex = BatteryChartViewModel.SELECTED_INDEX_ALL;
@VisibleForTesting
- Map<Integer, Map<Integer, BatteryDiffData>> mBatteryUsageMap;
+ int mDailyHighlightSlotIndex = BatteryChartViewModel.SELECTED_INDEX_INVALID;
+ @VisibleForTesting
+ int mHourlyHighlightSlotIndex = BatteryChartViewModel.SELECTED_INDEX_INVALID;
private boolean mIs24HourFormat;
private View mBatteryChartViewGroup;
- private TextView mChartSummaryTextView;
private BatteryChartViewModel mDailyViewModel;
private List<BatteryChartViewModel> mHourlyViewModels;
- private OnBatteryUsageUpdatedListener mOnBatteryUsageUpdatedListener;
- private OnScreenOnTimeUpdatedListener mOnScreenOnTimeUpdatedListener;
- private OnBatteryTipsUpdatedListener mOnBatteryTipsUpdatedListener;
- private AtomicBoolean mIsAppResume = new AtomicBoolean(false);
+ private OnSelectedIndexUpdatedListener mOnSelectedIndexUpdatedListener;
private final SettingsActivity mActivity;
private final MetricsFeatureProvider mMetricsFeatureProvider;
- private final PowerUsageFeatureProvider mPowerUsageFeatureProvider;
private final Handler mHandler = new Handler(Looper.getMainLooper());
private final AnimatorListenerAdapter mHourlyChartFadeInAdapter =
createHourlyChartAnimatorListenerAdapter(/*visible=*/ true);
private final AnimatorListenerAdapter mHourlyChartFadeOutAdapter =
createHourlyChartAnimatorListenerAdapter(/*visible=*/ false);
- private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
@VisibleForTesting
final DailyChartLabelTextGenerator mDailyChartLabelTextGenerator =
@@ -165,8 +118,6 @@
mIs24HourFormat = DateFormat.is24HourFormat(context);
mMetricsFeatureProvider =
FeatureFactory.getFactory(mContext).getMetricsFeatureProvider();
- mPowerUsageFeatureProvider =
- FeatureFactory.getFactory(mContext).getPowerUsageFeatureProvider(context);
if (lifecycle != null) {
lifecycle.addObserver(this);
}
@@ -184,15 +135,9 @@
Log.d(TAG, String.format("onCreate() dailyIndex=%d hourlyIndex=%d",
mDailyChartIndex, mHourlyChartIndex));
}
- @Override
- public void onPause() {
- mIsAppResume.compareAndSet(/* expect= */ true, /* update= */ false);
- }
-
@Override
public void onResume() {
- mIsAppResume.compareAndSet(/* expect= */ false, /* update= */ true);
mIs24HourFormat = DateFormat.is24HourFormat(mContext);
mMetricsFeatureProvider.action(mPrefContext, SettingsEnums.OPEN_BATTERY_USAGE);
}
@@ -232,16 +177,16 @@
return PREFERENCE_KEY;
}
- void setOnBatteryUsageUpdatedListener(OnBatteryUsageUpdatedListener listener) {
- mOnBatteryUsageUpdatedListener = listener;
+ int getDailyChartIndex() {
+ return mDailyChartIndex;
}
- void setOnScreenOnTimeUpdatedListener(OnScreenOnTimeUpdatedListener listener) {
- mOnScreenOnTimeUpdatedListener = listener;
+ int getHourlyChartIndex() {
+ return mHourlyChartIndex;
}
- void setOnBatteryTipsUpdatedListener(OnBatteryTipsUpdatedListener listener) {
- mOnBatteryTipsUpdatedListener = listener;
+ void setOnSelectedIndexUpdatedListener(OnSelectedIndexUpdatedListener listener) {
+ mOnSelectedIndexUpdatedListener = listener;
}
void onBatteryLevelDataUpdate(final BatteryLevelData batteryLevelData) {
@@ -276,13 +221,37 @@
refreshUi();
}
- void onBatteryUsageMapUpdate(Map<Integer, Map<Integer, BatteryDiffData>> batteryUsageMap) {
- Log.d(TAG, "onBatteryUsageMapUpdate: " + batteryUsageMap);
- mBatteryUsageMap = batteryUsageMap;
- logScreenUsageTime();
+ void onHighlightSlotIndexUpdate(int dailyHighlightSlotIndex, int hourlyHighlightSlotIndex) {
+ if (mDailyHighlightSlotIndex == dailyHighlightSlotIndex
+ && mHourlyHighlightSlotIndex == hourlyHighlightSlotIndex) {
+ return;
+ }
+ mDailyHighlightSlotIndex = dailyHighlightSlotIndex;
+ mHourlyHighlightSlotIndex = hourlyHighlightSlotIndex;
refreshUi();
}
+ void selectHighlightSlotIndex() {
+ if (mDailyHighlightSlotIndex == BatteryChartViewModel.SELECTED_INDEX_INVALID
+ || mHourlyHighlightSlotIndex == BatteryChartViewModel.SELECTED_INDEX_INVALID) {
+ return;
+ }
+ if (mDailyHighlightSlotIndex == mDailyChartIndex
+ && mHourlyHighlightSlotIndex == mHourlyChartIndex) {
+ return;
+ }
+ mDailyChartIndex = mDailyHighlightSlotIndex;
+ mHourlyChartIndex = mHourlyHighlightSlotIndex;
+ Log.d(TAG, String.format("onDailyChartSelect:%d, onHourlyChartSelect:%d",
+ mDailyChartIndex, mHourlyChartIndex));
+ refreshUi();
+ mHandler.post(() -> mDailyChartView.announceForAccessibility(
+ getAccessibilityAnnounceMessage()));
+ if (mOnSelectedIndexUpdatedListener != null) {
+ mOnSelectedIndexUpdatedListener.onSelectedIndexUpdated();
+ }
+ }
+
void setBatteryChartView(@NonNull final BatteryChartView dailyChartView,
@NonNull final BatteryChartView hourlyChartView) {
final View parentView = (View) dailyChartView.getParent();
@@ -319,6 +288,9 @@
? SettingsEnums.ACTION_BATTERY_USAGE_DAILY_SHOW_ALL
: SettingsEnums.ACTION_BATTERY_USAGE_DAILY_TIME_SLOT,
mDailyChartIndex);
+ if (mOnSelectedIndexUpdatedListener != null) {
+ mOnSelectedIndexUpdatedListener.onSelectedIndexUpdated();
+ }
});
mHourlyChartView = hourlyChartView;
mHourlyChartView.setOnSelectListener(trapezoidIndex -> {
@@ -340,105 +312,37 @@
? SettingsEnums.ACTION_BATTERY_USAGE_SHOW_ALL
: SettingsEnums.ACTION_BATTERY_USAGE_TIME_SLOT,
mHourlyChartIndex);
+ if (mOnSelectedIndexUpdatedListener != null) {
+ mOnSelectedIndexUpdatedListener.onSelectedIndexUpdated();
+ }
});
refreshUi();
}
+ // Show empty hourly chart view only if there is no valid battery usage data.
+ void showEmptyChart() {
+ setChartSummaryVisible(true);
+ mDailyChartView.setVisibility(View.GONE);
+ mHourlyChartView.setVisibility(View.VISIBLE);
+ mHourlyChartView.setViewModel(null);
+ }
+
@VisibleForTesting
- boolean refreshUi() {
+ void refreshUi() {
if (mDailyChartView == null || mHourlyChartView == null) {
// Chart views are not initialized.
- return false;
+ return;
}
- // When mDailyViewModel or mHourlyViewModels is null, there is no battery level data.
- // This is mainly in 2 cases:
- // 1) battery data is within 2 hours
- // 2) no battery data in the latest 7 days (power off >= 7 days)
- final boolean refreshUiResult = mDailyViewModel == null || mHourlyViewModels == null
- ? refreshUiWithNoLevelDataCase()
- : refreshUiWithLevelDataCase();
-
- if (!refreshUiResult) {
- return false;
- }
-
- if (mOnBatteryUsageUpdatedListener != null && mBatteryUsageMap != null
- && mBatteryUsageMap.get(mDailyChartIndex) != null) {
- final BatteryDiffData slotUsageData =
- mBatteryUsageMap.get(mDailyChartIndex).get(mHourlyChartIndex);
- if (slotUsageData != null) {
- mOnScreenOnTimeUpdatedListener.onScreenOnTimeUpdated(
- slotUsageData.getScreenOnTime(),
- getSlotInformation());
- }
- mOnBatteryUsageUpdatedListener.onBatteryUsageUpdated(
- slotUsageData, getSlotInformation(), isBatteryUsageMapNullOrEmpty());
-
- Log.d(TAG, "isBatteryTipsEnabled = "
- + mPowerUsageFeatureProvider.isBatteryTipsEnabled());
- if (mOnBatteryTipsUpdatedListener != null) {
- mExecutor.execute(() -> {
- final PowerAnomalyEventList anomalyEventList = mPowerUsageFeatureProvider
- .detectSettingsAnomaly(mContext, /* displayDrain= */ 0);
- Log.d(TAG, "anomalyEventList = " + anomalyEventList);
- final PowerAnomalyEvent displayEvent =
- getHighestScoreAnomalyEvent(anomalyEventList);
- mHandler.post(() -> {
- if (mIsAppResume.get()) {
- mOnBatteryTipsUpdatedListener
- .onBatteryTipsUpdated(displayEvent);
- }
- }
- );
- });
- }
- }
- return true;
- }
-
- @VisibleForTesting
- PowerAnomalyEvent getHighestScoreAnomalyEvent(PowerAnomalyEventList anomalyEventList) {
- if (anomalyEventList == null || anomalyEventList.getPowerAnomalyEventsCount() == 0) {
- return null;
- }
- 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() {
- setChartSummaryVisible(false);
- if (mBatteryUsageMap == null) {
- // There is no battery level data and battery usage data is not ready, wait for data
- // ready to refresh UI. Show nothing temporarily.
+ if (mDailyViewModel == null || mHourlyViewModels == null) {
+ setChartSummaryVisible(false);
mDailyChartView.setVisibility(View.GONE);
mHourlyChartView.setVisibility(View.GONE);
mDailyChartView.setViewModel(null);
mHourlyChartView.setViewModel(null);
- return false;
- } else if (mBatteryUsageMap
- .get(BatteryChartViewModel.SELECTED_INDEX_ALL)
- .get(BatteryChartViewModel.SELECTED_INDEX_ALL) == null) {
- // There is no battery level data and battery usage data, show an empty hourly chart
- // view.
- mDailyChartView.setVisibility(View.GONE);
- mHourlyChartView.setVisibility(View.VISIBLE);
- mHourlyChartView.setViewModel(null);
+ return;
}
- return true;
- }
- private boolean refreshUiWithLevelDataCase() {
setChartSummaryVisible(true);
// Gets valid battery level data.
if (isBatteryLevelDataInOneDay()) {
@@ -451,6 +355,7 @@
mDailyChartIndex = BatteryChartViewModel.SELECTED_INDEX_ALL;
}
mDailyViewModel.setSelectedIndex(mDailyChartIndex);
+ mDailyViewModel.setHighlightSlotIndex(mDailyHighlightSlotIndex);
mDailyChartView.setViewModel(mDailyViewModel);
}
@@ -465,17 +370,13 @@
mHourlyChartIndex = BatteryChartViewModel.SELECTED_INDEX_ALL;
}
hourlyViewModel.setSelectedIndex(mHourlyChartIndex);
+ hourlyViewModel.setHighlightSlotIndex((mDailyChartIndex == mDailyHighlightSlotIndex)
+ ? mHourlyHighlightSlotIndex
+ : BatteryChartViewModel.SELECTED_INDEX_INVALID);
mHourlyChartView.setViewModel(hourlyViewModel);
}
-
- if (mBatteryUsageMap == null) {
- // Battery usage data is not ready, wait for data ready to refresh UI.
- return false;
- }
- return true;
}
- @VisibleForTesting
String getSlotInformation() {
if (mDailyViewModel == null || mHourlyViewModels == null) {
// No data
@@ -566,44 +467,6 @@
};
}
- private void logScreenUsageTime() {
- if (mBatteryUsageMap == null) {
- return;
- }
- final BatteryDiffData allBatteryDiffData = mBatteryUsageMap.get(
- BatteryChartViewModel.SELECTED_INDEX_ALL).get(
- BatteryChartViewModel.SELECTED_INDEX_ALL);
- if (allBatteryDiffData == null) {
- return;
- }
- mMetricsFeatureProvider.action(
- mPrefContext,
- SettingsEnums.ACTION_BATTERY_USAGE_SCREEN_ON_TIME,
- (int) allBatteryDiffData.getScreenOnTime());
- mMetricsFeatureProvider.action(
- mPrefContext,
- SettingsEnums.ACTION_BATTERY_USAGE_FOREGROUND_USAGE_TIME,
- (int) getTotalForegroundUsageTime());
- }
-
- private long getTotalForegroundUsageTime() {
- if (mBatteryUsageMap == null) {
- return 0;
- }
- final BatteryDiffData totalBatteryUsageDiffData =
- mBatteryUsageMap
- .get(BatteryChartViewModel.SELECTED_INDEX_ALL)
- .get(BatteryChartViewModel.SELECTED_INDEX_ALL);
- if (totalBatteryUsageDiffData == null) {
- return 0;
- }
- long totalValue = 0;
- for (final BatteryDiffEntry entry : totalBatteryUsageDiffData.getAppDiffEntryList()) {
- totalValue += entry.mForegroundUsageTimeInMs;
- }
- return totalValue;
- }
-
private boolean isBatteryLevelDataInOneDay() {
return mHourlyViewModels != null && mHourlyViewModels.size() == 1;
}
@@ -614,19 +477,6 @@
&& mHourlyChartIndex == BatteryChartViewModel.SELECTED_INDEX_ALL;
}
- private boolean isBatteryUsageMapNullOrEmpty() {
- if (mBatteryUsageMap == null) {
- return true;
- }
- BatteryDiffData allBatteryDiffData = mBatteryUsageMap
- .get(BatteryChartViewModel.SELECTED_INDEX_ALL)
- .get(BatteryChartViewModel.SELECTED_INDEX_ALL);
- // If all data is null or empty, each slot must be null or empty.
- return allBatteryDiffData == null
- || (allBatteryDiffData.getAppDiffEntryList().isEmpty()
- && allBatteryDiffData.getSystemDiffEntryList().isEmpty());
- }
-
@VisibleForTesting
static int getTotalHours(final BatteryLevelData batteryLevelData) {
if (batteryLevelData == null) {
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java
index 086f56c..bb468fe 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java
@@ -31,6 +31,7 @@
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.ArraySet;
import android.util.AttributeSet;
@@ -90,6 +91,15 @@
private int mTrapezoidHoverColor;
private int mDefaultTextColor;
private int mTextPadding;
+ private int mTransomIconSize;
+ private int mTransomTop;
+ private int mTransomViewHeight;
+ private int mTransomLineDefaultColor;
+ private int mTransomLineSelectedColor;
+ private float mTransomPadding;
+ private Drawable mTransomIcon;
+ private Paint mTransomLinePaint;
+ private Paint mTransomSelectedSlotPaint;
private Paint mDividerPaint;
private Paint mTrapezoidPaint;
private Paint mTextPaint;
@@ -123,8 +133,9 @@
return;
}
- Log.d(TAG, String.format("setViewModel(): size: %d, selectedIndex: %d.",
- viewModel.size(), viewModel.selectedIndex()));
+ Log.d(TAG, String.format(
+ "setViewModel(): size: %d, selectedIndex: %d, getHighlightSlotIndex: %d",
+ viewModel.size(), viewModel.selectedIndex(), viewModel.getHighlightSlotIndex()));
mViewModel = viewModel;
initializeAxisLabelsBounds();
initializeTrapezoidSlots(viewModel.size() - 1);
@@ -162,7 +173,7 @@
mPercentageBounds[index]);
}
// Updates the indent configurations.
- mIndent.top = mPercentageBounds[0].height();
+ mIndent.top = mPercentageBounds[0].height() + mTransomViewHeight;
final int textWidth = mPercentageBounds[0].width() + mTextPadding;
if (isRTL()) {
mIndent.left = textWidth;
@@ -196,6 +207,7 @@
}
drawVerticalDividers(canvas);
drawTrapezoids(canvas);
+ drawTransomLine(canvas);
}
@Override
@@ -340,6 +352,40 @@
resources.getDimensionPixelSize(R.dimen.chartview_trapezoid_radius)));
// Initializes for drawing text information.
mTextPadding = resources.getDimensionPixelSize(R.dimen.chartview_text_padding);
+ // Initializes the padding top for drawing text information.
+ mTransomViewHeight = resources.getDimensionPixelSize(
+ R.dimen.chartview_transom_layout_height);
+ }
+
+ private void initializeTransomPaint() {
+ if (mTransomLinePaint != null && mTransomSelectedSlotPaint != null
+ && mTransomIcon != null) {
+ return;
+ }
+ // Initializes the transom line paint.
+ final Resources resources = getContext().getResources();
+ final int transomLineWidth = resources.getDimensionPixelSize(
+ R.dimen.chartview_transom_width);
+ final int transomRadius = resources.getDimensionPixelSize(R.dimen.chartview_transom_radius);
+ mTransomPadding = transomRadius * .5f;
+ mTransomTop = resources.getDimensionPixelSize(R.dimen.chartview_transom_padding_top);
+ mTransomLineDefaultColor = Utils.getDisabled(mContext, DIVIDER_COLOR);
+ mTransomLineSelectedColor = resources.getColor(
+ R.color.color_battery_anomaly_yellow_selector);
+ final int slotHighlightColor = Utils.getDisabled(mContext, mTransomLineSelectedColor);
+ mTransomIconSize = resources.getDimensionPixelSize(R.dimen.chartview_transom_icon_size);
+ mTransomLinePaint = new Paint();
+ mTransomLinePaint.setAntiAlias(true);
+ mTransomLinePaint.setStyle(Paint.Style.STROKE);
+ mTransomLinePaint.setStrokeWidth(transomLineWidth);
+ mTransomLinePaint.setStrokeCap(Paint.Cap.ROUND);
+ mTransomLinePaint.setPathEffect(new CornerPathEffect(transomRadius));
+ mTransomSelectedSlotPaint = new Paint();
+ mTransomSelectedSlotPaint.setAntiAlias(true);
+ mTransomSelectedSlotPaint.setColor(slotHighlightColor);
+ mTransomSelectedSlotPaint.setStyle(Paint.Style.FILL);
+ // Get the companion icon beside transom line
+ mTransomIcon = getResources().getDrawable(R.drawable.ic_battery_tips_warning_icon);
}
private void drawHorizontalDividers(Canvas canvas) {
@@ -592,6 +638,50 @@
}
}
+ private boolean isHighlightSlotValid() {
+ return mViewModel != null && mViewModel.getHighlightSlotIndex()
+ != BatteryChartViewModel.SELECTED_INDEX_INVALID;
+ }
+
+ private void drawTransomLine(Canvas canvas) {
+ if (!isHighlightSlotValid()) {
+ return;
+ }
+ initializeTransomPaint();
+ // Draw the whole transom line and a warning icon
+ mTransomLinePaint.setColor(mTransomLineDefaultColor);
+ final int width = getWidth() - abs(mIndent.width());
+ final float transomOffset = mTrapezoidHOffset + mDividerWidth * .5f + mTransomPadding;
+ final float trapezoidBottom = getHeight() - mIndent.bottom - mDividerHeight - mDividerWidth
+ - mTrapezoidVOffset;
+ canvas.drawLine(mIndent.left + transomOffset, mTransomTop,
+ mIndent.left + width - transomOffset, mTransomTop,
+ mTransomLinePaint);
+ drawTransomIcon(canvas);
+ // Draw selected segment of transom line and a highlight slot
+ mTransomLinePaint.setColor(mTransomLineSelectedColor);
+ final int index = mViewModel.getHighlightSlotIndex();
+ final float startX = mTrapezoidSlots[index].mLeft;
+ final float endX = mTrapezoidSlots[index].mRight;
+ canvas.drawLine(startX + mTransomPadding, mTransomTop,
+ endX - mTransomPadding, mTransomTop,
+ mTransomLinePaint);
+ canvas.drawRect(startX, mTransomTop, endX, trapezoidBottom,
+ mTransomSelectedSlotPaint);
+ }
+
+ private void drawTransomIcon(Canvas canvas) {
+ if (mTransomIcon == null) {
+ return;
+ }
+ final int left = isRTL()
+ ? mIndent.left - mTextPadding - mTransomIconSize
+ : getWidth() - abs(mIndent.width()) + mTextPadding;
+ mTransomIcon.setBounds(left, mTransomTop - mTransomIconSize / 2,
+ left + mTransomIconSize, mTransomTop + mTransomIconSize / 2);
+ mTransomIcon.draw(canvas);
+ }
+
// Searches the corresponding trapezoid index from x location.
private int getTrapezoidIndex(float x) {
if (mTrapezoidSlots == null) {
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartViewModel.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartViewModel.java
index f58d241..bf8a771 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartViewModel.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartViewModel.java
@@ -55,6 +55,7 @@
private final String[] mFullTexts;
private int mSelectedIndex = SELECTED_INDEX_ALL;
+ private int mHighlightSlotIndex = SELECTED_INDEX_INVALID;
BatteryChartViewModel(@NonNull List<Integer> levels, @NonNull List<Long> timestamps,
@NonNull AxisLabelPosition axisLabelPosition,
@@ -106,6 +107,14 @@
mSelectedIndex = index;
}
+ public int getHighlightSlotIndex() {
+ return mHighlightSlotIndex;
+ }
+
+ public void setHighlightSlotIndex(int index) {
+ mHighlightSlotIndex = index;
+ }
+
@Override
public int hashCode() {
return Objects.hash(mLevels, mTimestamps, mSelectedIndex, mAxisLabelPosition);
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryLevelData.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryLevelData.java
index 53ebbd9..09d66c7 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryLevelData.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryLevelData.java
@@ -20,6 +20,7 @@
import android.text.format.DateUtils;
import android.util.ArrayMap;
+import android.util.Pair;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -69,6 +70,16 @@
return String.format(Locale.ENGLISH, "timestamps: %s; levels: %s",
Objects.toString(mTimestamps), Objects.toString(mLevels));
}
+
+ private int getIndexByTimestamps(long startTimestamp, long endTimestamp) {
+ for (int index = 0; index < mTimestamps.size() - 1; index++) {
+ if (mTimestamps.get(index) <= startTimestamp
+ && endTimestamp <= mTimestamps.get(index + 1)) {
+ return index;
+ }
+ }
+ return BatteryChartViewModel.SELECTED_INDEX_INVALID;
+ }
}
/**
@@ -100,6 +111,18 @@
}
}
+ /** Gets daily and hourly index between start and end timestamps. */
+ public Pair<Integer, Integer> getIndexByTimestamps(long startTimestamp, long endTimestamp) {
+ final int dailyHighlightIndex =
+ mDailyBatteryLevels.getIndexByTimestamps(startTimestamp, endTimestamp);
+ final int hourlyHighlightIndex =
+ (dailyHighlightIndex == BatteryChartViewModel.SELECTED_INDEX_INVALID)
+ ? BatteryChartViewModel.SELECTED_INDEX_INVALID
+ : mHourlyBatteryLevelsPerDay.get(dailyHighlightIndex)
+ .getIndexByTimestamps(startTimestamp, endTimestamp);
+ return Pair.create(dailyHighlightIndex, hourlyHighlightIndex);
+ }
+
public PeriodBatteryLevelData getDailyBatteryLevels() {
return mDailyBatteryLevels;
}
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java
index ea5534d..e98077c 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java
@@ -16,13 +16,10 @@
package com.android.settings.fuelgauge.batteryusage;
-import android.app.settings.SettingsEnums;
import android.content.Context;
-import android.os.Bundle;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
-import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -32,9 +29,6 @@
import androidx.preference.PreferenceViewHolder;
import com.android.settings.R;
-import com.android.settings.SettingsActivity;
-import com.android.settings.core.SubSettingLauncher;
-import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -47,11 +41,17 @@
private static final String TAG = "BatteryTipsCardPreference";
- private final PowerUsageFeatureProvider mPowerUsageFeatureProvider;
- private final MetricsFeatureProvider mMetricsFeatureProvider;
+ interface OnConfirmListener {
+ void onConfirm();
+ }
- private String mAnomalyEventId;
- private PowerAnomalyKey mPowerAnomalyKey;
+ interface OnRejectListener {
+ void onReject();
+ }
+
+ private final MetricsFeatureProvider mMetricsFeatureProvider;
+ private OnConfirmListener mOnConfirmListener;
+ private OnRejectListener mOnRejectListener;
private int mIconResourceId = 0;
private int mMainButtonStrokeColorResourceId = 0;
@@ -59,21 +59,21 @@
CharSequence mMainButtonLabel;
@VisibleForTesting
CharSequence mDismissButtonLabel;
- @VisibleForTesting
- String mDestinationComponentName;
- @VisibleForTesting
- String mPreferenceHighlightKey;
- @VisibleForTesting
- Integer mSourceMetricsCategory;
public BatteryTipsCardPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setLayoutResource(R.layout.battery_tips_card);
setSelectable(false);
final FeatureFactory featureFactory = FeatureFactory.getFactory(context);
- mPowerUsageFeatureProvider = featureFactory.getPowerUsageFeatureProvider(context);
mMetricsFeatureProvider = featureFactory.getMetricsFeatureProvider();
- mPowerAnomalyKey = null;
+ }
+
+ public void setOnConfirmListener(OnConfirmListener listener) {
+ mOnConfirmListener = listener;
+ }
+
+ public void setOnRejectListener(OnRejectListener listener) {
+ mOnRejectListener = listener;
}
/**
@@ -97,13 +97,6 @@
}
/**
- * Sets the anomaly event id which is used in metrics.
- */
- public void setAnomalyEventId(final String anomalyEventId) {
- mAnomalyEventId = anomalyEventId;
- }
-
- /**
* Sets the label of main button in tips card.
*/
public void setMainButtonLabel(CharSequence label) {
@@ -123,50 +116,18 @@
}
}
- /**
- * 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.
- */
- public void setMainButtonLauncherInfo(final String destinationClassName,
- final Integer sourceMetricsCategory, final String highlightKey) {
- mDestinationComponentName = destinationClassName;
- mSourceMetricsCategory = sourceMetricsCategory;
- mPreferenceHighlightKey = highlightKey;
- }
-
@Override
public void onClick(View view) {
final int viewId = view.getId();
if (viewId == R.id.main_button || viewId == R.id.tips_card) {
- if (TextUtils.isEmpty(mDestinationComponentName)) {
- return;
- }
- Bundle arguments = Bundle.EMPTY;
- if (!TextUtils.isEmpty(mPreferenceHighlightKey)) {
- arguments = new Bundle(1);
- arguments.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY,
- mPreferenceHighlightKey);
- }
- new SubSettingLauncher(getContext())
- .setDestination(mDestinationComponentName)
- .setSourceMetricsCategory(mSourceMetricsCategory)
- .setArguments(arguments)
- .launch();
setVisible(false);
- mMetricsFeatureProvider.action(
- getContext(), SettingsEnums.ACTION_BATTERY_TIPS_CARD_ACCEPT, mAnomalyEventId);
+ if (mOnConfirmListener != null) {
+ mOnConfirmListener.onConfirm();
+ }
} else if (viewId == R.id.dismiss_button) {
setVisible(false);
- mMetricsFeatureProvider.action(
- getContext(), SettingsEnums.ACTION_BATTERY_TIPS_CARD_DISMISS, mAnomalyEventId);
- if (mPowerAnomalyKey != null) {
- DatabaseUtils.setDismissedPowerAnomalyKeys(getContext(), mPowerAnomalyKey.name());
+ if (mOnRejectListener != null) {
+ mOnRejectListener.onReject();
}
}
}
@@ -191,17 +152,5 @@
if (mIconResourceId != 0) {
((ImageView) view.findViewById(R.id.icon)).setImageResource(mIconResourceId);
}
-
- if (!mPowerUsageFeatureProvider.isBatteryTipsFeedbackEnabled()) {
- return;
- }
- view.findViewById(R.id.tips_card)
- .setBackgroundResource(R.drawable.battery_tips_half_rounded_top_bg);
- view.findViewById(R.id.feedback_card).setVisibility(View.VISIBLE);
-
- ImageButton thumbUpButton = (ImageButton) view.findViewById(R.id.thumb_up);
- thumbUpButton.setOnClickListener(this);
- ImageButton thumbDownButton = (ImageButton) view.findViewById(R.id.thumb_down);
- thumbDownButton.setOnClickListener(this);
}
}
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java
index 80b2695..400e70a 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java
@@ -18,14 +18,16 @@
import android.app.settings.SettingsEnums;
import android.content.Context;
+import android.os.Bundle;
import android.text.TextUtils;
import androidx.preference.PreferenceScreen;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
+import com.android.settings.SettingsActivity;
import com.android.settings.core.BasePreferenceController;
-import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
+import com.android.settings.core.SubSettingLauncher;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -38,23 +40,32 @@
private static final String ROOT_PREFERENCE_KEY = "battery_tips_category";
private static final String CARD_PREFERENCE_KEY = "battery_tips_card";
- private final PowerUsageFeatureProvider mPowerUsageFeatureProvider;
private final MetricsFeatureProvider mMetricsFeatureProvider;
+ /** A callback listener for the battery tips is confirmed. */
+ interface OnAnomalyConfirmListener {
+ /** The callback function for the battery tips is confirmed. */
+ void onAnomalyConfirm();
+ }
+
+ /** A callback listener for the battery tips is rejected. */
+ interface OnAnomalyRejectListener {
+ /** The callback function for the battery tips is rejected. */
+ void onAnomalyReject();
+ }
+
+ private OnAnomalyConfirmListener mOnAnomalyConfirmListener;
+ private OnAnomalyRejectListener mOnAnomalyRejectListener;
+
@VisibleForTesting
BatteryTipsCardPreference mCardPreference;
public BatteryTipsController(Context context) {
super(context, ROOT_PREFERENCE_KEY);
final FeatureFactory featureFactory = FeatureFactory.getFactory(context);
- mPowerUsageFeatureProvider = featureFactory.getPowerUsageFeatureProvider(context);
mMetricsFeatureProvider = featureFactory.getMetricsFeatureProvider();
}
- private boolean isTipsCardVisible() {
- return mPowerUsageFeatureProvider.isBatteryTipsEnabled();
- }
-
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
@@ -66,6 +77,14 @@
mCardPreference = screen.findPreference(CARD_PREFERENCE_KEY);
}
+ void setOnAnomalyConfirmListener(OnAnomalyConfirmListener listener) {
+ mOnAnomalyConfirmListener = listener;
+ }
+
+ void setOnAnomalyRejectListener(OnAnomalyRejectListener listener) {
+ mOnAnomalyRejectListener = listener;
+ }
+
private <T> T getInfo(PowerAnomalyEvent powerAnomalyEvent,
Function<WarningBannerInfo, T> warningBannerInfoSupplier,
Function<WarningItemInfo, T> warningItemInfoSupplier) {
@@ -102,12 +121,22 @@
: getStringFromResource(resourceId, resourceIndex);
}
- @VisibleForTesting
- void handleBatteryTipsCardUpdated(PowerAnomalyEvent powerAnomalyEvent) {
- if (!isTipsCardVisible()) {
- mCardPreference.setVisible(false);
- return;
+ /** Generate a key string of current anomaly to record as dismissed in sharedPreferences. */
+ public static String getDismissRecordKey(PowerAnomalyEvent event) {
+ if (!event.hasKey()) {
+ return null;
}
+ switch (event.getKey()){
+ case KEY_APP:
+ return event.hasWarningItemInfo()
+ && event.getWarningItemInfo().hasDismissRecordKey()
+ ? event.getWarningItemInfo().getDismissRecordKey() : null;
+ default:
+ return event.getKey().name();
+ }
+ }
+
+ void handleBatteryTipsCardUpdated(PowerAnomalyEvent powerAnomalyEvent) {
if (powerAnomalyEvent == null) {
mCardPreference.setVisible(false);
return;
@@ -121,44 +150,76 @@
R.array.battery_tips_card_colors, cardStyleId, "color");
// Get card preference strings and navigate fragment info
+ final String eventId = powerAnomalyEvent.hasEventId()
+ ? powerAnomalyEvent.getEventId() : null;
final PowerAnomalyKey powerAnomalyKey = powerAnomalyEvent.hasKey()
? powerAnomalyEvent.getKey() : null;
final int resourceIndex = powerAnomalyKey != null ? powerAnomalyKey.getNumber() : -1;
- String titleString = getString(powerAnomalyEvent, WarningBannerInfo::getTitleString,
+ final String titleString = getString(powerAnomalyEvent, WarningBannerInfo::getTitleString,
WarningItemInfo::getTitleString, R.array.power_anomaly_titles, resourceIndex);
if (titleString.isEmpty()) {
mCardPreference.setVisible(false);
return;
}
- String mainBtnString = getString(powerAnomalyEvent,
+ final String mainBtnString = getString(powerAnomalyEvent,
WarningBannerInfo::getMainButtonString, WarningItemInfo::getMainButtonString,
R.array.power_anomaly_main_btn_strings, resourceIndex);
- String dismissBtnString = getString(powerAnomalyEvent,
+ final String dismissBtnString = getString(powerAnomalyEvent,
WarningBannerInfo::getCancelButtonString, WarningItemInfo::getCancelButtonString,
R.array.power_anomaly_dismiss_btn_strings, resourceIndex);
- String destinationClassName = getInfo(powerAnomalyEvent,
+ final String destinationClassName = getInfo(powerAnomalyEvent,
WarningBannerInfo::getMainButtonDestination, null);
- Integer sourceMetricsCategory = getInfo(powerAnomalyEvent,
+ final Integer sourceMetricsCategory = getInfo(powerAnomalyEvent,
WarningBannerInfo::getMainButtonSourceMetricsCategory, null);
- String preferenceHighlightKey = getInfo(powerAnomalyEvent,
+ final String preferenceHighlightKey = getInfo(powerAnomalyEvent,
WarningBannerInfo::getMainButtonSourceHighlightKey, null);
// Update card preference and main button fragment launcher
- mCardPreference.setAnomalyEventId(powerAnomalyEvent.getEventId());
- mCardPreference.setPowerAnomalyKey(powerAnomalyKey);
mCardPreference.setTitle(titleString);
mCardPreference.setIconResourceId(iconResId);
mCardPreference.setMainButtonStrokeColorResourceId(colorResId);
mCardPreference.setMainButtonLabel(mainBtnString);
mCardPreference.setDismissButtonLabel(dismissBtnString);
- mCardPreference.setMainButtonLauncherInfo(
- destinationClassName, sourceMetricsCategory, preferenceHighlightKey);
- mCardPreference.setVisible(true);
- mMetricsFeatureProvider.action(mContext,
- SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, powerAnomalyEvent.getEventId());
+ // Set battery tips card listener
+ mCardPreference.setOnConfirmListener(() -> {
+ if (mOnAnomalyConfirmListener != null) {
+ mOnAnomalyConfirmListener.onAnomalyConfirm();
+ } else if (!TextUtils.isEmpty(destinationClassName)) {
+ // Navigate to sub setting page
+ Bundle arguments = Bundle.EMPTY;
+ if (!TextUtils.isEmpty(preferenceHighlightKey)) {
+ arguments = new Bundle(1);
+ arguments.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY,
+ preferenceHighlightKey);
+ }
+ new SubSettingLauncher(mContext)
+ .setDestination(destinationClassName)
+ .setSourceMetricsCategory(sourceMetricsCategory)
+ .setArguments(arguments)
+ .launch();
+ }
+ mMetricsFeatureProvider.action(
+ mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_ACCEPT, eventId);
+ });
+ mCardPreference.setOnRejectListener(() -> {
+ if (mOnAnomalyRejectListener != null) {
+ mOnAnomalyRejectListener.onAnomalyReject();
+ }
+ // For anomaly events with same record key, dismissed until next time full charged.
+ final String dismissRecordKey = getDismissRecordKey(powerAnomalyEvent);
+ if (!TextUtils.isEmpty(dismissRecordKey)) {
+ DatabaseUtils.setDismissedPowerAnomalyKeys(mContext, dismissRecordKey);
+ }
+ mMetricsFeatureProvider.action(
+ mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_DISMISS, eventId);
+ });
+
+ mCardPreference.setVisible(true);
+ mMetricsFeatureProvider.action(
+ mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, eventId);
}
}
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBroadcastReceiver.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBroadcastReceiver.java
index ed5f182..952b83f 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBroadcastReceiver.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBroadcastReceiver.java
@@ -120,6 +120,7 @@
mFetchBatteryUsageData = true;
BatteryUsageDataLoader.enqueueWork(context, /*isFullChargeStart=*/ true);
+ BootBroadcastReceiver.invokeJobRecheck(context);
}
private void sendBatteryEventData(Context context, BatteryEventType batteryEventType) {
diff --git a/src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java b/src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java
index ec0d01a..a1987c9 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java
@@ -473,6 +473,9 @@
.setConsumePower(batteryDiffEntry.mConsumePower)
.setForegroundUsageConsumePower(batteryDiffEntry.mForegroundUsageConsumePower)
.setBackgroundUsageConsumePower(batteryDiffEntry.mBackgroundUsageConsumePower)
+ .setForegroundServiceUsageConsumePower(
+ batteryDiffEntry.mForegroundServiceUsageConsumePower)
+ .setCachedUsageConsumePower(batteryDiffEntry.mCachedUsageConsumePower)
.setForegroundUsageTime(batteryDiffEntry.mForegroundUsageTimeInMs)
.setBackgroundUsageTime(batteryDiffEntry.mBackgroundUsageTimeInMs)
.setScreenOnTime(batteryDiffEntry.mScreenOnTimeInMs);
@@ -525,9 +528,9 @@
batteryUsageDiff.getScreenOnTime(),
batteryUsageDiff.getConsumePower(),
batteryUsageDiff.getForegroundUsageConsumePower(),
- /*foregroundServiceUsageConsumePower=*/ 0,
+ batteryUsageDiff.getForegroundServiceUsageConsumePower(),
batteryUsageDiff.getBackgroundUsageConsumePower(),
- /*cachedUsageConsumePower=*/ 0);
+ batteryUsageDiff.getCachedUsageConsumePower());
}
static BatteryDiffData convertToBatteryDiffData(
diff --git a/src/com/android/settings/fuelgauge/batteryusage/PeriodicJobManager.java b/src/com/android/settings/fuelgauge/batteryusage/PeriodicJobManager.java
index 8c0e66c..43cd69d 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/PeriodicJobManager.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/PeriodicJobManager.java
@@ -68,6 +68,8 @@
/** Schedules the next alarm job if it is available. */
public void refreshJob(final boolean fromBoot) {
if (mAlarmManager == null) {
+ BatteryUsageLogUtils.writeLog(mContext, Action.SCHEDULE_JOB,
+ "cannot schedule next alarm job due to AlarmManager is null");
Log.e(TAG, "cannot schedule next alarm job");
return;
}
@@ -80,8 +82,8 @@
AlarmManager.RTC_WAKEUP, triggerAtMillis, pendingIntent);
final String utcToLocalTime = ConvertUtils.utcToLocalTimeForLogging(triggerAtMillis);
- BatteryUsageLogUtils.writeLog(
- mContext, Action.SCHEDULE_JOB, "triggerTime=" + utcToLocalTime);
+ BatteryUsageLogUtils.writeLog(mContext, Action.SCHEDULE_JOB,
+ String.format("triggerTime=%s, fromBoot=%b", utcToLocalTime, fromBoot));
Log.d(TAG, "schedule next alarm job at " + utcToLocalTime);
}
diff --git a/src/com/android/settings/fuelgauge/batteryusage/PeriodicJobReceiver.java b/src/com/android/settings/fuelgauge/batteryusage/PeriodicJobReceiver.java
index 2371a19..dccca43 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/PeriodicJobReceiver.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/PeriodicJobReceiver.java
@@ -33,12 +33,23 @@
@Override
public void onReceive(Context context, Intent intent) {
+ try {
+ loadDataAndRefreshJob(context, intent);
+ } catch (Exception e) {
+ BatteryUsageLogUtils.writeLog(context, Action.SCHEDULE_JOB,
+ String.format("loadDataAndRefreshJob() failed: %s", e));
+ }
+ }
+
+ private static void loadDataAndRefreshJob(Context context, Intent intent) {
final String action = intent == null ? "" : intent.getAction();
if (!ACTION_PERIODIC_JOB_UPDATE.equals(action)) {
Log.w(TAG, "receive unexpected action=" + action);
return;
}
if (DatabaseUtils.isWorkProfile(context)) {
+ BatteryUsageLogUtils.writeLog(context, Action.SCHEDULE_JOB,
+ "do not refresh job for work profile");
Log.w(TAG, "do not refresh job for work profile action=" + action);
return;
}
diff --git a/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvanced.java b/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvanced.java
index e4f8b39..4e8e396 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvanced.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvanced.java
@@ -27,6 +27,7 @@
import android.os.Looper;
import android.provider.SearchIndexableResource;
import android.util.Log;
+import android.util.Pair;
import androidx.annotation.VisibleForTesting;
import androidx.loader.app.LoaderManager;
@@ -44,9 +45,13 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
/** Advanced power usage. */
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
@@ -63,9 +68,9 @@
private boolean mIsChartDataLoaded = false;
private long mResumeTimestamp;
- private BatteryChartPreferenceController mBatteryChartPreferenceController;
- private Optional<BatteryLevelData> mBatteryLevelData;
+ private Map<Integer, Map<Integer, BatteryDiffData>> mBatteryUsageMap;
+ private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
private final Handler mHandler = new Handler(Looper.getMainLooper());
private final ContentObserver mBatteryObserver =
new ContentObserver(mHandler) {
@@ -78,6 +83,19 @@
}
};
+ @VisibleForTesting
+ BatteryTipsController mBatteryTipsController;
+ @VisibleForTesting
+ BatteryChartPreferenceController mBatteryChartPreferenceController;
+ @VisibleForTesting
+ ScreenOnTimeController mScreenOnTimeController;
+ @VisibleForTesting
+ BatteryUsageBreakdownController mBatteryUsageBreakdownController;
+ @VisibleForTesting
+ PowerAnomalyEvent mPowerAnomalyEvent;
+ @VisibleForTesting
+ Optional<BatteryLevelData> mBatteryLevelData;
+
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
@@ -92,6 +110,7 @@
if (getActivity().isChangingConfigurations()) {
BatteryEntry.clearUidCache();
}
+ mExecutor.shutdown();
}
@Override
@@ -114,7 +133,6 @@
super.onPause();
// Resets the flag to reload usage data in onResume() callback.
mIsChartDataLoaded = false;
- mBatteryLevelData = null;
final Uri uri = DatabaseUtils.BATTERY_CONTENT_URI;
if (uri != null) {
getContext().getContentResolver().unregisterContentObserver(mBatteryObserver);
@@ -135,33 +153,25 @@
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
+ mBatteryTipsController = new BatteryTipsController(context);
mBatteryChartPreferenceController =
new BatteryChartPreferenceController(
context, getSettingsLifecycle(), (SettingsActivity) getActivity());
- ScreenOnTimeController screenOnTimeController = new ScreenOnTimeController(context);
- BatteryUsageBreakdownController batteryUsageBreakdownController =
+ mScreenOnTimeController = new ScreenOnTimeController(context);
+ mBatteryUsageBreakdownController =
new BatteryUsageBreakdownController(
context, getSettingsLifecycle(), (SettingsActivity) getActivity(), this);
- mBatteryChartPreferenceController.setOnScreenOnTimeUpdatedListener(
- screenOnTimeController::handleSceenOnTimeUpdated);
- mBatteryChartPreferenceController.setOnBatteryUsageUpdatedListener(
- batteryUsageBreakdownController::handleBatteryUsageUpdated);
-
+ controllers.add(mBatteryTipsController);
controllers.add(mBatteryChartPreferenceController);
- controllers.add(screenOnTimeController);
- controllers.add(batteryUsageBreakdownController);
+ controllers.add(mScreenOnTimeController);
+ controllers.add(mBatteryUsageBreakdownController);
setBatteryChartPreferenceController();
+ mBatteryChartPreferenceController.setOnSelectedIndexUpdatedListener(
+ this::onSelectedSlotDataUpdated);
- final PowerUsageFeatureProvider powerUsageFeatureProvider =
- FeatureFactory.getFactory(context).getPowerUsageFeatureProvider(context);
- if (powerUsageFeatureProvider.isBatteryTipsEnabled()) {
- BatteryTipsController batteryTipsController = new BatteryTipsController(context);
- mBatteryChartPreferenceController.setOnBatteryTipsUpdatedListener(
- batteryTipsController::handleBatteryTipsCardUpdated);
- controllers.add(batteryTipsController);
- }
-
+ // Force UI refresh if battery usage data was loaded before UI initialization.
+ onSelectedSlotDataUpdated();
return controllers;
}
@@ -176,12 +186,18 @@
bundle.putInt(KEY_REFRESH_TYPE, refreshType);
if (!mIsChartDataLoaded) {
mIsChartDataLoaded = true;
+ mBatteryLevelData = null;
+ mBatteryUsageMap = null;
+ mPowerAnomalyEvent = null;
restartLoader(LoaderIndex.BATTERY_LEVEL_DATA_LOADER, bundle,
mBatteryLevelDataLoaderCallbacks);
}
}
private void onBatteryLevelDataUpdate(BatteryLevelData batteryLevelData) {
+ if (!isResumed()) {
+ return;
+ }
mBatteryLevelData = Optional.ofNullable(batteryLevelData);
if (mBatteryChartPreferenceController != null) {
mBatteryChartPreferenceController.onBatteryLevelDataUpdate(batteryLevelData);
@@ -191,23 +207,164 @@
}
private void onBatteryDiffDataMapUpdate(Map<Long, BatteryDiffData> batteryDiffDataMap) {
- if (mBatteryLevelData != null && mBatteryChartPreferenceController != null) {
- Map<Integer, Map<Integer, BatteryDiffData>> batteryUsageMap =
- DataProcessor.generateBatteryUsageMap(
- getContext(), batteryDiffDataMap, mBatteryLevelData.orElse(null));
- DataProcessor.loadLabelAndIcon(batteryUsageMap);
- mBatteryChartPreferenceController.onBatteryUsageMapUpdate(batteryUsageMap);
+ if (!isResumed() || mBatteryLevelData == null) {
+ return;
}
+ mBatteryUsageMap = DataProcessor.generateBatteryUsageMap(
+ getContext(), batteryDiffDataMap, mBatteryLevelData.orElse(null));
+ Log.d(TAG, "onBatteryDiffDataMapUpdate: " + mBatteryUsageMap);
+ DataProcessor.loadLabelAndIcon(mBatteryUsageMap);
+ onSelectedSlotDataUpdated();
+ detectAnomaly();
+ logScreenUsageTime();
+ if (mBatteryChartPreferenceController != null
+ && mBatteryLevelData.isEmpty() && isBatteryUsageMapNullOrEmpty()) {
+ // No available battery usage and battery level data.
+ mBatteryChartPreferenceController.showEmptyChart();
+ }
+ }
+
+ private void onSelectedSlotDataUpdated() {
+ if (mBatteryChartPreferenceController == null
+ || mScreenOnTimeController == null
+ || mBatteryUsageBreakdownController == null
+ || mBatteryUsageMap == null) {
+ return;
+ }
+ final int dailyIndex = mBatteryChartPreferenceController.getDailyChartIndex();
+ final int hourlyIndex = mBatteryChartPreferenceController.getHourlyChartIndex();
+ final String slotInformation = mBatteryChartPreferenceController.getSlotInformation();
+ final BatteryDiffData slotUsageData = mBatteryUsageMap.get(dailyIndex).get(hourlyIndex);
+ if (slotUsageData != null) {
+ mScreenOnTimeController.handleSceenOnTimeUpdated(
+ slotUsageData.getScreenOnTime(), slotInformation);
+ }
+ mBatteryUsageBreakdownController.handleBatteryUsageUpdated(
+ slotUsageData, slotInformation, isBatteryUsageMapNullOrEmpty());
Log.d(TAG, String.format("Battery usage list shows in %d millis",
System.currentTimeMillis() - mResumeTimestamp));
}
+ private void detectAnomaly() {
+ mExecutor.execute(() -> {
+ final PowerUsageFeatureProvider powerUsageFeatureProvider =
+ FeatureFactory.getFactory(getContext())
+ .getPowerUsageFeatureProvider(getContext());
+ final PowerAnomalyEventList anomalyEventList =
+ powerUsageFeatureProvider.detectSettingsAnomaly(
+ getContext(), /* displayDrain= */ 0);
+ mHandler.post(() -> onAnomalyDetected(anomalyEventList));
+ });
+ }
+
+ private void onAnomalyDetected(PowerAnomalyEventList anomalyEventList) {
+ if (!isResumed() || anomalyEventList == null) {
+ return;
+ }
+ Log.d(TAG, "anomalyEventList = " + anomalyEventList);
+ final PowerAnomalyEvent displayEvent =
+ getHighestScoreAnomalyEvent(getContext(), anomalyEventList);
+ onDisplayAnomalyEventUpdated(displayEvent);
+ }
+
+ @VisibleForTesting
+ void onDisplayAnomalyEventUpdated(PowerAnomalyEvent event) {
+ mPowerAnomalyEvent = event;
+ if (mBatteryTipsController == null
+ || mBatteryChartPreferenceController == null
+ || mBatteryUsageBreakdownController == null) {
+ return;
+ }
+
+ // Update battery tips card preference & behaviour
+ mBatteryTipsController.setOnAnomalyConfirmListener(null);
+ mBatteryTipsController.setOnAnomalyRejectListener(null);
+ mBatteryTipsController.handleBatteryTipsCardUpdated(mPowerAnomalyEvent);
+
+ // Update highlight slot effect in battery chart view
+ Pair<Integer, Integer> highlightSlotIndexPair = Pair.create(
+ BatteryChartViewModel.SELECTED_INDEX_INVALID,
+ BatteryChartViewModel.SELECTED_INDEX_INVALID);
+ if (mPowerAnomalyEvent != null && mPowerAnomalyEvent.hasWarningItemInfo()) {
+ final WarningItemInfo warningItemInfo = mPowerAnomalyEvent.getWarningItemInfo();
+ final Long startTimestamp = warningItemInfo.hasStartTimestamp()
+ ? warningItemInfo.getStartTimestamp() : null;
+ final Long endTimestamp = warningItemInfo.hasEndTimestamp()
+ ? warningItemInfo.getEndTimestamp() : null;
+ if (startTimestamp != null && endTimestamp != null) {
+ highlightSlotIndexPair = mBatteryLevelData.map(levelData ->
+ levelData.getIndexByTimestamps(startTimestamp, endTimestamp))
+ .orElse(highlightSlotIndexPair);
+ mBatteryTipsController.setOnAnomalyConfirmListener(
+ mBatteryChartPreferenceController::selectHighlightSlotIndex);
+ mBatteryTipsController.setOnAnomalyRejectListener(
+ () -> onDisplayAnomalyEventUpdated(null));
+ }
+ }
+ mBatteryChartPreferenceController.onHighlightSlotIndexUpdate(
+ highlightSlotIndexPair.first, highlightSlotIndexPair.second);
+ }
+
private void setBatteryChartPreferenceController() {
if (mHistPref != null && mBatteryChartPreferenceController != null) {
mHistPref.setChartPreferenceController(mBatteryChartPreferenceController);
}
}
+ private boolean isBatteryUsageMapNullOrEmpty() {
+ final BatteryDiffData allBatteryDiffData = getAllBatteryDiffData(mBatteryUsageMap);
+ // If all data is null or empty, each slot must be null or empty.
+ return allBatteryDiffData == null
+ || (allBatteryDiffData.getAppDiffEntryList().isEmpty()
+ && allBatteryDiffData.getSystemDiffEntryList().isEmpty());
+ }
+
+ private void logScreenUsageTime() {
+ final BatteryDiffData allBatteryDiffData = getAllBatteryDiffData(mBatteryUsageMap);
+ if (allBatteryDiffData == null) {
+ return;
+ }
+ long totalForegroundUsageTime = 0;
+ for (final BatteryDiffEntry entry : allBatteryDiffData.getAppDiffEntryList()) {
+ totalForegroundUsageTime += entry.mForegroundUsageTimeInMs;
+ }
+ mMetricsFeatureProvider.action(
+ getContext(),
+ SettingsEnums.ACTION_BATTERY_USAGE_SCREEN_ON_TIME,
+ (int) allBatteryDiffData.getScreenOnTime());
+ mMetricsFeatureProvider.action(
+ getContext(),
+ SettingsEnums.ACTION_BATTERY_USAGE_FOREGROUND_USAGE_TIME,
+ (int) totalForegroundUsageTime);
+ }
+
+ @VisibleForTesting
+ static PowerAnomalyEvent getHighestScoreAnomalyEvent(
+ Context context, PowerAnomalyEventList anomalyEventList) {
+ if (anomalyEventList == null || anomalyEventList.getPowerAnomalyEventsCount() == 0) {
+ return null;
+ }
+ final Set<String> dismissedPowerAnomalyKeys =
+ DatabaseUtils.getDismissedPowerAnomalyKeys(context);
+ Log.d(TAG, "dismissedPowerAnomalyKeys = " + dismissedPowerAnomalyKeys);
+
+ final PowerAnomalyEvent highestScoreEvent = anomalyEventList.getPowerAnomalyEventsList()
+ .stream()
+ .filter(event -> !dismissedPowerAnomalyKeys.contains(
+ BatteryTipsController.getDismissRecordKey(event)))
+ .max(Comparator.comparing(PowerAnomalyEvent::getScore))
+ .orElse(null);
+ Log.d(TAG, "highestScoreAnomalyEvent = " + highestScoreEvent);
+ return highestScoreEvent;
+ }
+
+ private static BatteryDiffData getAllBatteryDiffData(
+ Map<Integer, Map<Integer, BatteryDiffData>> batteryUsageMap) {
+ return batteryUsageMap == null ? null : batteryUsageMap
+ .get(BatteryChartViewModel.SELECTED_INDEX_ALL)
+ .get(BatteryChartViewModel.SELECTED_INDEX_ALL);
+ }
+
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
@@ -228,6 +385,7 @@
controllers.add(new BatteryUsageBreakdownController(
context, null /* lifecycle */, null /* activity */,
null /* fragment */));
+ controllers.add(new BatteryTipsController(context));
return controllers;
}
};
@@ -244,7 +402,7 @@
public BatteryLevelData loadInBackground() {
return DataProcessManager.getBatteryLevelData(
getContext(), mHandler, /*isFromPeriodJob=*/ false,
- map -> PowerUsageAdvanced.this.onBatteryDiffDataMapUpdate(map));
+ PowerUsageAdvanced.this::onBatteryDiffDataMapUpdate);
}
};
}
diff --git a/src/com/android/settings/fuelgauge/protos/battery_usage_slot.proto b/src/com/android/settings/fuelgauge/protos/battery_usage_slot.proto
index e3b604b..5bc1a3e 100644
--- a/src/com/android/settings/fuelgauge/protos/battery_usage_slot.proto
+++ b/src/com/android/settings/fuelgauge/protos/battery_usage_slot.proto
@@ -26,7 +26,9 @@
optional double consume_power = 9;
optional double foreground_usage_consume_power = 10;
optional double background_usage_consume_power = 11;
- optional int64 foreground_usage_time = 12;
- optional int64 background_usage_time = 13;
- optional int64 screen_on_time = 14;
+ optional double foreground_service_usage_consume_power = 12;
+ optional double cached_usage_consume_power = 13;
+ optional int64 foreground_usage_time = 14;
+ optional int64 background_usage_time = 15;
+ optional int64 screen_on_time = 16;
}
diff --git a/src/com/android/settings/fuelgauge/protos/power_anomaly_event.proto b/src/com/android/settings/fuelgauge/protos/power_anomaly_event.proto
index 644ab9e..99df215 100644
--- a/src/com/android/settings/fuelgauge/protos/power_anomaly_event.proto
+++ b/src/com/android/settings/fuelgauge/protos/power_anomaly_event.proto
@@ -60,4 +60,6 @@
optional string description_string = 5;
optional string main_button_string = 6;
optional string cancel_button_string = 7;
+ optional string dismiss_record_key = 8;
+ optional string item_key = 9;
}
diff --git a/src/com/android/settings/spa/app/appcompat/UserAspectRatioAppsPageProvider.kt b/src/com/android/settings/spa/app/appcompat/UserAspectRatioAppsPageProvider.kt
index 35e99a7..1884599 100644
--- a/src/com/android/settings/spa/app/appcompat/UserAspectRatioAppsPageProvider.kt
+++ b/src/com/android/settings/spa/app/appcompat/UserAspectRatioAppsPageProvider.kt
@@ -110,7 +110,7 @@
appList = appList,
header = {
Box(Modifier.padding(SettingsDimension.itemPadding)) {
- SettingsBody(UserAspectRatioAppsPageProvider.getSummary())
+ SettingsBody(stringResource(R.string.aspect_ratio_main_summary, Build.MODEL))
}
Illustration(object : IllustrationModel {
override val resId = R.raw.user_aspect_ratio_education
@@ -217,5 +217,5 @@
private enum class SpinnerItem(val stringResId: Int) {
Suggested(R.string.user_aspect_ratio_suggested_apps_label),
All(R.string.filter_all_apps),
- Overridden(R.string.user_aspect_ratio_overridden_apps_label)
+ Overridden(R.string.user_aspect_ratio_changed_apps_label)
}
\ No newline at end of file
diff --git a/src/com/android/settings/system/FactoryResetDemoUserPreferenceController.java b/src/com/android/settings/system/FactoryResetDemoUserPreferenceController.java
new file mode 100644
index 0000000..f6a9b31
--- /dev/null
+++ b/src/com/android/settings/system/FactoryResetDemoUserPreferenceController.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017 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.system;
+
+import android.content.Context;
+import com.android.settings.Utils;
+
+public class FactoryResetDemoUserPreferenceController extends FactoryResetPreferenceController {
+
+ public FactoryResetDemoUserPreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey);
+ }
+
+ /** Hide demo user specific "Factory reset" settings for non demo users. */
+ @Override
+ public int getAvailabilityStatus() {
+ return Utils.isDemoUser(mContext) ? AVAILABLE : DISABLED_FOR_USER;
+ }
+}
diff --git a/src/com/android/settings/system/FactoryResetPreferenceController.java b/src/com/android/settings/system/FactoryResetPreferenceController.java
index a307171..6e010c1 100644
--- a/src/com/android/settings/system/FactoryResetPreferenceController.java
+++ b/src/com/android/settings/system/FactoryResetPreferenceController.java
@@ -24,35 +24,26 @@
import com.android.settings.R;
import com.android.settings.Settings;
import com.android.settings.Utils;
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settings.core.BasePreferenceController;
-public class FactoryResetPreferenceController extends AbstractPreferenceController
- implements PreferenceControllerMixin {
- /** Key of the "Factory reset" preference in {@link R.xml.reset_dashboard_fragment}. */
- private static final String KEY_FACTORY_RESET = "factory_reset";
+public class FactoryResetPreferenceController extends BasePreferenceController {
private final UserManager mUm;
- public FactoryResetPreferenceController(Context context) {
- super(context);
+ public FactoryResetPreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey);
mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
}
- /** Hide "Factory reset" settings for secondary users, except demo users. */
+ /** Hide "Factory reset" settings for secondary users. */
@Override
- public boolean isAvailable() {
- return mUm.isAdminUser() || Utils.isDemoUser(mContext);
- }
-
- @Override
- public String getPreferenceKey() {
- return KEY_FACTORY_RESET;
+ public int getAvailabilityStatus() {
+ return mUm.isAdminUser() ? AVAILABLE : DISABLED_FOR_USER;
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
- if (KEY_FACTORY_RESET.equals(preference.getKey())) {
+ if (mPreferenceKey.equals(preference.getKey())) {
final Intent intent = new Intent(mContext, Settings.FactoryResetActivity.class);
mContext.startActivity(intent);
return true;
diff --git a/src/com/android/settings/system/ResetDashboardFragment.java b/src/com/android/settings/system/ResetDashboardFragment.java
index aea92aa..662edc5 100644
--- a/src/com/android/settings/system/ResetDashboardFragment.java
+++ b/src/com/android/settings/system/ResetDashboardFragment.java
@@ -78,7 +78,6 @@
if (SubscriptionUtil.isSimHardwareVisible(context)) {
controllers.add(new NetworkResetPreferenceController(context));
}
- controllers.add(new FactoryResetPreferenceController(context));
controllers.add(new ResetAppPrefPreferenceController(context, lifecycle));
return controllers;
}
diff --git a/src/com/android/settings/system/ResetPreferenceController.java b/src/com/android/settings/system/ResetPreferenceController.java
index 0740ac9..35f1ff7 100644
--- a/src/com/android/settings/system/ResetPreferenceController.java
+++ b/src/com/android/settings/system/ResetPreferenceController.java
@@ -26,13 +26,11 @@
private final UserManager mUm;
private final NetworkResetPreferenceController mNetworkReset;
- private final FactoryResetPreferenceController mFactpruReset;
public ResetPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
mNetworkReset = new NetworkResetPreferenceController(context);
- mFactpruReset = new FactoryResetPreferenceController(context);
}
@Override
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImplTest.java
index bf4e893..a0b449a 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImplTest.java
@@ -73,10 +73,6 @@
}
@Test
- public void testIsBatteryTipsFeedbackEnabled_returnFalse() {
- assertThat(mPowerFeatureProvider.isBatteryTipsFeedbackEnabled()).isFalse();
- }
- @Test
public void testGetBatteryUsageListConsumePowerThreshold_return0() {
assertThat(mPowerFeatureProvider.getBatteryUsageListConsumePowerThreshold()).isEqualTo(0.0);
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerTest.java
index 786a529..cd4e599 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerTest.java
@@ -28,6 +28,7 @@
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -44,9 +45,9 @@
import android.view.View;
import android.view.ViewPropertyAnimator;
import android.widget.LinearLayout;
+import android.widget.TextView;
import com.android.settings.SettingsActivity;
-import com.android.settings.testutils.BatteryTestUtils;
import com.android.settings.testutils.FakeFeatureFactory;
import org.junit.Before;
@@ -72,6 +73,8 @@
@Mock
private SettingsActivity mSettingsActivity;
@Mock
+ private TextView mChartSummaryTextView;
+ @Mock
private BatteryChartView mDailyChartView;
@Mock
private BatteryChartView mHourlyChartView;
@@ -112,6 +115,7 @@
setupHourlyChartViewAnimationMock();
mBatteryChartPreferenceController = createController();
mBatteryChartPreferenceController.mPrefContext = mContext;
+ mBatteryChartPreferenceController.mChartSummaryTextView = mChartSummaryTextView;
mBatteryChartPreferenceController.mDailyChartView = mDailyChartView;
mBatteryChartPreferenceController.mHourlyChartView = mHourlyChartView;
BatteryDiffEntry.clearCache();
@@ -180,7 +184,6 @@
mBatteryChartPreferenceController.mDailyChartLabelTextGenerator);
mBatteryChartPreferenceController.onBatteryLevelDataUpdate(createBatteryLevelData(60));
- mBatteryChartPreferenceController.onBatteryUsageMapUpdate(getEmptyBatteryUsageMap());
verify(mDailyChartView, atLeastOnce()).setVisibility(View.VISIBLE);
verify(mViewPropertyAnimator, atLeastOnce()).alpha(0f);
@@ -275,29 +278,78 @@
}
@Test
- public void refreshUi_normalCase_returnTrue() {
+ public void onBatteryLevelDataUpdate_oneDay_showHourlyChartOnly() {
+ doReturn(View.GONE).when(mHourlyChartView).getVisibility();
+
mBatteryChartPreferenceController.onBatteryLevelDataUpdate(createBatteryLevelData(6));
- mBatteryChartPreferenceController.onBatteryUsageMapUpdate(getEmptyBatteryUsageMap());
- assertThat(mBatteryChartPreferenceController.refreshUi()).isTrue();
+
+ verify(mChartSummaryTextView).setVisibility(View.VISIBLE);
+ verify(mDailyChartView).setVisibility(View.GONE);
+ verify(mHourlyChartView).setVisibility(View.VISIBLE);
}
@Test
- public void refreshUi_batteryIndexedMapIsNull_returnTrue() {
+ public void onBatteryLevelDataUpdate_selectAllForMultipleDays_showDailyChartOnly() {
+ doReturn(View.GONE).when(mHourlyChartView).getVisibility();
+
+ mBatteryChartPreferenceController.mDailyChartIndex = SELECTED_INDEX_ALL;
+ mBatteryChartPreferenceController.onBatteryLevelDataUpdate(createBatteryLevelData(60));
+
+ verify(mChartSummaryTextView).setVisibility(View.VISIBLE);
+ verify(mDailyChartView).setVisibility(View.VISIBLE);
+ verify(mHourlyChartView, never()).setVisibility(View.VISIBLE);
+ }
+
+ @Test
+ public void onBatteryLevelDataUpdate_selectOneDayForMultipleDays_showBothCharts() {
+ doReturn(View.GONE).when(mHourlyChartView).getVisibility();
+
+ mBatteryChartPreferenceController.mDailyChartIndex = 0;
+ mBatteryChartPreferenceController.onBatteryLevelDataUpdate(createBatteryLevelData(60));
+
+ verify(mChartSummaryTextView).setVisibility(View.VISIBLE);
+ verify(mDailyChartView).setVisibility(View.VISIBLE);
+ verify(mHourlyChartView).setVisibility(View.VISIBLE);
+ }
+
+ @Test
+ public void onBatteryLevelDataUpdate_batteryLevelDataIsNull_showNoChart() {
+ doReturn(View.GONE).when(mHourlyChartView).getVisibility();
+
mBatteryChartPreferenceController.onBatteryLevelDataUpdate(null);
- mBatteryChartPreferenceController.onBatteryUsageMapUpdate(getEmptyBatteryUsageMap());
- assertThat(mBatteryChartPreferenceController.refreshUi()).isTrue();
+
+ verify(mChartSummaryTextView).setVisibility(View.GONE);
+ verify(mDailyChartView).setVisibility(View.GONE);
+ verify(mHourlyChartView).setVisibility(View.GONE);
+ }
+
+ @Test
+ public void showEmptyChart_normalCase_showEmptyChart() {
+ doReturn(View.GONE).when(mHourlyChartView).getVisibility();
+
+ mBatteryChartPreferenceController.showEmptyChart();
+
+ verify(mChartSummaryTextView).setVisibility(View.VISIBLE);
+ verify(mDailyChartView).setVisibility(View.GONE);
+ verify(mHourlyChartView).setVisibility(View.VISIBLE);
}
@Test
public void refreshUi_dailyChartViewIsNull_ignoreRefresh() {
mBatteryChartPreferenceController.mDailyChartView = null;
- assertThat(mBatteryChartPreferenceController.refreshUi()).isFalse();
+
+ mBatteryChartPreferenceController.refreshUi();
+
+ verify(mChartSummaryTextView, never()).setVisibility(anyInt());
}
@Test
public void refreshUi_hourlyChartViewIsNull_ignoreRefresh() {
mBatteryChartPreferenceController.mHourlyChartView = null;
- assertThat(mBatteryChartPreferenceController.refreshUi()).isFalse();
+
+ mBatteryChartPreferenceController.refreshUi();
+
+ verify(mChartSummaryTextView, never()).setVisibility(anyInt());
}
@Test
@@ -408,57 +460,6 @@
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;
@@ -481,11 +482,6 @@
return new BatteryLevelData(batteryLevelMap);
}
- private static Map<Integer, Map<Integer, BatteryDiffData>> getEmptyBatteryUsageMap() {
- return Map.of(SELECTED_INDEX_ALL, Map.of(SELECTED_INDEX_ALL, new BatteryDiffData(
- null, 0, 0, 0, 0, 0, List.of(), List.of(), Set.of(), Set.of(), false)));
- }
-
private BatteryChartPreferenceController createController() {
final BatteryChartPreferenceController controller =
new BatteryChartPreferenceController(
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryLevelDataTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryLevelDataTest.java
index 13d60bb..7dc4eab 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryLevelDataTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryLevelDataTest.java
@@ -18,6 +18,10 @@
import static com.google.common.truth.Truth.assertThat;
+import android.util.Pair;
+
+import com.android.settings.testutils.BatteryTestUtils;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -211,4 +215,29 @@
assertThat(result.getHourlyBatteryLevelsPerDay().get(0).getLevels())
.isEqualTo(List.of(100, 98));
}
+
+ @Test
+ public void getIndexByTimestamps_returnExpectedResult() {
+ final BatteryLevelData batteryLevelData =
+ new BatteryLevelData(Map.of(
+ 1694354400000L, 1, // 2023-09-10 22:00:00
+ 1694361600000L, 2, // 2023-09-11 00:00:00
+ 1694368800000L, 3)); // 2023-09-11 02:00:00
+ final PowerAnomalyEvent event = BatteryTestUtils.createAppAnomalyEvent();
+
+ assertThat(batteryLevelData.getIndexByTimestamps(0L, 0L))
+ .isEqualTo(Pair.create(BatteryChartViewModel.SELECTED_INDEX_INVALID,
+ BatteryChartViewModel.SELECTED_INDEX_INVALID));
+ assertThat(batteryLevelData.getIndexByTimestamps(1694361600000L + 1L, 1694368800000L + 1L))
+ .isEqualTo(Pair.create(BatteryChartViewModel.SELECTED_INDEX_INVALID,
+ BatteryChartViewModel.SELECTED_INDEX_INVALID));
+ assertThat(batteryLevelData.getIndexByTimestamps(1694361600000L, 1694368800000L))
+ .isEqualTo(Pair.create(1, 0));
+ assertThat(batteryLevelData.getIndexByTimestamps(1694361600000L + 1L, 1694368800000L - 1L))
+ .isEqualTo(Pair.create(1, 0));
+ assertThat(batteryLevelData.getIndexByTimestamps(
+ event.getWarningItemInfo().getStartTimestamp(),
+ event.getWarningItemInfo().getEndTimestamp()))
+ .isEqualTo(Pair.create(1, 0));
+ }
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreferenceTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreferenceTest.java
index ac67dfd..630ff45 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreferenceTest.java
@@ -19,7 +19,9 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -45,16 +47,24 @@
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
+import java.util.Map;
+import java.util.Optional;
+
@RunWith(RobolectricTestRunner.class)
public final class BatteryTipsCardPreferenceTest {
private Context mContext;
private FakeFeatureFactory mFeatureFactory;
private BatteryTipsCardPreference mBatteryTipsCardPreference;
+ private PowerUsageAdvanced mPowerUsageAdvanced;
private BatteryTipsController mBatteryTipsController;
@Mock
private View mFakeView;
+ @Mock
+ private BatteryChartPreferenceController mBatteryChartPreferenceController;
+ @Mock
+ private BatteryUsageBreakdownController mBatteryUsageBreakdownController;
@Before
public void setUp() {
@@ -64,6 +74,14 @@
mBatteryTipsCardPreference = new BatteryTipsCardPreference(mContext, /*attrs=*/ null);
mBatteryTipsController = new BatteryTipsController(mContext);
mBatteryTipsController.mCardPreference = mBatteryTipsCardPreference;
+ mPowerUsageAdvanced = new PowerUsageAdvanced();
+ mPowerUsageAdvanced.mBatteryTipsController = mBatteryTipsController;
+ mPowerUsageAdvanced.mBatteryChartPreferenceController = mBatteryChartPreferenceController;
+ mPowerUsageAdvanced.mBatteryUsageBreakdownController = mBatteryUsageBreakdownController;
+ mPowerUsageAdvanced.mBatteryLevelData = Optional.of(new BatteryLevelData(Map.of(
+ 1694354400000L, 1, // 2023-09-10 22:00:00
+ 1694361600000L, 2, // 2023-09-11 00:00:00
+ 1694368800000L, 3))); // 2023-09-11 02:00:00
}
@Test
@@ -71,8 +89,9 @@
assertThat(mBatteryTipsCardPreference.getLayoutResource()).isEqualTo(
R.layout.battery_tips_card);
}
+
@Test
- public void onClick_mainBtn_getAdaptiveBrightnessLauncher() {
+ public void onClick_mainBtnOfSettingsAnomaly_getAdaptiveBrightnessLauncher() {
final ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
PowerAnomalyEvent adaptiveBrightnessAnomaly =
BatteryTestUtils.createAdaptiveBrightnessAnomalyEvent();
@@ -80,10 +99,10 @@
when(mFakeView.getId()).thenReturn(R.id.main_button);
doNothing().when(mContext).startActivity(captor.capture());
- mBatteryTipsController.handleBatteryTipsCardUpdated(adaptiveBrightnessAnomaly);
+ mPowerUsageAdvanced.onDisplayAnomalyEventUpdated(adaptiveBrightnessAnomaly);
mBatteryTipsCardPreference.onClick(mFakeView);
- assertThat(mBatteryTipsCardPreference.isVisible()).isEqualTo(false);
+ assertThat(mBatteryTipsCardPreference.isVisible()).isFalse();
verify(mContext).startActivity(any(Intent.class));
final Intent intent = captor.getValue();
assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
@@ -96,21 +115,53 @@
@Test
public void onClick_dismissBtn_cardDismissAndLogged() {
- PowerAnomalyEvent screenTimeoutAnomaly =
+ final PowerAnomalyEvent screenTimeoutAnomaly =
BatteryTestUtils.createScreenTimeoutAnomalyEvent();
DatabaseUtils.removeDismissedPowerAnomalyKeys(mContext);
when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
when(mFakeView.getId()).thenReturn(R.id.dismiss_button);
- mBatteryTipsController.handleBatteryTipsCardUpdated(screenTimeoutAnomaly);
+ mPowerUsageAdvanced.onDisplayAnomalyEventUpdated(screenTimeoutAnomaly);
mBatteryTipsCardPreference.onClick(mFakeView);
- assertThat(mBatteryTipsCardPreference.isVisible()).isEqualTo(false);
- assertThat(DatabaseUtils.getDismissedPowerAnomalyKeys(mContext).size())
- .isEqualTo(1);
+ assertThat(mBatteryTipsCardPreference.isVisible()).isFalse();
+ assertThat(DatabaseUtils.getDismissedPowerAnomalyKeys(mContext)).hasSize(1);
assertThat(DatabaseUtils.getDismissedPowerAnomalyKeys(mContext))
.contains(PowerAnomalyKey.KEY_SCREEN_TIMEOUT.name());
verify(mFeatureFactory.metricsFeatureProvider).action(
mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_DISMISS, "ScreenTimeoutAnomaly");
}
+
+ @Test
+ public void onClick_mainBtnOfAppsAnomaly_selectHighlightSlot() {
+ final PowerAnomalyEvent appsAnomaly = BatteryTestUtils.createAppAnomalyEvent();
+ when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
+ when(mFakeView.getId()).thenReturn(R.id.main_button);
+
+ mPowerUsageAdvanced.onDisplayAnomalyEventUpdated(appsAnomaly);
+ mBatteryTipsCardPreference.onClick(mFakeView);
+
+ assertThat(mBatteryTipsCardPreference.isVisible()).isFalse();
+ verify(mContext, never()).startActivity(any(Intent.class));
+ verify(mBatteryChartPreferenceController).selectHighlightSlotIndex();
+ verify(mFeatureFactory.metricsFeatureProvider).action(
+ mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_ACCEPT, "AppAnomaly");
+ }
+
+ @Test
+ public void onClick_dismissBtnOfAppsAnomaly_removeHighlightSlotIndex() {
+ final PowerAnomalyEvent appsAnomaly = BatteryTestUtils.createAppAnomalyEvent();
+ when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
+ when(mFakeView.getId()).thenReturn(R.id.dismiss_button);
+
+ mPowerUsageAdvanced.onDisplayAnomalyEventUpdated(appsAnomaly);
+ mBatteryTipsCardPreference.onClick(mFakeView);
+
+ assertThat(mBatteryTipsCardPreference.isVisible()).isFalse();
+ verify(mBatteryChartPreferenceController).onHighlightSlotIndexUpdate(
+ eq(BatteryChartViewModel.SELECTED_INDEX_INVALID),
+ eq(BatteryChartViewModel.SELECTED_INDEX_INVALID));
+ verify(mFeatureFactory.metricsFeatureProvider).action(
+ mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_DISMISS, "AppAnomaly");
+ }
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java
index ac9de1f..913c00a 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java
@@ -16,6 +16,8 @@
package com.android.settings.fuelgauge.batteryusage;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -74,13 +76,25 @@
}
@Test
+ public void getDismissRecordKey_returnExpectedResult() {
+ assertThat(BatteryTipsController.getDismissRecordKey(
+ BatteryTestUtils.createAdaptiveBrightnessAnomalyEvent()))
+ .isEqualTo("KEY_BRIGHTNESS");
+ assertThat(BatteryTipsController.getDismissRecordKey(
+ BatteryTestUtils.createScreenTimeoutAnomalyEvent()))
+ .isEqualTo("KEY_SCREEN_TIMEOUT");
+ assertThat(BatteryTipsController.getDismissRecordKey(
+ BatteryTestUtils.createAppAnomalyEvent()))
+ .isEqualTo("KEY_APP_1");
+ }
+
+ @Test
public void handleBatteryTipsCardUpdated_adaptiveBrightnessAnomaly_showAnomaly() {
PowerAnomalyEvent event = BatteryTestUtils.createAdaptiveBrightnessAnomalyEvent();
when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
mBatteryTipsController.handleBatteryTipsCardUpdated(event);
- verify(mBatteryTipsCardPreference).setAnomalyEventId("BrightnessAnomaly");
// Check pre-defined string
verify(mBatteryTipsCardPreference).setTitle(
"Turn on adaptive brightness to extend battery life");
@@ -90,9 +104,6 @@
verify(mBatteryTipsCardPreference).setMainButtonLabel("View Settings");
verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
// Check proto info
- verify(mBatteryTipsCardPreference).setMainButtonLauncherInfo(
- "com.android.settings.DisplaySettings",
- 46, "auto_brightness_entry");
verify(mBatteryTipsCardPreference).setVisible(true);
verify(mFeatureFactory.metricsFeatureProvider).action(
mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, "BrightnessAnomaly");
@@ -105,16 +116,12 @@
mBatteryTipsController.handleBatteryTipsCardUpdated(event);
- verify(mBatteryTipsCardPreference).setAnomalyEventId("ScreenTimeoutAnomaly");
verify(mBatteryTipsCardPreference).setTitle("Reduce screen timeout to extend battery life");
verify(mBatteryTipsCardPreference).setIconResourceId(R.drawable.ic_battery_tips_lightbulb);
verify(mBatteryTipsCardPreference).setMainButtonStrokeColorResourceId(
R.color.color_accent_selector);
verify(mBatteryTipsCardPreference).setMainButtonLabel("View Settings");
verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
- verify(mBatteryTipsCardPreference).setMainButtonLauncherInfo(
- "com.android.settings.display.ScreenTimeoutSettings",
- 1852, "60000");
verify(mBatteryTipsCardPreference).setVisible(true);
verify(mFeatureFactory.metricsFeatureProvider).action(
mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, "ScreenTimeoutAnomaly");
@@ -134,16 +141,12 @@
mBatteryTipsController.handleBatteryTipsCardUpdated(event);
- verify(mBatteryTipsCardPreference).setAnomalyEventId("ScreenTimeoutAnomaly");
verify(mBatteryTipsCardPreference).setTitle(testTitle);
verify(mBatteryTipsCardPreference).setIconResourceId(R.drawable.ic_battery_tips_lightbulb);
verify(mBatteryTipsCardPreference).setMainButtonStrokeColorResourceId(
R.color.color_accent_selector);
verify(mBatteryTipsCardPreference).setMainButtonLabel("View Settings");
verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
- verify(mBatteryTipsCardPreference).setMainButtonLauncherInfo(
- "com.android.settings.display.ScreenTimeoutSettings",
- 1852, "60000");
verify(mBatteryTipsCardPreference).setVisible(true);
verify(mFeatureFactory.metricsFeatureProvider).action(
mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, "ScreenTimeoutAnomaly");
@@ -156,7 +159,6 @@
mBatteryTipsController.handleBatteryTipsCardUpdated(event);
- verify(mBatteryTipsCardPreference).setAnomalyEventId("AppAnomaly");
verify(mBatteryTipsCardPreference).setTitle(
"Chrome used more battery than usual in foreground");
verify(mBatteryTipsCardPreference).setIconResourceId(
@@ -165,8 +167,6 @@
R.color.color_battery_anomaly_yellow_selector);
verify(mBatteryTipsCardPreference).setMainButtonLabel("Check");
verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
- verify(mBatteryTipsCardPreference).setMainButtonLauncherInfo(
- null, null, null);
verify(mBatteryTipsCardPreference).setVisible(true);
verify(mFeatureFactory.metricsFeatureProvider).action(
mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, "AppAnomaly");
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvancedTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvancedTest.java
new file mode 100644
index 0000000..953c2d4
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvancedTest.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2022 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.fuelgauge.batteryusage;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.ArgumentMatchers.notNull;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.util.Pair;
+
+import com.android.settings.testutils.BatteryTestUtils;
+import com.android.settings.testutils.shadow.ShadowDashboardFragment;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.util.Map;
+import java.util.Optional;
+import java.util.TimeZone;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = ShadowDashboardFragment.class)
+public final class PowerUsageAdvancedTest {
+
+ private Context mContext;
+ private PowerUsageAdvanced mPowerUsageAdvanced;
+
+ @Mock
+ private BatteryTipsController mBatteryTipsController;
+ @Mock
+ private BatteryChartPreferenceController mBatteryChartPreferenceController;
+ @Mock
+ private ScreenOnTimeController mScreenOnTimeController;
+ @Mock
+ private BatteryUsageBreakdownController mBatteryUsageBreakdownController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT+8"));
+ mContext = spy(RuntimeEnvironment.application);
+
+ mPowerUsageAdvanced = new PowerUsageAdvanced();
+ mPowerUsageAdvanced.mBatteryTipsController = mBatteryTipsController;
+ mPowerUsageAdvanced.mBatteryChartPreferenceController = mBatteryChartPreferenceController;
+ mPowerUsageAdvanced.mScreenOnTimeController = mScreenOnTimeController;
+ mPowerUsageAdvanced.mBatteryUsageBreakdownController = mBatteryUsageBreakdownController;
+ mPowerUsageAdvanced.mBatteryLevelData = Optional.of(new BatteryLevelData(Map.of(
+ 1694354400000L, 1, // 2023-09-10 22:00:00
+ 1694361600000L, 2, // 2023-09-11 00:00:00
+ 1694368800000L, 3))); // 2023-09-11 02:00:00
+ }
+
+ @Test
+ public void getHighestScoreAnomalyEvent_withEmptyOrNullList_getNull() {
+ assertThat(PowerUsageAdvanced.getHighestScoreAnomalyEvent(mContext, null)).isNull();
+ assertThat(PowerUsageAdvanced.getHighestScoreAnomalyEvent(
+ mContext, BatteryTestUtils.createEmptyPowerAnomalyEventList())).isNull();
+ }
+
+ @Test
+ public void getHighestScoreAnomalyEvent_withoutDismissed_getHighestScoreEvent() {
+ final PowerAnomalyEventList powerAnomalyEventList =
+ BatteryTestUtils.createNonEmptyPowerAnomalyEventList();
+
+ final PowerAnomalyEvent highestScoreEvent =
+ PowerUsageAdvanced.getHighestScoreAnomalyEvent(mContext, powerAnomalyEventList);
+
+ assertThat(highestScoreEvent)
+ .isEqualTo(BatteryTestUtils.createAdaptiveBrightnessAnomalyEvent());
+ }
+
+ @Test
+ public void getHighestScoreAnomalyEvent_withBrightnessDismissed_getScreenTimeout() {
+ final PowerAnomalyEventList powerAnomalyEventList =
+ BatteryTestUtils.createNonEmptyPowerAnomalyEventList();
+ DatabaseUtils.removeDismissedPowerAnomalyKeys(mContext);
+ DatabaseUtils.setDismissedPowerAnomalyKeys(mContext, PowerAnomalyKey.KEY_BRIGHTNESS.name());
+
+ final PowerAnomalyEvent highestScoreEvent =
+ PowerUsageAdvanced.getHighestScoreAnomalyEvent(mContext, powerAnomalyEventList);
+
+ assertThat(highestScoreEvent)
+ .isEqualTo(BatteryTestUtils.createScreenTimeoutAnomalyEvent());
+ }
+
+ @Test
+ public void getHighestScoreAnomalyEvent_withAllDismissed_getNull() {
+ final PowerAnomalyEventList powerAnomalyEventList =
+ BatteryTestUtils.createNonEmptyPowerAnomalyEventList();
+ DatabaseUtils.removeDismissedPowerAnomalyKeys(mContext);
+ for (PowerAnomalyKey key : PowerAnomalyKey.values()) {
+ DatabaseUtils.setDismissedPowerAnomalyKeys(mContext, key.name());
+ }
+
+ final PowerAnomalyEvent highestScoreEvent =
+ PowerUsageAdvanced.getHighestScoreAnomalyEvent(mContext, powerAnomalyEventList);
+
+ assertThat(highestScoreEvent).isNull();
+ }
+
+ @Test
+ public void onDisplayAnomalyEventUpdated_withSettingsAnomalyEvent_skipHighlightSlotEffect() {
+ final PowerAnomalyEvent event = BatteryTestUtils.createAdaptiveBrightnessAnomalyEvent();
+
+ mPowerUsageAdvanced.onDisplayAnomalyEventUpdated(event);
+
+ assertThat(mPowerUsageAdvanced.mPowerAnomalyEvent).isEqualTo(event);
+ verify(mBatteryTipsController).handleBatteryTipsCardUpdated(eq(event));
+ verify(mPowerUsageAdvanced.mBatteryTipsController).setOnAnomalyConfirmListener(isNull());
+ verify(mPowerUsageAdvanced.mBatteryTipsController).setOnAnomalyRejectListener(isNull());
+ verify(mPowerUsageAdvanced.mBatteryChartPreferenceController).onHighlightSlotIndexUpdate(
+ eq(BatteryChartViewModel.SELECTED_INDEX_INVALID),
+ eq(BatteryChartViewModel.SELECTED_INDEX_INVALID));
+ }
+
+ @Test
+ public void onDisplayAnomalyEventUpdated_withAppAnomalyEvent_setHighlightSlotEffect() {
+ final PowerAnomalyEvent event = BatteryTestUtils.createAppAnomalyEvent();
+
+ mPowerUsageAdvanced.onDisplayAnomalyEventUpdated(event);
+
+ assertThat(mPowerUsageAdvanced.mPowerAnomalyEvent).isEqualTo(event);
+ verify(mBatteryTipsController).handleBatteryTipsCardUpdated(eq(event));
+ verify(mBatteryTipsController).setOnAnomalyConfirmListener(isNull());
+ verify(mBatteryTipsController).setOnAnomalyRejectListener(isNull());
+
+ assertThat(event.getWarningItemInfo().hasStartTimestamp()).isTrue();
+ assertThat(event.getWarningItemInfo().hasEndTimestamp()).isTrue();
+ assertThat(mPowerUsageAdvanced.mBatteryLevelData.get().getIndexByTimestamps(
+ event.getWarningItemInfo().getStartTimestamp(),
+ event.getWarningItemInfo().getEndTimestamp()
+ )).isEqualTo(Pair.create(1, 0));
+ verify(mBatteryChartPreferenceController).onHighlightSlotIndexUpdate(eq(1), eq(0));
+ verify(mBatteryTipsController).setOnAnomalyConfirmListener(notNull());
+ verify(mBatteryTipsController).setOnAnomalyRejectListener(notNull());
+ }
+
+ @Test
+ public void onDisplayAnomalyEventUpdated_withNull_removeHighlightSlotEffect() {
+ final PowerAnomalyEvent event = BatteryTestUtils.createAppAnomalyEvent();
+
+ mPowerUsageAdvanced.onDisplayAnomalyEventUpdated(event);
+ mPowerUsageAdvanced.onDisplayAnomalyEventUpdated(null);
+
+ assertThat(mPowerUsageAdvanced.mPowerAnomalyEvent).isNull();
+ verify(mBatteryTipsController, times(2))
+ .setOnAnomalyConfirmListener(isNull());
+ verify(mBatteryTipsController, times(2))
+ .setOnAnomalyRejectListener(isNull());
+ verify(mBatteryTipsController).setOnAnomalyConfirmListener(notNull());
+ verify(mBatteryTipsController).setOnAnomalyRejectListener(notNull());
+
+ verify(mBatteryChartPreferenceController)
+ .onHighlightSlotIndexUpdate(eq(1), eq(0));
+ verify(mBatteryChartPreferenceController).onHighlightSlotIndexUpdate(
+ eq(BatteryChartViewModel.SELECTED_INDEX_INVALID),
+ eq(BatteryChartViewModel.SELECTED_INDEX_INVALID));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/system/FactoryResetDemoUserPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/system/FactoryResetDemoUserPreferenceControllerTest.java
new file mode 100644
index 0000000..0c92b05
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/system/FactoryResetDemoUserPreferenceControllerTest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2017 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.system;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.os.UserHandle;
+import android.provider.Settings;
+
+import com.android.settings.testutils.shadow.ShadowUserManager;
+import com.android.settings.testutils.shadow.ShadowUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = ShadowUserManager.class)
+public class FactoryResetDemoUserPreferenceControllerTest {
+
+ private static final String FACTORY_RESET_DEMO_USER_KEY = "factory_reset_demo_user";
+
+ private ShadowUserManager mShadowUserManager;
+
+ private Context mContext;
+ private FactoryResetDemoUserPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+ mShadowUserManager = ShadowUserManager.getShadow();
+
+ mController = new FactoryResetDemoUserPreferenceController(
+ mContext, FACTORY_RESET_DEMO_USER_KEY);
+ }
+
+ @After
+ public void tearDown() {
+ ShadowUtils.reset();
+ mShadowUserManager.setIsAdminUser(false);
+ mShadowUserManager.setIsDemoUser(false);
+ Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.DEVICE_DEMO_MODE, 0);
+ }
+
+ @Test
+ public void isAvailable_systemUser() {
+ mShadowUserManager.setIsAdminUser(true);
+
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void isAvailable_nonSystemUser() {
+ mShadowUserManager.setIsAdminUser(false);
+ mShadowUserManager.setIsDemoUser(false);
+
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void isAvailable_demoUser() {
+ mShadowUserManager.setIsAdminUser(false);
+
+ // Place the device in demo mode.
+ Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.DEVICE_DEMO_MODE, 1);
+
+ // Indicate the user is a demo user.
+ mShadowUserManager.addUser(UserHandle.myUserId(), "test", UserInfo.FLAG_DEMO);
+
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void getPreferenceKey() {
+ assertThat(mController.getPreferenceKey()).isEqualTo(FACTORY_RESET_DEMO_USER_KEY);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/system/FactoryResetPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/system/FactoryResetPreferenceControllerTest.java
index f2a932e..6e6fad8 100644
--- a/tests/robotests/src/com/android/settings/system/FactoryResetPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/system/FactoryResetPreferenceControllerTest.java
@@ -49,7 +49,7 @@
mContext = RuntimeEnvironment.application;
mShadowUserManager = ShadowUserManager.getShadow();
- mController = new FactoryResetPreferenceController(mContext);
+ mController = new FactoryResetPreferenceController(mContext, FACTORY_RESET_KEY);
}
@After
@@ -85,7 +85,7 @@
// Indicate the user is a demo user.
mShadowUserManager.addUser(UserHandle.myUserId(), "test", UserInfo.FLAG_DEMO);
- assertThat(mController.isAvailable()).isTrue();
+ assertThat(mController.isAvailable()).isFalse();
}
@Test
diff --git a/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java b/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java
index 3297d1e..1035560 100644
--- a/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java
@@ -283,6 +283,9 @@
.setKey(PowerAnomalyKey.KEY_APP)
.setScore(2.0f)
.setWarningItemInfo(WarningItemInfo.newBuilder()
+ .setDismissRecordKey("KEY_APP_1")
+ .setStartTimestamp(1694361600000L) // 2023-09-11 00:00:00
+ .setEndTimestamp(1694368800000L) // 2023-09-11 02:00:00
.setTitleString("Chrome used more battery than usual in foreground")
.setMainButtonString("Check")
.setCancelButtonString("Got it")
diff --git a/tests/spa_unit/src/com/android/settings/spa/app/appcompat/UserAspectRatioAppsPageProviderTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/appcompat/UserAspectRatioAppsPageProviderTest.kt
index c314655..044968d 100644
--- a/tests/spa_unit/src/com/android/settings/spa/app/appcompat/UserAspectRatioAppsPageProviderTest.kt
+++ b/tests/spa_unit/src/com/android/settings/spa/app/appcompat/UserAspectRatioAppsPageProviderTest.kt
@@ -67,7 +67,8 @@
@Test
fun injectEntry_summary() {
setInjectEntry()
- composeTestRule.onNodeWithText(context.getString(R.string.aspect_ratio_summary, Build.MODEL))
+ composeTestRule
+ .onNodeWithText(context.getString(R.string.aspect_ratio_summary, Build.MODEL))
.assertIsDisplayed()
}