Implement alternate power button behavior for dreams. am: bffe18bf28
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20132039 Change-Id: I906067a2d0763943e95f57149543eb59146f83e1 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -53,6 +53,13 @@ public abstract class DreamManagerInternal {
|
||||
*/
|
||||
public abstract void requestDream();
|
||||
|
||||
/**
|
||||
* Whether dreaming can start given user settings and the current dock/charge state.
|
||||
*
|
||||
* @param isScreenOn True if the screen is currently on.
|
||||
*/
|
||||
public abstract boolean canStartDreaming(boolean isScreenOn);
|
||||
|
||||
/**
|
||||
* Called by the ActivityTaskManagerService to verify that the startDreamActivity
|
||||
* request comes from the current active dream component.
|
||||
|
||||
@@ -23,12 +23,14 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
|
||||
import static com.android.server.wm.ActivityInterceptorCallback.DREAM_MANAGER_ORDERED_ID;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.TaskInfo;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
@@ -39,6 +41,8 @@ import android.content.pm.ServiceInfo;
|
||||
import android.database.ContentObserver;
|
||||
import android.hardware.display.AmbientDisplayConfiguration;
|
||||
import android.hardware.input.InputManagerInternal;
|
||||
import android.net.Uri;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
@@ -72,6 +76,8 @@ import com.android.server.wm.ActivityTaskManagerInternal;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@@ -88,6 +94,15 @@ public final class DreamManagerService extends SystemService {
|
||||
private static final String DOZE_WAKE_LOCK_TAG = "dream:doze";
|
||||
private static final String DREAM_WAKE_LOCK_TAG = "dream:dream";
|
||||
|
||||
/** Constants for the when to activate dreams. */
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({DREAM_ON_DOCK, DREAM_ON_CHARGE, DREAM_ON_DOCK_OR_CHARGE})
|
||||
public @interface WhenToDream {}
|
||||
private static final int DREAM_DISABLED = 0x0;
|
||||
private static final int DREAM_ON_DOCK = 0x1;
|
||||
private static final int DREAM_ON_CHARGE = 0x2;
|
||||
private static final int DREAM_ON_DOCK_OR_CHARGE = 0x3;
|
||||
|
||||
private final Object mLock = new Object();
|
||||
|
||||
private final Context mContext;
|
||||
@@ -101,12 +116,20 @@ public final class DreamManagerService extends SystemService {
|
||||
private final DreamUiEventLogger mDreamUiEventLogger;
|
||||
private final ComponentName mAmbientDisplayComponent;
|
||||
private final boolean mDismissDreamOnActivityStart;
|
||||
private final boolean mDreamsOnlyEnabledForSystemUser;
|
||||
private final boolean mDreamsEnabledByDefaultConfig;
|
||||
private final boolean mDreamsActivatedOnChargeByDefault;
|
||||
private final boolean mDreamsActivatedOnDockByDefault;
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private DreamRecord mCurrentDream;
|
||||
|
||||
private boolean mForceAmbientDisplayEnabled;
|
||||
private final boolean mDreamsOnlyEnabledForSystemUser;
|
||||
private SettingsObserver mSettingsObserver;
|
||||
private boolean mDreamsEnabledSetting;
|
||||
@WhenToDream private int mWhenToDream;
|
||||
private boolean mIsDocked;
|
||||
private boolean mIsCharging;
|
||||
|
||||
// A temporary dream component that, when present, takes precedence over user configured dream
|
||||
// component.
|
||||
@@ -144,6 +167,37 @@ public final class DreamManagerService extends SystemService {
|
||||
}
|
||||
};
|
||||
|
||||
private final BroadcastReceiver mChargingReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
mIsCharging = BatteryManager.ACTION_CHARGING.equals(intent.getAction());
|
||||
}
|
||||
};
|
||||
|
||||
private final BroadcastReceiver mDockStateReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) {
|
||||
final int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
|
||||
Intent.EXTRA_DOCK_STATE_UNDOCKED);
|
||||
mIsDocked = dockState != Intent.EXTRA_DOCK_STATE_UNDOCKED;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final class SettingsObserver extends ContentObserver {
|
||||
SettingsObserver(Handler handler) {
|
||||
super(handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(boolean selfChange, Uri uri) {
|
||||
synchronized (mLock) {
|
||||
updateWhenToDreamSettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DreamManagerService(Context context) {
|
||||
super(context);
|
||||
mContext = context;
|
||||
@@ -164,6 +218,14 @@ public final class DreamManagerService extends SystemService {
|
||||
mContext.getResources().getBoolean(R.bool.config_dreamsOnlyEnabledForSystemUser);
|
||||
mDismissDreamOnActivityStart = mContext.getResources().getBoolean(
|
||||
R.bool.config_dismissDreamOnActivityStart);
|
||||
|
||||
mDreamsEnabledByDefaultConfig = mContext.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_dreamsEnabledByDefault);
|
||||
mDreamsActivatedOnChargeByDefault = mContext.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault);
|
||||
mDreamsActivatedOnDockByDefault = mContext.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault);
|
||||
mSettingsObserver = new SettingsObserver(mHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -197,6 +259,30 @@ public final class DreamManagerService extends SystemService {
|
||||
DREAM_MANAGER_ORDERED_ID,
|
||||
mActivityInterceptorCallback);
|
||||
}
|
||||
|
||||
mContext.registerReceiver(
|
||||
mDockStateReceiver, new IntentFilter(Intent.ACTION_DOCK_EVENT));
|
||||
IntentFilter chargingIntentFilter = new IntentFilter();
|
||||
chargingIntentFilter.addAction(BatteryManager.ACTION_CHARGING);
|
||||
chargingIntentFilter.addAction(BatteryManager.ACTION_DISCHARGING);
|
||||
mContext.registerReceiver(mChargingReceiver, chargingIntentFilter);
|
||||
|
||||
mSettingsObserver = new SettingsObserver(mHandler);
|
||||
mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor(
|
||||
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP),
|
||||
false, mSettingsObserver, UserHandle.USER_ALL);
|
||||
mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor(
|
||||
Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK),
|
||||
false, mSettingsObserver, UserHandle.USER_ALL);
|
||||
mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor(
|
||||
Settings.Secure.SCREENSAVER_ENABLED),
|
||||
false, mSettingsObserver, UserHandle.USER_ALL);
|
||||
|
||||
// We don't get an initial broadcast for the batter state, so we have to initialize
|
||||
// directly from BatteryManager.
|
||||
mIsCharging = mContext.getSystemService(BatteryManager.class).isCharging();
|
||||
|
||||
updateWhenToDreamSettings();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,6 +293,14 @@ public final class DreamManagerService extends SystemService {
|
||||
pw.println("mCurrentDream=" + mCurrentDream);
|
||||
pw.println("mForceAmbientDisplayEnabled=" + mForceAmbientDisplayEnabled);
|
||||
pw.println("mDreamsOnlyEnabledForSystemUser=" + mDreamsOnlyEnabledForSystemUser);
|
||||
pw.println("mDreamsEnabledSetting=" + mDreamsEnabledSetting);
|
||||
pw.println("mForceAmbientDisplayEnabled=" + mForceAmbientDisplayEnabled);
|
||||
pw.println("mDreamsOnlyEnabledForSystemUser=" + mDreamsOnlyEnabledForSystemUser);
|
||||
pw.println("mDreamsActivatedOnDockByDefault=" + mDreamsActivatedOnDockByDefault);
|
||||
pw.println("mDreamsActivatedOnChargeByDefault=" + mDreamsActivatedOnChargeByDefault);
|
||||
pw.println("mIsDocked=" + mIsDocked);
|
||||
pw.println("mIsCharging=" + mIsCharging);
|
||||
pw.println("mWhenToDream=" + mWhenToDream);
|
||||
pw.println("getDozeComponent()=" + getDozeComponent());
|
||||
pw.println();
|
||||
|
||||
@@ -214,7 +308,28 @@ public final class DreamManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
/** Whether a real dream is occurring. */
|
||||
private void updateWhenToDreamSettings() {
|
||||
synchronized (mLock) {
|
||||
final ContentResolver resolver = mContext.getContentResolver();
|
||||
|
||||
final int activateWhenCharging = (Settings.Secure.getIntForUser(resolver,
|
||||
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
|
||||
mDreamsActivatedOnChargeByDefault ? 1 : 0,
|
||||
UserHandle.USER_CURRENT) != 0) ? DREAM_ON_CHARGE : DREAM_DISABLED;
|
||||
final int activateWhenDocked = (Settings.Secure.getIntForUser(resolver,
|
||||
Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
|
||||
mDreamsActivatedOnDockByDefault ? 1 : 0,
|
||||
UserHandle.USER_CURRENT) != 0) ? DREAM_ON_DOCK : DREAM_DISABLED;
|
||||
mWhenToDream = activateWhenCharging + activateWhenDocked;
|
||||
|
||||
mDreamsEnabledSetting = (Settings.Secure.getIntForUser(resolver,
|
||||
Settings.Secure.SCREENSAVER_ENABLED,
|
||||
mDreamsEnabledByDefaultConfig ? 1 : 0,
|
||||
UserHandle.USER_CURRENT) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
/** Whether a real dream is occurring. */
|
||||
private boolean isDreamingInternal() {
|
||||
synchronized (mLock) {
|
||||
return mCurrentDream != null && !mCurrentDream.isPreview
|
||||
@@ -236,6 +351,30 @@ public final class DreamManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
/** Whether dreaming can start given user settings and the current dock/charge state. */
|
||||
private boolean canStartDreamingInternal(boolean isScreenOn) {
|
||||
synchronized (mLock) {
|
||||
// Can't start dreaming if we are already dreaming.
|
||||
if (isScreenOn && isDreamingInternal()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mDreamsEnabledSetting) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((mWhenToDream & DREAM_ON_CHARGE) == DREAM_ON_CHARGE) {
|
||||
return mIsCharging;
|
||||
}
|
||||
|
||||
if ((mWhenToDream & DREAM_ON_DOCK) == DREAM_ON_DOCK) {
|
||||
return mIsDocked;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected void requestStartDreamFromShell() {
|
||||
requestDreamInternal();
|
||||
}
|
||||
@@ -868,6 +1007,11 @@ public final class DreamManagerService extends SystemService {
|
||||
return isDreamingInternal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canStartDreaming(boolean isScreenOn) {
|
||||
return canStartDreamingInternal(isScreenOn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComponentName getActiveDreamComponent(boolean doze) {
|
||||
return getActiveDreamComponentInternal(doze);
|
||||
|
||||
@@ -257,6 +257,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
static final int SHORT_PRESS_POWER_GO_HOME = 4;
|
||||
static final int SHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME = 5;
|
||||
static final int SHORT_PRESS_POWER_LOCK_OR_SLEEP = 6;
|
||||
static final int SHORT_PRESS_POWER_DREAM_OR_SLEEP = 7;
|
||||
|
||||
// must match: config_LongPressOnPowerBehavior in config.xml
|
||||
static final int LONG_PRESS_POWER_NOTHING = 0;
|
||||
@@ -973,7 +974,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
powerMultiPressAction(eventTime, interactive, mTriplePressOnPowerBehavior);
|
||||
} else if (count > 3 && count <= getMaxMultiPressPowerCount()) {
|
||||
Slog.d(TAG, "No behavior defined for power press count " + count);
|
||||
} else if (count == 1 && interactive && !beganFromNonInteractive) {
|
||||
} else if (count == 1 && interactive) {
|
||||
if (beganFromNonInteractive) {
|
||||
// The screen off case, where we might want to start dreaming on power button press.
|
||||
attemptToDreamFromShortPowerButtonPress(false, () -> {});
|
||||
return;
|
||||
}
|
||||
if (mSideFpsEventHandler.shouldConsumeSinglePress(eventTime)) {
|
||||
Slog.i(TAG, "Suppressing power key because the user is interacting with the "
|
||||
+ "fingerprint sensor");
|
||||
@@ -1022,10 +1028,38 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SHORT_PRESS_POWER_DREAM_OR_SLEEP: {
|
||||
attemptToDreamFromShortPowerButtonPress(
|
||||
true,
|
||||
() -> sleepDefaultDisplayFromPowerButton(eventTime, 0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to dream from a power button press.
|
||||
*
|
||||
* @param isScreenOn Whether the screen is currently on.
|
||||
* @param noDreamAction The action to perform if dreaming is not possible.
|
||||
*/
|
||||
private void attemptToDreamFromShortPowerButtonPress(
|
||||
boolean isScreenOn, Runnable noDreamAction) {
|
||||
if (mShortPressOnPowerBehavior != SHORT_PRESS_POWER_DREAM_OR_SLEEP) {
|
||||
noDreamAction.run();
|
||||
return;
|
||||
}
|
||||
|
||||
final DreamManagerInternal dreamManagerInternal = getDreamManagerInternal();
|
||||
if (dreamManagerInternal == null || !dreamManagerInternal.canStartDreaming(isScreenOn)) {
|
||||
noDreamAction.run();
|
||||
return;
|
||||
}
|
||||
|
||||
dreamManagerInternal.requestDream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the default display to sleep as a result of a power button press.
|
||||
*
|
||||
@@ -1597,7 +1631,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
|
||||
// If there's a dream running then use home to escape the dream
|
||||
// but don't actually go home.
|
||||
if (mDreamManagerInternal != null && mDreamManagerInternal.isDreaming()) {
|
||||
final DreamManagerInternal dreamManagerInternal = getDreamManagerInternal();
|
||||
if (dreamManagerInternal != null && dreamManagerInternal.isDreaming()) {
|
||||
mDreamManagerInternal.stopDream(false /*immediate*/, "short press on home" /*reason*/);
|
||||
return;
|
||||
}
|
||||
@@ -2486,6 +2521,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
}
|
||||
}
|
||||
|
||||
private DreamManagerInternal getDreamManagerInternal() {
|
||||
if (mDreamManagerInternal == null) {
|
||||
// If mDreamManagerInternal is null, attempt to re-fetch it.
|
||||
mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class);
|
||||
}
|
||||
|
||||
return mDreamManagerInternal;
|
||||
}
|
||||
|
||||
private void updateWakeGestureListenerLp() {
|
||||
if (shouldEnableWakeGestureLp()) {
|
||||
mWakeGestureListener.requestWakeUpTrigger();
|
||||
|
||||
Reference in New Issue
Block a user