AmbientDisplay: Add always on prototype
Test: adb shell settings put secure doze_always_on 1 Change-Id: I3f293b3ef43847b7848af416b44f212fc40514d4
This commit is contained in:
@@ -6000,6 +6000,12 @@ public final class Settings {
|
||||
*/
|
||||
public static final String DOZE_ENABLED = "doze_enabled";
|
||||
|
||||
/**
|
||||
* Whether doze should be always on.
|
||||
* @hide
|
||||
*/
|
||||
public static final String DOZE_ALWAYS_ON = "doze_always_on";
|
||||
|
||||
/**
|
||||
* Whether the device should pulse on pick up gesture.
|
||||
* @hide
|
||||
|
||||
@@ -1667,6 +1667,14 @@
|
||||
not appear on production builds ever. -->
|
||||
<string name="plugins" translatable="false">Plugins</string>
|
||||
|
||||
<!-- Ambient display section of the tuner. Non-translatable since it should
|
||||
not appear on production builds ever. -->
|
||||
<string name="tuner_doze" translatable="false">Ambient Display</string>
|
||||
|
||||
<!-- Ambient display always-on of the tuner. Non-translatable since it should
|
||||
not appear on production builds ever. -->
|
||||
<string name="tuner_doze_always_on" translatable="false">Always on</string>
|
||||
|
||||
<!-- PIP section of the tuner. Non-translatable since it should
|
||||
not appear on production builds ever. -->
|
||||
<string name="picture_in_picture" translatable="false">Picture-in-Picture</string>
|
||||
|
||||
@@ -139,6 +139,17 @@
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
<PreferenceScreen
|
||||
android:key="doze"
|
||||
android:title="@string/tuner_doze">
|
||||
|
||||
<com.android.systemui.tuner.TunerSwitch
|
||||
android:key="doze_always_on"
|
||||
android:title="@string/tuner_doze_always_on"
|
||||
sysui:defValue="false" />
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
<!--
|
||||
<Preference
|
||||
android:key="nav_bar"
|
||||
|
||||
@@ -27,6 +27,7 @@ public interface DozeHost {
|
||||
void startDozing(@NonNull Runnable ready);
|
||||
void pulseWhileDozing(@NonNull PulseCallback callback, int reason);
|
||||
void stopDozing();
|
||||
void dozeTimeTick();
|
||||
boolean isPowerSaveActive();
|
||||
boolean isNotificationLightOn();
|
||||
boolean isPulsingBlocked();
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.doze;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.UiModeManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
@@ -43,7 +44,9 @@ import com.android.systemui.util.Assert;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
public class DozeService extends DreamService implements DozeSensors.Callback {
|
||||
private static final String TAG = "DozeService";
|
||||
@@ -77,6 +80,7 @@ public class DozeService extends DreamService implements DozeSensors.Callback {
|
||||
private long mNotificationPulseTime;
|
||||
|
||||
private AmbientDisplayConfiguration mConfig;
|
||||
private AlarmManager mAlarmManager;
|
||||
|
||||
public DozeService() {
|
||||
if (DEBUG) Log.d(mTag, "new DozeService()");
|
||||
@@ -114,6 +118,7 @@ public class DozeService extends DreamService implements DozeSensors.Callback {
|
||||
setWindowless(true);
|
||||
|
||||
mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
|
||||
mAlarmManager = (AlarmManager) mContext.getSystemService(AlarmManager.class);
|
||||
mConfig = new AmbientDisplayConfiguration(mContext);
|
||||
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
|
||||
mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
|
||||
@@ -168,6 +173,10 @@ public class DozeService extends DreamService implements DozeSensors.Callback {
|
||||
// stopDozing because can we just keep dozing until the bitter end.
|
||||
}
|
||||
}));
|
||||
|
||||
if (mDozeParameters.getAlwaysOn()) {
|
||||
mTimeTick.onAlarm();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -184,6 +193,7 @@ public class DozeService extends DreamService implements DozeSensors.Callback {
|
||||
|
||||
// Tell the host that it's over.
|
||||
mHost.stopDozing();
|
||||
mAlarmManager.cancel(mTimeTick);
|
||||
}
|
||||
|
||||
private void requestPulse(final int reason) {
|
||||
@@ -264,7 +274,11 @@ public class DozeService extends DreamService implements DozeSensors.Callback {
|
||||
|
||||
private void turnDisplayOff() {
|
||||
if (DEBUG) Log.d(mTag, "Display off");
|
||||
setDozeScreenState(Display.STATE_OFF);
|
||||
if (mDozeParameters.getAlwaysOn()) {
|
||||
turnDisplayOn();
|
||||
} else {
|
||||
setDozeScreenState(Display.STATE_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
private void turnDisplayOn() {
|
||||
@@ -353,6 +367,26 @@ public class DozeService extends DreamService implements DozeSensors.Callback {
|
||||
}
|
||||
};
|
||||
|
||||
private AlarmManager.OnAlarmListener mTimeTick = new AlarmManager.OnAlarmListener() {
|
||||
@Override
|
||||
public void onAlarm() {
|
||||
mHost.dozeTimeTick();
|
||||
|
||||
// Keep wakelock until a frame has been pushed.
|
||||
mHandler.post(mWakeLock.wrap(()->{}));
|
||||
|
||||
Calendar calendar = GregorianCalendar.getInstance();
|
||||
calendar.setTimeInMillis(System.currentTimeMillis());
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.add(Calendar.MINUTE, 1);
|
||||
|
||||
long delta = calendar.getTimeInMillis() - System.currentTimeMillis();
|
||||
mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
|
||||
SystemClock.elapsedRealtime() + delta, "doze_time_tick", mTimeTick, mHandler);
|
||||
}
|
||||
};
|
||||
|
||||
private final DozeHost.Callback mHostCallback = new DozeHost.Callback() {
|
||||
@Override
|
||||
public void onNewNotifications() {
|
||||
|
||||
@@ -17,20 +17,17 @@
|
||||
package com.android.systemui.statusbar.phone;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.SystemProperties;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.MathUtils;
|
||||
import android.util.SparseBooleanArray;
|
||||
|
||||
import com.android.internal.hardware.AmbientDisplayConfiguration;
|
||||
import com.android.systemui.R;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class DozeParameters {
|
||||
private static final int MAX_DURATION = 60 * 1000;
|
||||
@@ -115,6 +112,12 @@ public class DozeParameters {
|
||||
return getInt("doze.pickup.vibration.threshold", R.integer.doze_pickup_vibration_threshold);
|
||||
}
|
||||
|
||||
public boolean getAlwaysOn() {
|
||||
return Build.IS_DEBUGGABLE
|
||||
&& Settings.Secure.getIntForUser(mContext.getContentResolver(),
|
||||
Settings.Secure.DOZE_ALWAYS_ON, 0, UserHandle.USER_CURRENT) != 0;
|
||||
}
|
||||
|
||||
private boolean getBoolean(String propName, int resId) {
|
||||
return SystemProperties.getBoolean(propName, mContext.getResources().getBoolean(resId));
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.annotation.NonNull;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import com.android.systemui.Interpolators;
|
||||
@@ -40,6 +41,8 @@ public class DozeScrimController {
|
||||
private final Handler mHandler = new Handler();
|
||||
private final ScrimController mScrimController;
|
||||
|
||||
private final View mStackScroller;
|
||||
|
||||
private boolean mDozing;
|
||||
private DozeHost.PulseCallback mPulseCallback;
|
||||
private int mPulseReason;
|
||||
@@ -48,7 +51,9 @@ public class DozeScrimController {
|
||||
private float mInFrontTarget;
|
||||
private float mBehindTarget;
|
||||
|
||||
public DozeScrimController(ScrimController scrimController, Context context) {
|
||||
public DozeScrimController(ScrimController scrimController, Context context,
|
||||
View stackScroller) {
|
||||
mStackScroller = stackScroller;
|
||||
mScrimController = scrimController;
|
||||
mDozeParameters = new DozeParameters(context);
|
||||
}
|
||||
@@ -59,7 +64,11 @@ public class DozeScrimController {
|
||||
if (mDozing) {
|
||||
abortAnimations();
|
||||
mScrimController.setDozeBehindAlpha(1f);
|
||||
mScrimController.setDozeInFrontAlpha(1f);
|
||||
mScrimController.setDozeInFrontAlpha(mDozeParameters.getAlwaysOn() ? 0f : 1f);
|
||||
if (mDozeParameters.getAlwaysOn()) {
|
||||
mStackScroller.setAlpha(0f);
|
||||
mHandler.postDelayed(() -> mStackScroller.setAlpha(0f), 30);
|
||||
}
|
||||
} else {
|
||||
cancelPulsing();
|
||||
if (animate) {
|
||||
@@ -74,6 +83,9 @@ public class DozeScrimController {
|
||||
mScrimController.setDozeBehindAlpha(0f);
|
||||
mScrimController.setDozeInFrontAlpha(0f);
|
||||
}
|
||||
if (mDozeParameters.getAlwaysOn()) {
|
||||
mStackScroller.setAlpha(1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +105,9 @@ public class DozeScrimController {
|
||||
// be invoked when we're done so that the caller can drop the pulse wakelock.
|
||||
mPulseCallback = callback;
|
||||
mPulseReason = reason;
|
||||
mHandler.post(mPulseIn);
|
||||
if (mDozeParameters.getAlwaysOn()) {
|
||||
mHandler.post(mPulseIn);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,6 +125,9 @@ public class DozeScrimController {
|
||||
if (isPulsing()) {
|
||||
final boolean pickupOrDoubleTap = mPulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP
|
||||
|| mPulseReason == DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP;
|
||||
if (mDozeParameters.getAlwaysOn()) {
|
||||
mStackScroller.setAlpha(1f);
|
||||
}
|
||||
startScrimAnimation(true /* inFront */, 0f,
|
||||
mDozeParameters.getPulseInDuration(pickupOrDoubleTap),
|
||||
pickupOrDoubleTap ? Interpolators.LINEAR_OUT_SLOW_IN : Interpolators.ALPHA_OUT,
|
||||
@@ -245,6 +262,10 @@ public class DozeScrimController {
|
||||
|
||||
// Signal that the pulse is ready to turn the screen on and draw.
|
||||
pulseStarted();
|
||||
|
||||
if (mDozeParameters.getAlwaysOn()) {
|
||||
mHandler.post(DozeScrimController.this::onScreenTurnedOn);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -262,7 +283,8 @@ public class DozeScrimController {
|
||||
public void run() {
|
||||
if (DEBUG) Log.d(TAG, "Pulse out, mDozing=" + mDozing);
|
||||
if (!mDozing) return;
|
||||
startScrimAnimation(true /* inFront */, 1f, mDozeParameters.getPulseOutDuration(),
|
||||
startScrimAnimation(true /* inFront */, mDozeParameters.getAlwaysOn() ? 0 : 1,
|
||||
mDozeParameters.getPulseOutDuration(),
|
||||
Interpolators.ALPHA_IN, mPulseOutFinished);
|
||||
}
|
||||
};
|
||||
@@ -271,6 +293,9 @@ public class DozeScrimController {
|
||||
@Override
|
||||
public void run() {
|
||||
if (DEBUG) Log.d(TAG, "Pulse out finished");
|
||||
if (mDozeParameters.getAlwaysOn()) {
|
||||
mStackScroller.setAlpha(0f);
|
||||
}
|
||||
DozeLog.tracePulseFinish();
|
||||
|
||||
// Signal that the pulse is all finished so we can turn the screen off now.
|
||||
|
||||
@@ -123,6 +123,7 @@ import com.android.internal.logging.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.statusbar.NotificationVisibility;
|
||||
import com.android.internal.statusbar.StatusBarIcon;
|
||||
import com.android.keyguard.KeyguardHostView.OnDismissAction;
|
||||
import com.android.keyguard.KeyguardStatusView;
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
||||
import com.android.keyguard.ViewMediatorCallback;
|
||||
@@ -367,7 +368,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
// top bar
|
||||
BaseStatusBarHeader mHeader;
|
||||
protected KeyguardStatusBarView mKeyguardStatusBar;
|
||||
View mKeyguardStatusView;
|
||||
KeyguardStatusView mKeyguardStatusView;
|
||||
KeyguardBottomAreaView mKeyguardBottomArea;
|
||||
boolean mLeaveOpenOnKeyguardHide;
|
||||
KeyguardIndicationController mKeyguardIndicationController;
|
||||
@@ -846,10 +847,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
mHeadsUpManager.addListener(mScrimController);
|
||||
mStackScroller.setScrimController(mScrimController);
|
||||
mStatusBarView.setScrimController(mScrimController);
|
||||
mDozeScrimController = new DozeScrimController(mScrimController, context);
|
||||
mDozeScrimController = new DozeScrimController(mScrimController, context, mStackScroller);
|
||||
|
||||
mKeyguardStatusBar = (KeyguardStatusBarView) mStatusBarWindow.findViewById(R.id.keyguard_header);
|
||||
mKeyguardStatusView = mStatusBarWindow.findViewById(R.id.keyguard_status_view);
|
||||
mKeyguardStatusView =
|
||||
(KeyguardStatusView) mStatusBarWindow.findViewById(R.id.keyguard_status_view);
|
||||
mKeyguardBottomArea =
|
||||
(KeyguardBottomAreaView) mStatusBarWindow.findViewById(R.id.keyguard_bottom_area);
|
||||
mKeyguardBottomArea.setActivityStarter(this);
|
||||
@@ -2695,6 +2697,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
mFalsingManager.onScreenOff();
|
||||
}
|
||||
|
||||
public boolean isPulsing() {
|
||||
return mDozeScrimController.isPulsing();
|
||||
}
|
||||
|
||||
/**
|
||||
* All changes to the status bar and notifications funnel through here and are batched.
|
||||
*/
|
||||
@@ -5134,6 +5140,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
mHandler.obtainMessage(H.MSG_STOP_DOZING).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dozeTimeTick() {
|
||||
mKeyguardStatusView.refreshTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPowerSaveActive() {
|
||||
return mBatteryController != null && mBatteryController.isPowerSave();
|
||||
|
||||
@@ -248,6 +248,10 @@ public class StatusBarWindowView extends FrameLayout {
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
if (mService.isDozing() && !mService.isPulsing()) {
|
||||
// Discard all touch events in always-on.
|
||||
return true;
|
||||
}
|
||||
boolean intercept = false;
|
||||
if (mNotificationPanel.isFullyExpanded()
|
||||
&& mStackScrollLayout.getVisibility() == View.VISIBLE
|
||||
@@ -274,6 +278,11 @@ public class StatusBarWindowView extends FrameLayout {
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
if (mService.isDozing() && !mService.isPulsing()) {
|
||||
// Discard all touch events in always-on.
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean handled = false;
|
||||
if (mService.getBarState() == StatusBarState.KEYGUARD) {
|
||||
handled = mDragDownHelper.onTouchEvent(ev);
|
||||
|
||||
Reference in New Issue
Block a user