From fe54aa00e22c3542b25d7476b44adc5548169688 Mon Sep 17 00:00:00 2001 From: Adrian Roos Date: Mon, 7 Nov 2016 14:14:25 -0800 Subject: [PATCH] AOD: Fix AoD time tick after refactor Test: Turn on AoD, check if time keeps updating after a minute Bug: 30876804 Fixed: 34985073 Change-Id: I7d5ce01b4f04e1a1a89b62ba321215b44f54de7b --- .../android/systemui/doze/DozeFactory.java | 11 ++- .../src/com/android/systemui/doze/DozeUi.java | 74 ++++++++++++++++++- 2 files changed, 75 insertions(+), 10 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java index aa226181d7136..7c15096a5f9ab 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java @@ -16,6 +16,7 @@ package com.android.systemui.doze; +import android.app.AlarmManager; import android.app.Application; import android.app.PendingIntent; import android.content.Context; @@ -25,10 +26,7 @@ import android.os.PowerManager; import android.os.SystemClock; import com.android.internal.hardware.AmbientDisplayConfiguration; -import com.android.systemui.SystemUI; import com.android.systemui.SystemUIApplication; -import com.android.systemui.plugins.PluginListener; -import com.android.systemui.plugins.PluginManager; import com.android.systemui.plugins.doze.DozeProvider; import com.android.systemui.statusbar.phone.DozeParameters; @@ -45,6 +43,7 @@ public class DozeFactory { Context context = dozeService; SensorManager sensorManager = context.getSystemService(SensorManager.class); PowerManager powerManager = context.getSystemService(PowerManager.class); + AlarmManager alarmManager = context.getSystemService(AlarmManager.class); DozeHost host = getHost(dozeService); AmbientDisplayConfiguration config = new AmbientDisplayConfiguration(context); @@ -57,7 +56,7 @@ public class DozeFactory { machine.setParts(new DozeMachine.Part[]{ createDozeTriggers(context, sensorManager, host, config, params, handler, wakeLock, machine), - createDozeUi(context, host, wakeLock, machine), + createDozeUi(context, host, wakeLock, machine, handler, alarmManager), }); return machine; @@ -72,7 +71,7 @@ public class DozeFactory { } private DozeMachine.Part createDozeUi(Context context, DozeHost host, WakeLock wakeLock, - DozeMachine machine) { + DozeMachine machine, Handler handler, AlarmManager alarmManager) { if (mDozePlugin != null) { DozeProvider.DozeUi dozeUi = mDozePlugin.provideDozeUi(context, pluginMachine(context, machine, host), @@ -82,7 +81,7 @@ public class DozeFactory { pluginState(newState)); }; } else { - return new DozeUi(context, machine, wakeLock, host); + return new DozeUi(context, alarmManager, machine, wakeLock, host, handler); } } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java index 95e49cea62f21..76e0283b0456d 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java @@ -16,7 +16,13 @@ package com.android.systemui.doze; +import android.app.AlarmManager; import android.content.Context; +import android.os.Handler; +import android.os.SystemClock; + +import java.util.Calendar; +import java.util.GregorianCalendar; /** * The policy controlling doze. @@ -24,16 +30,25 @@ import android.content.Context; public class DozeUi implements DozeMachine.Part { private final Context mContext; + private final AlarmManager mAlarmManager; private final DozeHost mHost; - private DozeFactory.WakeLock mWakeLock; - private DozeMachine mMachine; + private final Handler mHandler; + private final DozeFactory.WakeLock mWakeLock; + private final DozeMachine mMachine; + private final AlarmManager.OnAlarmListener mTimeTick; - public DozeUi(Context context, DozeMachine machine, DozeFactory.WakeLock wakeLock, - DozeHost host) { + private boolean mTimeTickScheduled = false; + + public DozeUi(Context context, AlarmManager alarmManager, DozeMachine machine, + DozeFactory.WakeLock wakeLock, DozeHost host, Handler handler) { mContext = context; + mAlarmManager = alarmManager; mMachine = machine; mWakeLock = wakeLock; mHost = host; + mHandler = handler; + + mTimeTick = this::onTimeTick; } private void pulseWhileDozing(int reason) { @@ -54,6 +69,12 @@ public class DozeUi implements DozeMachine.Part { @Override public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) { switch (newState) { + case DOZE_AOD: + scheduleTimeTick(); + break; + case DOZE: + unscheduleTimeTick(); + break; case DOZE_REQUEST_PULSE: pulseWhileDozing(DozeLog.PULSE_REASON_NOTIFICATION /* TODO */); break; @@ -62,7 +83,52 @@ public class DozeUi implements DozeMachine.Part { break; case FINISH: mHost.stopDozing(); + unscheduleTimeTick(); break; } } + + private void scheduleTimeTick() { + if (mTimeTickScheduled) { + return; + } + + long delta = roundToNextMinute(System.currentTimeMillis()) - System.currentTimeMillis(); + mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, + SystemClock.elapsedRealtime() + delta, "doze_time_tick", mTimeTick, mHandler); + + mTimeTickScheduled = true; + } + + private void unscheduleTimeTick() { + if (!mTimeTickScheduled) { + return; + } + mAlarmManager.cancel(mTimeTick); + } + + private long roundToNextMinute(long timeInMillis) { + Calendar calendar = GregorianCalendar.getInstance(); + calendar.setTimeInMillis(timeInMillis); + calendar.set(Calendar.MILLISECOND, 0); + calendar.set(Calendar.SECOND, 0); + calendar.add(Calendar.MINUTE, 1); + + return calendar.getTimeInMillis(); + } + + private void onTimeTick() { + if (!mTimeTickScheduled) { + // Alarm was canceled, but we still got the callback. Ignore. + return; + } + + mHost.dozeTimeTick(); + + // Keep wakelock until a frame has been pushed. + mHandler.post(mWakeLock.wrap(() -> {})); + + mTimeTickScheduled = false; + scheduleTimeTick(); + } }