diff options
9 files changed, 121 insertions, 13 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 03e0ebf32b70..68b7b3a50514 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -6001,6 +6001,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 */ diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 1b7a92294486..d8c8b82eee4a 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -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> diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml index 46a9ee312b60..942f8472b7ef 100644 --- a/packages/SystemUI/res/xml/tuner_prefs.xml +++ b/packages/SystemUI/res/xml/tuner_prefs.xml @@ -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" diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java index 82a1bfe172ec..02a98b0df7fc 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java @@ -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(); diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java index 8789845cb56b..cbaf232216a0 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java @@ -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() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java index 9e9bdd7a172e..0e074c7b8710 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java @@ -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)); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java index b44f5f7e237a..b141454df8e8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java @@ -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. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 28e5f7ef075a..0ef268743afe 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -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. */ @@ -5135,6 +5141,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @Override + public void dozeTimeTick() { + mKeyguardStatusView.refreshTime(); + } + + @Override public boolean isPowerSaveActive() { return mBatteryController != null && mBatteryController.isPowerSave(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java index 4425c5e6c69c..5696123dd756 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java @@ -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); |