Merge "Impl the detect & show pipeline for PowerAnomalyEventList." into udc-qpr-dev am: 1119c81d10

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/24400415

Change-Id: I81f08d96e2867dd70d031bb7ee4a05756daa33ed
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
YK Hung
2023-08-18 02:08:40 +00:00
committed by Automerger Merge Worker
4 changed files with 86 additions and 6 deletions

View File

@@ -28,7 +28,6 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:maxLines="2"
android:textAlignment="viewStart" android:textAlignment="viewStart"
android:textAppearance="?android:attr/textAppearanceLarge" android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="?android:attr/textColorPrimary" /> android:textColor="?android:attr/textColorPrimary" />
@@ -45,7 +44,7 @@
style="@style/Widget.Material3.Button.TextButton" style="@style/Widget.Material3.Button.TextButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="end" android:layout_gravity="end|center_vertical"
android:paddingHorizontal="16dp" android:paddingHorizontal="16dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:text="@string/battery_tips_card_dismiss_button" android:text="@string/battery_tips_card_dismiss_button"
@@ -59,7 +58,7 @@
android:paddingHorizontal="16dp" android:paddingHorizontal="16dp"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="end" android:layout_gravity="end|center_vertical"
android:text="@string/battery_tips_card_action_button" android:text="@string/battery_tips_card_action_button"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorPrimary" android:textColor="?android:attr/textColorPrimary"

View File

@@ -36,6 +36,7 @@ import androidx.preference.PreferenceScreen;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -43,6 +44,7 @@ import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnCreate; import com.android.settingslib.core.lifecycle.events.OnCreate;
import com.android.settingslib.core.lifecycle.events.OnDestroy; 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.OnResume;
import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState; import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
@@ -50,12 +52,17 @@ import com.google.common.base.Objects;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
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. */ /** Controls the update for chart graph and the list items. */
public class BatteryChartPreferenceController extends AbstractPreferenceController public class BatteryChartPreferenceController extends AbstractPreferenceController
implements PreferenceControllerMixin, LifecycleObserver, OnCreate, OnDestroy, implements PreferenceControllerMixin, LifecycleObserver, OnCreate, OnDestroy, OnPause,
OnSaveInstanceState, OnResume { OnSaveInstanceState, OnResume {
private static final String TAG = "BatteryChartPreferenceController"; private static final String TAG = "BatteryChartPreferenceController";
private static final String PREFERENCE_KEY = "battery_chart"; private static final String PREFERENCE_KEY = "battery_chart";
@@ -133,14 +140,17 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
private OnBatteryUsageUpdatedListener mOnBatteryUsageUpdatedListener; private OnBatteryUsageUpdatedListener mOnBatteryUsageUpdatedListener;
private OnScreenOnTimeUpdatedListener mOnScreenOnTimeUpdatedListener; private OnScreenOnTimeUpdatedListener mOnScreenOnTimeUpdatedListener;
private OnBatteryTipsUpdatedListener mOnBatteryTipsUpdatedListener; private OnBatteryTipsUpdatedListener mOnBatteryTipsUpdatedListener;
private AtomicBoolean mIsAppResume = new AtomicBoolean(false);
private final SettingsActivity mActivity; private final SettingsActivity mActivity;
private final MetricsFeatureProvider mMetricsFeatureProvider; private final MetricsFeatureProvider mMetricsFeatureProvider;
private final PowerUsageFeatureProvider mPowerUsageFeatureProvider;
private final Handler mHandler = new Handler(Looper.getMainLooper()); private final Handler mHandler = new Handler(Looper.getMainLooper());
private final AnimatorListenerAdapter mHourlyChartFadeInAdapter = private final AnimatorListenerAdapter mHourlyChartFadeInAdapter =
createHourlyChartAnimatorListenerAdapter(/*visible=*/ true); createHourlyChartAnimatorListenerAdapter(/*visible=*/ true);
private final AnimatorListenerAdapter mHourlyChartFadeOutAdapter = private final AnimatorListenerAdapter mHourlyChartFadeOutAdapter =
createHourlyChartAnimatorListenerAdapter(/*visible=*/ false); createHourlyChartAnimatorListenerAdapter(/*visible=*/ false);
private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
@VisibleForTesting @VisibleForTesting
final DailyChartLabelTextGenerator mDailyChartLabelTextGenerator = final DailyChartLabelTextGenerator mDailyChartLabelTextGenerator =
@@ -156,6 +166,8 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
mIs24HourFormat = DateFormat.is24HourFormat(context); mIs24HourFormat = DateFormat.is24HourFormat(context);
mMetricsFeatureProvider = mMetricsFeatureProvider =
FeatureFactory.getFactory(mContext).getMetricsFeatureProvider(); FeatureFactory.getFactory(mContext).getMetricsFeatureProvider();
mPowerUsageFeatureProvider =
FeatureFactory.getFactory(mContext).getPowerUsageFeatureProvider(context);
if (lifecycle != null) { if (lifecycle != null) {
lifecycle.addObserver(this); lifecycle.addObserver(this);
} }
@@ -173,9 +185,15 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
Log.d(TAG, String.format("onCreate() dailyIndex=%d hourlyIndex=%d", Log.d(TAG, String.format("onCreate() dailyIndex=%d hourlyIndex=%d",
mDailyChartIndex, mHourlyChartIndex)); mDailyChartIndex, mHourlyChartIndex));
} }
@Override
public void onPause() {
mIsAppResume.compareAndSet(/* expect= */ true, /* update= */ false);
}
@Override @Override
public void onResume() { public void onResume() {
mIsAppResume.compareAndSet(/* expect= */ false, /* update= */ true);
mIs24HourFormat = DateFormat.is24HourFormat(mContext); mIs24HourFormat = DateFormat.is24HourFormat(mContext);
mMetricsFeatureProvider.action(mPrefContext, SettingsEnums.OPEN_BATTERY_USAGE); mMetricsFeatureProvider.action(mPrefContext, SettingsEnums.OPEN_BATTERY_USAGE);
} }
@@ -363,14 +381,36 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
mOnBatteryUsageUpdatedListener.onBatteryUsageUpdated( mOnBatteryUsageUpdatedListener.onBatteryUsageUpdated(
slotUsageData, getSlotInformation(), isBatteryUsageMapNullOrEmpty()); slotUsageData, getSlotInformation(), isBatteryUsageMapNullOrEmpty());
Log.d(TAG, "isBatteryTipsEnabled = "
+ mPowerUsageFeatureProvider.isBatteryTipsEnabled());
if (mOnBatteryTipsUpdatedListener != null) { if (mOnBatteryTipsUpdatedListener != null) {
// TODO: replace with a selected powerAnomalyEvent with highest score mExecutor.execute(() -> {
mOnBatteryTipsUpdatedListener.onBatteryTipsUpdated(null); 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; return true;
} }
private PowerAnomalyEvent getHighestScoreAnomalyEvent(PowerAnomalyEventList anomalyEventList) {
if (anomalyEventList == null || anomalyEventList.getPowerAnomalyEventsCount() == 0) {
return null;
}
return Collections.max(anomalyEventList.getPowerAnomalyEventsList(),
Comparator.comparing(PowerAnomalyEvent::getScore));
}
private boolean refreshUiWithNoLevelDataCase() { private boolean refreshUiWithNoLevelDataCase() {
setChartSummaryVisible(false); setChartSummaryVisible(false);
if (mBatteryUsageMap == null) { if (mBatteryUsageMap == null) {

View File

@@ -101,6 +101,7 @@ public class BatteryTipsCardPreference extends Preference implements View.OnClic
.setDestination(mDestinationComponentName) .setDestination(mDestinationComponentName)
.setSourceMetricsCategory(mSourceMetricsCategory) .setSourceMetricsCategory(mSourceMetricsCategory)
.launch(); .launch();
setVisible(false);
} else if (viewId == R.id.dismiss_button) { } else if (viewId == R.id.dismiss_button) {
setVisible(false); setVisible(false);
} }

View File

@@ -18,15 +18,30 @@ package com.android.settings.fuelgauge.batteryusage;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.view.View;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.display.AutoBrightnessSettings;
import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
import com.android.settings.testutils.BatteryTestUtils;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment; import org.robolectric.RuntimeEnvironment;
@@ -36,13 +51,19 @@ public final class BatteryTipsCardPreferenceTest {
private Context mContext; private Context mContext;
private BatteryTipsCardPreference mBatteryTipsCardPreference; private BatteryTipsCardPreference mBatteryTipsCardPreference;
private BatteryTipsController mBatteryTipsController; private BatteryTipsController mBatteryTipsController;
@Mock
private View mFakeView;
@Mock
private PowerUsageFeatureProvider mPowerUsageFeatureProvider;
@Before @Before
public void setUp() { public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application); mContext = spy(RuntimeEnvironment.application);
mBatteryTipsCardPreference = new BatteryTipsCardPreference(mContext, /*attrs=*/ null); mBatteryTipsCardPreference = new BatteryTipsCardPreference(mContext, /*attrs=*/ null);
mBatteryTipsController = new BatteryTipsController(mContext); mBatteryTipsController = new BatteryTipsController(mContext);
mBatteryTipsController.mCardPreference = mBatteryTipsCardPreference; mBatteryTipsController.mCardPreference = mBatteryTipsCardPreference;
mBatteryTipsController.mPowerUsageFeatureProvider = mPowerUsageFeatureProvider;
} }
@Test @Test
@@ -50,4 +71,23 @@ public final class BatteryTipsCardPreferenceTest {
assertThat(mBatteryTipsCardPreference.getLayoutResource()).isEqualTo( assertThat(mBatteryTipsCardPreference.getLayoutResource()).isEqualTo(
R.layout.battery_tips_card); R.layout.battery_tips_card);
} }
@Test
public void onClick_actionBtn_getAdaptiveBrightnessLauncher() {
final ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
PowerAnomalyEvent adaptiveBrightnessAnomaly =
BatteryTestUtils.createAdaptiveBrightnessAnomalyEvent();
when(mPowerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
when(mFakeView.getId()).thenReturn(R.id.main_button);
doNothing().when(mContext).startActivity(captor.capture());
mBatteryTipsController.handleBatteryTipsCardUpdated(adaptiveBrightnessAnomaly);
mBatteryTipsCardPreference.onClick(mFakeView);
verify(mContext).startActivity(any(Intent.class));
final Intent intent = captor.getValue();
assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
.isEqualTo(AutoBrightnessSettings.class.getName());
assertThat(intent.getIntExtra(MetricsFeatureProvider.EXTRA_SOURCE_METRICS_CATEGORY, -1))
.isEqualTo(SettingsEnums.SETTINGS_AUTO_BRIGHTNESS);
}
} }