Add animation for power saver dialog
This dialog appears the first time Power Saver is enabled, if it's triggered from QS. Because there's a roundtrip through SettingsLib and a broadcast, we cannot just pass the view. Instead, save a (weak) reference to the view in the controller that can be retrieved when it's time to show the dialog. Test: manual Test: atest SystemUITests Fixes: 225183234 Change-Id: Ife049c5ce4eaf7823cd8ba636f511ada401308e3
This commit is contained in:
@@ -18,6 +18,7 @@ package com.android.systemui.power;
|
|||||||
|
|
||||||
import static android.app.PendingIntent.FLAG_IMMUTABLE;
|
import static android.app.PendingIntent.FLAG_IMMUTABLE;
|
||||||
|
|
||||||
|
import android.app.Dialog;
|
||||||
import android.app.KeyguardManager;
|
import android.app.KeyguardManager;
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
@@ -60,20 +61,25 @@ import com.android.settingslib.fuelgauge.BatterySaverUtils;
|
|||||||
import com.android.settingslib.utils.PowerUtil;
|
import com.android.settingslib.utils.PowerUtil;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.SystemUIApplication;
|
import com.android.systemui.SystemUIApplication;
|
||||||
|
import com.android.systemui.animation.DialogLaunchAnimator;
|
||||||
import com.android.systemui.broadcast.BroadcastSender;
|
import com.android.systemui.broadcast.BroadcastSender;
|
||||||
import com.android.systemui.dagger.SysUISingleton;
|
import com.android.systemui.dagger.SysUISingleton;
|
||||||
import com.android.systemui.plugins.ActivityStarter;
|
import com.android.systemui.plugins.ActivityStarter;
|
||||||
import com.android.systemui.statusbar.phone.SystemUIDialog;
|
import com.android.systemui.statusbar.phone.SystemUIDialog;
|
||||||
|
import com.android.systemui.statusbar.policy.BatteryController;
|
||||||
import com.android.systemui.util.NotificationChannels;
|
import com.android.systemui.util.NotificationChannels;
|
||||||
import com.android.systemui.volume.Events;
|
import com.android.systemui.volume.Events;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.Lazy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
@SysUISingleton
|
@SysUISingleton
|
||||||
@@ -164,11 +170,15 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
|
|||||||
private ActivityStarter mActivityStarter;
|
private ActivityStarter mActivityStarter;
|
||||||
private final BroadcastSender mBroadcastSender;
|
private final BroadcastSender mBroadcastSender;
|
||||||
|
|
||||||
|
private final Lazy<BatteryController> mBatteryControllerLazy;
|
||||||
|
private final DialogLaunchAnimator mDialogLaunchAnimator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
public PowerNotificationWarnings(Context context, ActivityStarter activityStarter,
|
public PowerNotificationWarnings(Context context, ActivityStarter activityStarter,
|
||||||
BroadcastSender broadcastSender) {
|
BroadcastSender broadcastSender, Lazy<BatteryController> batteryControllerLazy,
|
||||||
|
DialogLaunchAnimator dialogLaunchAnimator) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mNoMan = mContext.getSystemService(NotificationManager.class);
|
mNoMan = mContext.getSystemService(NotificationManager.class);
|
||||||
mPowerMan = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
mPowerMan = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||||
@@ -176,6 +186,8 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
|
|||||||
mReceiver.init();
|
mReceiver.init();
|
||||||
mActivityStarter = activityStarter;
|
mActivityStarter = activityStarter;
|
||||||
mBroadcastSender = broadcastSender;
|
mBroadcastSender = broadcastSender;
|
||||||
|
mBatteryControllerLazy = batteryControllerLazy;
|
||||||
|
mDialogLaunchAnimator = dialogLaunchAnimator;
|
||||||
mUseSevereDialog = mContext.getResources().getBoolean(R.bool.config_severe_battery_dialog);
|
mUseSevereDialog = mContext.getResources().getBoolean(R.bool.config_severe_battery_dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -685,8 +697,19 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
|
|||||||
}
|
}
|
||||||
d.setShowForAllUsers(true);
|
d.setShowForAllUsers(true);
|
||||||
d.setOnDismissListener((dialog) -> mSaverConfirmation = null);
|
d.setOnDismissListener((dialog) -> mSaverConfirmation = null);
|
||||||
d.show();
|
WeakReference<View> ref = mBatteryControllerLazy.get().getLastPowerSaverStartView();
|
||||||
|
if (ref != null && ref.get() != null && ref.get().isAggregatedVisible()) {
|
||||||
|
mDialogLaunchAnimator.showFromView(d, ref.get());
|
||||||
|
} else {
|
||||||
|
d.show();
|
||||||
|
}
|
||||||
mSaverConfirmation = d;
|
mSaverConfirmation = d;
|
||||||
|
mBatteryControllerLazy.get().clearLastPowerSaverStartView();
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
Dialog getSaverConfirmationDialog() {
|
||||||
|
return mSaverConfirmation;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isEnglishLocale() {
|
private boolean isEnglishLocale() {
|
||||||
|
|||||||
@@ -116,6 +116,11 @@ public class BatterySaverTile extends QSTileImpl<BooleanState> implements
|
|||||||
public void handleSetListening(boolean listening) {
|
public void handleSetListening(boolean listening) {
|
||||||
super.handleSetListening(listening);
|
super.handleSetListening(listening);
|
||||||
mSetting.setListening(listening);
|
mSetting.setListening(listening);
|
||||||
|
if (!listening) {
|
||||||
|
// If we stopped listening, it means that the tile is not visible. In that case, we
|
||||||
|
// don't need to save the view anymore
|
||||||
|
mBatteryController.clearLastPowerSaverStartView();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -128,7 +133,7 @@ public class BatterySaverTile extends QSTileImpl<BooleanState> implements
|
|||||||
if (getState().state == Tile.STATE_UNAVAILABLE) {
|
if (getState().state == Tile.STATE_UNAVAILABLE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mBatteryController.setPowerSaveMode(!mPowerSave);
|
mBatteryController.setPowerSaveMode(!mPowerSave, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.android.systemui.statusbar.policy;
|
package com.android.systemui.statusbar.policy;
|
||||||
|
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
import com.android.systemui.Dumpable;
|
import com.android.systemui.Dumpable;
|
||||||
import com.android.systemui.demomode.DemoMode;
|
import com.android.systemui.demomode.DemoMode;
|
||||||
@@ -24,6 +25,7 @@ import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChang
|
|||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
public interface BatteryController extends DemoMode, Dumpable,
|
public interface BatteryController extends DemoMode, Dumpable,
|
||||||
CallbackController<BatteryStateChangeCallback> {
|
CallbackController<BatteryStateChangeCallback> {
|
||||||
@@ -35,7 +37,32 @@ public interface BatteryController extends DemoMode, Dumpable,
|
|||||||
/**
|
/**
|
||||||
* Sets if the current device is in power save mode.
|
* Sets if the current device is in power save mode.
|
||||||
*/
|
*/
|
||||||
void setPowerSaveMode(boolean powerSave);
|
default void setPowerSaveMode(boolean powerSave) {
|
||||||
|
setPowerSaveMode(powerSave, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets if the current device is in power save mode.
|
||||||
|
*
|
||||||
|
* Can pass the view that triggered the request.
|
||||||
|
*/
|
||||||
|
void setPowerSaveMode(boolean powerSave, @Nullable View view);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a reference to the last view used when called {@link #setPowerSaveMode}.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default WeakReference<View> getLastPowerSaverStartView() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the last view used when called {@link #setPowerSaveMode}.
|
||||||
|
*
|
||||||
|
* Immediately after calling this, a call to {@link #getLastPowerSaverStartView()} should return
|
||||||
|
* {@code null}.
|
||||||
|
*/
|
||||||
|
default void clearLastPowerSaverStartView() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns {@code true} if the device is currently plugged in.
|
* Returns {@code true} if the device is currently plugged in.
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import android.os.Handler;
|
|||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.os.PowerSaveState;
|
import android.os.PowerSaveState;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@@ -45,8 +46,10 @@ import com.android.systemui.power.EnhancedEstimates;
|
|||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default implementation of a {@link BatteryController}. This controller monitors for battery
|
* Default implementation of a {@link BatteryController}. This controller monitors for battery
|
||||||
@@ -85,6 +88,11 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
|
|||||||
private Estimate mEstimate;
|
private Estimate mEstimate;
|
||||||
private boolean mFetchingEstimate = false;
|
private boolean mFetchingEstimate = false;
|
||||||
|
|
||||||
|
// Use AtomicReference because we may request it from a different thread
|
||||||
|
// Use WeakReference because we are keeping a reference to a View that's not as long lived
|
||||||
|
// as this controller.
|
||||||
|
private AtomicReference<WeakReference<View>> mPowerSaverStartView = new AtomicReference<>();
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public BatteryControllerImpl(
|
public BatteryControllerImpl(
|
||||||
Context context,
|
Context context,
|
||||||
@@ -141,10 +149,21 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setPowerSaveMode(boolean powerSave) {
|
public void setPowerSaveMode(boolean powerSave, View view) {
|
||||||
|
if (powerSave) mPowerSaverStartView.set(new WeakReference<>(view));
|
||||||
BatterySaverUtils.setPowerSaveMode(mContext, powerSave, /*needFirstTimeWarning*/ true);
|
BatterySaverUtils.setPowerSaveMode(mContext, powerSave, /*needFirstTimeWarning*/ true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WeakReference<View> getLastPowerSaverStartView() {
|
||||||
|
return mPowerSaverStartView.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearLastPowerSaverStartView() {
|
||||||
|
mPowerSaverStartView.set(null);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addCallback(@NonNull BatteryController.BatteryStateChangeCallback cb) {
|
public void addCallback(@NonNull BatteryController.BatteryStateChangeCallback cb) {
|
||||||
synchronized (mChangeCallbacks) {
|
synchronized (mChangeCallbacks) {
|
||||||
|
|||||||
@@ -25,29 +25,48 @@ import static org.mockito.Matchers.eq;
|
|||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.anyString;
|
import static org.mockito.Mockito.anyString;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.ContextWrapper;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
import android.os.BatteryManager;
|
import android.os.BatteryManager;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.UserHandle;
|
||||||
import android.test.suitebuilder.annotation.SmallTest;
|
import android.test.suitebuilder.annotation.SmallTest;
|
||||||
|
import android.testing.AndroidTestingRunner;
|
||||||
import androidx.test.runner.AndroidJUnit4;
|
import android.testing.TestableLooper;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
|
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
|
||||||
|
import com.android.settingslib.fuelgauge.BatterySaverUtils;
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
|
import com.android.systemui.animation.DialogLaunchAnimator;
|
||||||
import com.android.systemui.broadcast.BroadcastSender;
|
import com.android.systemui.broadcast.BroadcastSender;
|
||||||
import com.android.systemui.plugins.ActivityStarter;
|
import com.android.systemui.plugins.ActivityStarter;
|
||||||
|
import com.android.systemui.statusbar.policy.BatteryController;
|
||||||
import com.android.systemui.util.NotificationChannels;
|
import com.android.systemui.util.NotificationChannels;
|
||||||
|
|
||||||
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.ArgumentCaptor;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidTestingRunner.class)
|
||||||
|
@TestableLooper.RunWithLooper
|
||||||
public class PowerNotificationWarningsTest extends SysuiTestCase {
|
public class PowerNotificationWarningsTest extends SysuiTestCase {
|
||||||
|
|
||||||
public static final String FORMATTED_45M = "0h 45m";
|
public static final String FORMATTED_45M = "0h 45m";
|
||||||
@@ -55,14 +74,34 @@ public class PowerNotificationWarningsTest extends SysuiTestCase {
|
|||||||
private final NotificationManager mMockNotificationManager = mock(NotificationManager.class);
|
private final NotificationManager mMockNotificationManager = mock(NotificationManager.class);
|
||||||
private PowerNotificationWarnings mPowerNotificationWarnings;
|
private PowerNotificationWarnings mPowerNotificationWarnings;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private BatteryController mBatteryController;
|
||||||
|
@Mock
|
||||||
|
private DialogLaunchAnimator mDialogLaunchAnimator;
|
||||||
|
@Mock
|
||||||
|
private View mView;
|
||||||
|
|
||||||
|
private BroadcastReceiver mReceiver;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
|
Context wrapper = new ContextWrapper(mContext) {
|
||||||
|
@Override
|
||||||
|
public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
|
||||||
|
IntentFilter filter, String broadcastPermission, Handler scheduler, int flags) {
|
||||||
|
mReceiver = receiver;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Test Instance.
|
// Test Instance.
|
||||||
mContext.addMockSystemService(NotificationManager.class, mMockNotificationManager);
|
mContext.addMockSystemService(NotificationManager.class, mMockNotificationManager);
|
||||||
ActivityStarter starter = mDependency.injectMockDependency(ActivityStarter.class);
|
ActivityStarter starter = mDependency.injectMockDependency(ActivityStarter.class);
|
||||||
BroadcastSender broadcastSender = mDependency.injectMockDependency(BroadcastSender.class);
|
BroadcastSender broadcastSender = mDependency.injectMockDependency(BroadcastSender.class);
|
||||||
mPowerNotificationWarnings = new PowerNotificationWarnings(mContext, starter,
|
mPowerNotificationWarnings = new PowerNotificationWarnings(wrapper, starter,
|
||||||
broadcastSender);
|
broadcastSender, () -> mBatteryController, mDialogLaunchAnimator);
|
||||||
BatteryStateSnapshot snapshot = new BatteryStateSnapshot(100, false, false, 1,
|
BatteryStateSnapshot snapshot = new BatteryStateSnapshot(100, false, false, 1,
|
||||||
BatteryManager.BATTERY_HEALTH_GOOD, 5, 15);
|
BatteryManager.BATTERY_HEALTH_GOOD, 5, 15);
|
||||||
mPowerNotificationWarnings.updateSnapshot(snapshot);
|
mPowerNotificationWarnings.updateSnapshot(snapshot);
|
||||||
@@ -168,4 +207,52 @@ public class PowerNotificationWarningsTest extends SysuiTestCase {
|
|||||||
|
|
||||||
mPowerNotificationWarnings.mUsbHighTempDialog.dismiss();
|
mPowerNotificationWarnings.mUsbHighTempDialog.dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDialogStartedFromLauncher_viewVisible() {
|
||||||
|
when(mBatteryController.getLastPowerSaverStartView())
|
||||||
|
.thenReturn(new WeakReference<>(mView));
|
||||||
|
when(mView.isAggregatedVisible()).thenReturn(true);
|
||||||
|
|
||||||
|
Intent intent = new Intent(BatterySaverUtils.ACTION_SHOW_START_SAVER_CONFIRMATION);
|
||||||
|
intent.putExtras(new Bundle());
|
||||||
|
|
||||||
|
mReceiver.onReceive(mContext, intent);
|
||||||
|
|
||||||
|
verify(mDialogLaunchAnimator).showFromView(any(), eq(mView));
|
||||||
|
|
||||||
|
mPowerNotificationWarnings.getSaverConfirmationDialog().dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDialogStartedNotFromLauncher_viewNotVisible() {
|
||||||
|
when(mBatteryController.getLastPowerSaverStartView())
|
||||||
|
.thenReturn(new WeakReference<>(mView));
|
||||||
|
when(mView.isAggregatedVisible()).thenReturn(false);
|
||||||
|
|
||||||
|
Intent intent = new Intent(BatterySaverUtils.ACTION_SHOW_START_SAVER_CONFIRMATION);
|
||||||
|
intent.putExtras(new Bundle());
|
||||||
|
|
||||||
|
mReceiver.onReceive(mContext, intent);
|
||||||
|
|
||||||
|
verify(mDialogLaunchAnimator, never()).showFromView(any(), any());
|
||||||
|
|
||||||
|
assertThat(mPowerNotificationWarnings.getSaverConfirmationDialog().isShowing()).isTrue();
|
||||||
|
mPowerNotificationWarnings.getSaverConfirmationDialog().dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDialogShownNotFromLauncher() {
|
||||||
|
when(mBatteryController.getLastPowerSaverStartView()).thenReturn(null);
|
||||||
|
|
||||||
|
Intent intent = new Intent(BatterySaverUtils.ACTION_SHOW_START_SAVER_CONFIRMATION);
|
||||||
|
intent.putExtras(new Bundle());
|
||||||
|
|
||||||
|
mReceiver.onReceive(mContext, intent);
|
||||||
|
|
||||||
|
verify(mDialogLaunchAnimator, never()).showFromView(any(), any());
|
||||||
|
|
||||||
|
assertThat(mPowerNotificationWarnings.getSaverConfirmationDialog().isShowing()).isTrue();
|
||||||
|
mPowerNotificationWarnings.getSaverConfirmationDialog().dismiss();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import android.os.Handler
|
|||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
import android.testing.TestableLooper
|
import android.testing.TestableLooper
|
||||||
import android.testing.TestableLooper.RunWithLooper
|
import android.testing.TestableLooper.RunWithLooper
|
||||||
|
import android.view.View
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.internal.logging.MetricsLogger
|
import com.android.internal.logging.MetricsLogger
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
@@ -38,6 +39,9 @@ import org.junit.Test
|
|||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.Mockito.`when`
|
import org.mockito.Mockito.`when`
|
||||||
|
import org.mockito.Mockito.clearInvocations
|
||||||
|
import org.mockito.Mockito.never
|
||||||
|
import org.mockito.Mockito.verify
|
||||||
import org.mockito.MockitoAnnotations
|
import org.mockito.MockitoAnnotations
|
||||||
|
|
||||||
@RunWith(AndroidTestingRunner::class)
|
@RunWith(AndroidTestingRunner::class)
|
||||||
@@ -63,6 +67,8 @@ class BatterySaverTileTest : SysuiTestCase() {
|
|||||||
private lateinit var qsLogger: QSLogger
|
private lateinit var qsLogger: QSLogger
|
||||||
@Mock
|
@Mock
|
||||||
private lateinit var batteryController: BatteryController
|
private lateinit var batteryController: BatteryController
|
||||||
|
@Mock
|
||||||
|
private lateinit var view: View
|
||||||
private lateinit var secureSettings: SecureSettings
|
private lateinit var secureSettings: SecureSettings
|
||||||
private lateinit var testableLooper: TestableLooper
|
private lateinit var testableLooper: TestableLooper
|
||||||
private lateinit var tile: BatterySaverTile
|
private lateinit var tile: BatterySaverTile
|
||||||
@@ -105,4 +111,26 @@ class BatterySaverTileTest : SysuiTestCase() {
|
|||||||
|
|
||||||
assertEquals(USER + 1, tile.mSetting.currentUser)
|
assertEquals(USER + 1, tile.mSetting.currentUser)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testClickingPowerSavePassesView() {
|
||||||
|
tile.onPowerSaveChanged(true)
|
||||||
|
tile.handleClick(view)
|
||||||
|
|
||||||
|
tile.onPowerSaveChanged(false)
|
||||||
|
tile.handleClick(view)
|
||||||
|
|
||||||
|
verify(batteryController).setPowerSaveMode(true, view)
|
||||||
|
verify(batteryController).setPowerSaveMode(false, view)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testStopListeningClearsViewInController() {
|
||||||
|
clearInvocations(batteryController)
|
||||||
|
tile.handleSetListening(true)
|
||||||
|
verify(batteryController, never()).clearLastPowerSaverStartView()
|
||||||
|
|
||||||
|
tile.handleSetListening(false)
|
||||||
|
verify(batteryController).clearLastPowerSaverStartView()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -18,6 +18,10 @@ package com.android.systemui.statusbar.policy;
|
|||||||
|
|
||||||
import static android.os.BatteryManager.EXTRA_PRESENT;
|
import static android.os.BatteryManager.EXTRA_PRESENT;
|
||||||
|
|
||||||
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.inOrder;
|
||||||
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
|
||||||
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.staticMockMarker;
|
||||||
|
|
||||||
import static org.mockito.Mockito.atLeastOnce;
|
import static org.mockito.Mockito.atLeastOnce;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
@@ -30,20 +34,24 @@ import android.os.PowerSaveState;
|
|||||||
import android.test.suitebuilder.annotation.SmallTest;
|
import android.test.suitebuilder.annotation.SmallTest;
|
||||||
import android.testing.AndroidTestingRunner;
|
import android.testing.AndroidTestingRunner;
|
||||||
import android.testing.TestableLooper;
|
import android.testing.TestableLooper;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.android.dx.mockito.inline.extended.StaticInOrder;
|
||||||
|
import com.android.settingslib.fuelgauge.BatterySaverUtils;
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||||
import com.android.systemui.demomode.DemoModeController;
|
import com.android.systemui.demomode.DemoModeController;
|
||||||
import com.android.systemui.power.EnhancedEstimates;
|
import com.android.systemui.power.EnhancedEstimates;
|
||||||
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
|
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
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.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.mockito.MockitoSession;
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@RunWith(AndroidTestingRunner.class)
|
@RunWith(AndroidTestingRunner.class)
|
||||||
@@ -53,11 +61,19 @@ public class BatteryControllerTest extends SysuiTestCase {
|
|||||||
@Mock private PowerManager mPowerManager;
|
@Mock private PowerManager mPowerManager;
|
||||||
@Mock private BroadcastDispatcher mBroadcastDispatcher;
|
@Mock private BroadcastDispatcher mBroadcastDispatcher;
|
||||||
@Mock private DemoModeController mDemoModeController;
|
@Mock private DemoModeController mDemoModeController;
|
||||||
|
@Mock private View mView;
|
||||||
private BatteryControllerImpl mBatteryController;
|
private BatteryControllerImpl mBatteryController;
|
||||||
|
|
||||||
|
private MockitoSession mMockitoSession;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
mMockitoSession = mockitoSession()
|
||||||
|
.initMocks(this)
|
||||||
|
.mockStatic(BatterySaverUtils.class)
|
||||||
|
.startMocking();
|
||||||
|
|
||||||
mBatteryController = new BatteryControllerImpl(getContext(),
|
mBatteryController = new BatteryControllerImpl(getContext(),
|
||||||
mock(EnhancedEstimates.class),
|
mock(EnhancedEstimates.class),
|
||||||
mPowerManager,
|
mPowerManager,
|
||||||
@@ -68,6 +84,11 @@ public class BatteryControllerTest extends SysuiTestCase {
|
|||||||
mBatteryController.init();
|
mBatteryController.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
mMockitoSession.finishMocking();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBatteryInitialized() {
|
public void testBatteryInitialized() {
|
||||||
Assert.assertTrue(mBatteryController.mHasReceivedBattery);
|
Assert.assertTrue(mBatteryController.mHasReceivedBattery);
|
||||||
@@ -135,4 +156,33 @@ public class BatteryControllerTest extends SysuiTestCase {
|
|||||||
// THEN it is informed about the battery state
|
// THEN it is informed about the battery state
|
||||||
verify(cb, atLeastOnce()).onBatteryUnknownStateChanged(true);
|
verify(cb, atLeastOnce()).onBatteryUnknownStateChanged(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBatteryUtilsCalledOnSetPowerSaveMode() {
|
||||||
|
mBatteryController.setPowerSaveMode(true, mView);
|
||||||
|
mBatteryController.setPowerSaveMode(false, mView);
|
||||||
|
|
||||||
|
StaticInOrder inOrder = inOrder(staticMockMarker(BatterySaverUtils.class));
|
||||||
|
inOrder.verify(() -> BatterySaverUtils.setPowerSaveMode(getContext(), true, true));
|
||||||
|
inOrder.verify(() -> BatterySaverUtils.setPowerSaveMode(getContext(), false, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSaveViewReferenceWhenSettingPowerSaveMode() {
|
||||||
|
mBatteryController.setPowerSaveMode(false, mView);
|
||||||
|
|
||||||
|
Assert.assertNull(mBatteryController.getLastPowerSaverStartView());
|
||||||
|
|
||||||
|
mBatteryController.setPowerSaveMode(true, mView);
|
||||||
|
|
||||||
|
Assert.assertSame(mView, mBatteryController.getLastPowerSaverStartView().get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClearViewReference() {
|
||||||
|
mBatteryController.setPowerSaveMode(true, mView);
|
||||||
|
mBatteryController.clearLastPowerSaverStartView();
|
||||||
|
|
||||||
|
Assert.assertNull(mBatteryController.getLastPowerSaverStartView());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ package com.android.systemui.utils.leaks;
|
|||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.testing.LeakCheck;
|
import android.testing.LeakCheck;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
import com.android.systemui.statusbar.policy.BatteryController;
|
import com.android.systemui.statusbar.policy.BatteryController;
|
||||||
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
|
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
|
||||||
@@ -46,6 +47,11 @@ public class FakeBatteryController extends BaseLeakChecker<BatteryStateChangeCal
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPowerSaveMode(boolean powerSave, View view) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPluggedIn() {
|
public boolean isPluggedIn() {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user