Loading config/compiled-classes-phone +0 −1 Original line number Original line Diff line number Diff line Loading @@ -5243,7 +5243,6 @@ com.android.internal.app.IVoiceInteractor com.android.internal.app.IVoiceInteractor$Stub com.android.internal.app.IVoiceInteractor$Stub com.android.internal.app.NightDisplayController com.android.internal.app.NightDisplayController com.android.internal.app.NightDisplayController$Callback com.android.internal.app.NightDisplayController$Callback com.android.internal.app.NightDisplayController$LocalTime com.android.internal.app.ProcessMap com.android.internal.app.ProcessMap com.android.internal.app.ResolverActivity com.android.internal.app.ResolverActivity com.android.internal.app.ToolbarActionBar com.android.internal.app.ToolbarActionBar Loading config/preloaded-classes +0 −1 Original line number Original line Diff line number Diff line Loading @@ -2784,7 +2784,6 @@ com.android.internal.app.IVoiceInteractionManagerService$Stub com.android.internal.app.IVoiceInteractor com.android.internal.app.IVoiceInteractor com.android.internal.app.IVoiceInteractor$Stub com.android.internal.app.IVoiceInteractor$Stub com.android.internal.app.NightDisplayController com.android.internal.app.NightDisplayController com.android.internal.app.NightDisplayController$1 com.android.internal.appwidget.IAppWidgetService com.android.internal.appwidget.IAppWidgetService com.android.internal.appwidget.IAppWidgetService$Stub com.android.internal.appwidget.IAppWidgetService$Stub com.android.internal.appwidget.IAppWidgetService$Stub$Proxy com.android.internal.appwidget.IAppWidgetService$Stub$Proxy Loading core/java/android/provider/Settings.java +3 −2 Original line number Original line Diff line number Diff line Loading @@ -6931,8 +6931,9 @@ public final class Settings { public static final String NIGHT_DISPLAY_CUSTOM_END_TIME = "night_display_custom_end_time"; public static final String NIGHT_DISPLAY_CUSTOM_END_TIME = "night_display_custom_end_time"; /** /** * Time in milliseconds (since epoch) when Night display was last activated. Use to decide * A String representing the LocalDateTime when Night display was last activated. Use to * whether to apply the current activated state after a reboot or user change. * decide whether to apply the current activated state after a reboot or user change. In * legacy cases, this is represented by the time in milliseconds (since epoch). * @hide * @hide */ */ public static final String NIGHT_DISPLAY_LAST_ACTIVATED_TIME = public static final String NIGHT_DISPLAY_LAST_ACTIVATED_TIME = Loading core/java/com/android/internal/app/NightDisplayController.java +31 −119 Original line number Original line Diff line number Diff line Loading @@ -32,8 +32,12 @@ import com.android.internal.R; import java.lang.annotation.Retention; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy; import java.util.Calendar; import java.time.DateTimeException; import java.util.Locale; import java.time.Instant; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZoneId; import java.time.format.DateTimeParseException; /** /** * Controller for managing Night display settings. * Controller for managing Night display settings. Loading Loading @@ -116,8 +120,9 @@ public final class NightDisplayController { */ */ public boolean setActivated(boolean activated) { public boolean setActivated(boolean activated) { if (isActivated() != activated) { if (isActivated() != activated) { Secure.putLongForUser(mContext.getContentResolver(), Secure.putStringForUser(mContext.getContentResolver(), Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, System.currentTimeMillis(), Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, LocalDateTime.now().toString(), mUserId); mUserId); } } return Secure.putIntForUser(mContext.getContentResolver(), return Secure.putIntForUser(mContext.getContentResolver(), Loading @@ -128,17 +133,22 @@ public final class NightDisplayController { * Returns the time when Night display's activation state last changed, or {@code null} if it * Returns the time when Night display's activation state last changed, or {@code null} if it * has never been changed. * has never been changed. */ */ public Calendar getLastActivatedTime() { public LocalDateTime getLastActivatedTime() { final ContentResolver cr = mContext.getContentResolver(); final ContentResolver cr = mContext.getContentResolver(); final long lastActivatedTimeMillis = Secure.getLongForUser( final String lastActivatedTime = Secure.getStringForUser( cr, Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, -1, mUserId); cr, Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, mUserId); if (lastActivatedTimeMillis < 0) { if (lastActivatedTime != null) { return null; try { return LocalDateTime.parse(lastActivatedTime); } catch (DateTimeParseException ignored) {} // Uses the old epoch time. try { return LocalDateTime.ofInstant( Instant.ofEpochMilli(Long.parseLong(lastActivatedTime)), ZoneId.systemDefault()); } catch (DateTimeException|NumberFormatException ignored) {} } } return null; final Calendar lastActivatedTime = Calendar.getInstance(); lastActivatedTime.setTimeInMillis(lastActivatedTimeMillis); return lastActivatedTime; } } /** /** Loading Loading @@ -183,8 +193,10 @@ public final class NightDisplayController { } } if (getAutoMode() != autoMode) { if (getAutoMode() != autoMode) { Secure.putLongForUser(mContext.getContentResolver(), Secure.putStringForUser(mContext.getContentResolver(), Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, -1L, mUserId); Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, null, mUserId); } } return Secure.putIntForUser(mContext.getContentResolver(), return Secure.putIntForUser(mContext.getContentResolver(), Secure.NIGHT_DISPLAY_AUTO_MODE, autoMode, mUserId); Secure.NIGHT_DISPLAY_AUTO_MODE, autoMode, mUserId); Loading @@ -206,7 +218,7 @@ public final class NightDisplayController { R.integer.config_defaultNightDisplayCustomStartTime); R.integer.config_defaultNightDisplayCustomStartTime); } } return LocalTime.valueOf(startTimeValue); return LocalTime.ofSecondOfDay(startTimeValue / 1000); } } /** /** Loading @@ -221,7 +233,7 @@ public final class NightDisplayController { throw new IllegalArgumentException("startTime cannot be null"); throw new IllegalArgumentException("startTime cannot be null"); } } return Secure.putIntForUser(mContext.getContentResolver(), return Secure.putIntForUser(mContext.getContentResolver(), Secure.NIGHT_DISPLAY_CUSTOM_START_TIME, startTime.toMillis(), mUserId); Secure.NIGHT_DISPLAY_CUSTOM_START_TIME, startTime.toSecondOfDay() * 1000, mUserId); } } /** /** Loading @@ -240,7 +252,7 @@ public final class NightDisplayController { R.integer.config_defaultNightDisplayCustomEndTime); R.integer.config_defaultNightDisplayCustomEndTime); } } return LocalTime.valueOf(endTimeValue); return LocalTime.ofSecondOfDay(endTimeValue / 1000); } } /** /** Loading @@ -255,7 +267,7 @@ public final class NightDisplayController { throw new IllegalArgumentException("endTime cannot be null"); throw new IllegalArgumentException("endTime cannot be null"); } } return Secure.putIntForUser(mContext.getContentResolver(), return Secure.putIntForUser(mContext.getContentResolver(), Secure.NIGHT_DISPLAY_CUSTOM_END_TIME, endTime.toMillis(), mUserId); Secure.NIGHT_DISPLAY_CUSTOM_END_TIME, endTime.toSecondOfDay() * 1000, mUserId); } } /** /** Loading Loading @@ -378,106 +390,6 @@ public final class NightDisplayController { return context.getResources().getBoolean(R.bool.config_nightDisplayAvailable); return context.getResources().getBoolean(R.bool.config_nightDisplayAvailable); } } /** * A time without a time-zone or date. */ public static class LocalTime { /** * The hour of the day from 0 - 23. */ public final int hourOfDay; /** * The minute within the hour from 0 - 59. */ public final int minute; public LocalTime(int hourOfDay, int minute) { if (hourOfDay < 0 || hourOfDay > 23) { throw new IllegalArgumentException("Invalid hourOfDay: " + hourOfDay); } else if (minute < 0 || minute > 59) { throw new IllegalArgumentException("Invalid minute: " + minute); } this.hourOfDay = hourOfDay; this.minute = minute; } /** * Returns the first date time corresponding to this local time that occurs before the * provided date time. * * @param time the date time to compare against * @return the prior date time corresponding to this local time */ public Calendar getDateTimeBefore(Calendar time) { final Calendar c = Calendar.getInstance(); c.set(Calendar.YEAR, time.get(Calendar.YEAR)); c.set(Calendar.DAY_OF_YEAR, time.get(Calendar.DAY_OF_YEAR)); c.set(Calendar.HOUR_OF_DAY, hourOfDay); c.set(Calendar.MINUTE, minute); c.set(Calendar.SECOND, 0); c.set(Calendar.MILLISECOND, 0); // Check if the local time has past, if so return the same time tomorrow. if (c.after(time)) { c.add(Calendar.DATE, -1); } return c; } /** * Returns the first date time corresponding to this local time that occurs after the * provided date time. * * @param time the date time to compare against * @return the next date time corresponding to this local time */ public Calendar getDateTimeAfter(Calendar time) { final Calendar c = Calendar.getInstance(); c.set(Calendar.YEAR, time.get(Calendar.YEAR)); c.set(Calendar.DAY_OF_YEAR, time.get(Calendar.DAY_OF_YEAR)); c.set(Calendar.HOUR_OF_DAY, hourOfDay); c.set(Calendar.MINUTE, minute); c.set(Calendar.SECOND, 0); c.set(Calendar.MILLISECOND, 0); // Check if the local time has past, if so return the same time tomorrow. if (c.before(time)) { c.add(Calendar.DATE, 1); } return c; } /** * Returns a local time corresponding the given number of milliseconds from midnight. * * @param millis the number of milliseconds from midnight * @return the corresponding local time */ private static LocalTime valueOf(int millis) { final int hourOfDay = (millis / 3600000) % 24; final int minutes = (millis / 60000) % 60; return new LocalTime(hourOfDay, minutes); } /** * Returns the local time represented as milliseconds from midnight. */ private int toMillis() { return hourOfDay * 3600000 + minute * 60000; } @Override public String toString() { return String.format(Locale.US, "%02d:%02d", hourOfDay, minute); } } /** /** * Callback invoked whenever the Night display settings are changed. * Callback invoked whenever the Night display settings are changed. */ */ Loading services/core/java/com/android/server/display/NightDisplayService.java +59 −42 Original line number Original line Diff line number Diff line Loading @@ -48,8 +48,10 @@ import com.android.server.twilight.TwilightListener; import com.android.server.twilight.TwilightManager; import com.android.server.twilight.TwilightManager; import com.android.server.twilight.TwilightState; import com.android.server.twilight.TwilightState; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZoneId; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean; import java.util.Calendar; import java.util.TimeZone; import java.util.TimeZone; import com.android.internal.R; import com.android.internal.R; Loading Loading @@ -308,7 +310,7 @@ public final class NightDisplayService extends SystemService } } @Override @Override public void onCustomStartTimeChanged(NightDisplayController.LocalTime startTime) { public void onCustomStartTimeChanged(LocalTime startTime) { Slog.d(TAG, "onCustomStartTimeChanged: startTime=" + startTime); Slog.d(TAG, "onCustomStartTimeChanged: startTime=" + startTime); if (mAutoMode != null) { if (mAutoMode != null) { Loading @@ -317,7 +319,7 @@ public final class NightDisplayService extends SystemService } } @Override @Override public void onCustomEndTimeChanged(NightDisplayController.LocalTime endTime) { public void onCustomEndTimeChanged(LocalTime endTime) { Slog.d(TAG, "onCustomEndTimeChanged: endTime=" + endTime); Slog.d(TAG, "onCustomEndTimeChanged: endTime=" + endTime); if (mAutoMode != null) { if (mAutoMode != null) { Loading Loading @@ -416,6 +418,36 @@ public final class NightDisplayService extends SystemService outTemp[10] = blue; outTemp[10] = blue; } } /** * Returns the first date time corresponding to the local time that occurs before the * provided date time. * * @param compareTime the LocalDateTime to compare against * @return the prior LocalDateTime corresponding to this local time */ public static LocalDateTime getDateTimeBefore(LocalTime localTime, LocalDateTime compareTime) { final LocalDateTime ldt = LocalDateTime.of(compareTime.getYear(), compareTime.getMonth(), compareTime.getDayOfMonth(), localTime.getHour(), localTime.getMinute()); // Check if the local time has passed, if so return the same time yesterday. return ldt.isAfter(compareTime) ? ldt.minusDays(1) : ldt; } /** * Returns the first date time corresponding to this local time that occurs after the * provided date time. * * @param compareTime the LocalDateTime to compare against * @return the next LocalDateTime corresponding to this local time */ public static LocalDateTime getDateTimeAfter(LocalTime localTime, LocalDateTime compareTime) { final LocalDateTime ldt = LocalDateTime.of(compareTime.getYear(), compareTime.getMonth(), compareTime.getDayOfMonth(), localTime.getHour(), localTime.getMinute()); // Check if the local time has passed, if so return the same time tomorrow. return ldt.isBefore(compareTime) ? ldt.plusDays(1) : ldt; } private abstract class AutoMode implements NightDisplayController.Callback { private abstract class AutoMode implements NightDisplayController.Callback { public abstract void onStart(); public abstract void onStart(); Loading @@ -427,10 +459,10 @@ public final class NightDisplayService extends SystemService private final AlarmManager mAlarmManager; private final AlarmManager mAlarmManager; private final BroadcastReceiver mTimeChangedReceiver; private final BroadcastReceiver mTimeChangedReceiver; private NightDisplayController.LocalTime mStartTime; private LocalTime mStartTime; private NightDisplayController.LocalTime mEndTime; private LocalTime mEndTime; private Calendar mLastActivatedTime; private LocalDateTime mLastActivatedTime; CustomAutoMode() { CustomAutoMode() { mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE); mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE); Loading @@ -443,31 +475,15 @@ public final class NightDisplayService extends SystemService } } private void updateActivated() { private void updateActivated() { final Calendar now = Calendar.getInstance(); final LocalDateTime now = LocalDateTime.now(); final Calendar startTime = mStartTime.getDateTimeBefore(now); final LocalDateTime start = getDateTimeBefore(mStartTime, now); final Calendar endTime = mEndTime.getDateTimeAfter(startTime); final LocalDateTime end = getDateTimeAfter(mEndTime, start); boolean activate = now.isBefore(end); boolean activate = now.before(endTime); if (mLastActivatedTime != null) { if (mLastActivatedTime != null) { // Convert mLastActivatedTime to the current timezone if needed. final TimeZone currentTimeZone = now.getTimeZone(); if (!currentTimeZone.equals(mLastActivatedTime.getTimeZone())) { final int year = mLastActivatedTime.get(Calendar.YEAR); final int dayOfYear = mLastActivatedTime.get(Calendar.DAY_OF_YEAR); final int hourOfDay = mLastActivatedTime.get(Calendar.HOUR_OF_DAY); final int minute = mLastActivatedTime.get(Calendar.MINUTE); mLastActivatedTime.setTimeZone(currentTimeZone); mLastActivatedTime.set(Calendar.YEAR, year); mLastActivatedTime.set(Calendar.DAY_OF_YEAR, dayOfYear); mLastActivatedTime.set(Calendar.HOUR_OF_DAY, hourOfDay); mLastActivatedTime.set(Calendar.MINUTE, minute); } // Maintain the existing activated state if within the current period. // Maintain the existing activated state if within the current period. if (mLastActivatedTime.before(now) if (mLastActivatedTime.isBefore(now) && mLastActivatedTime.isAfter(start) && mLastActivatedTime.after(startTime) && (mLastActivatedTime.isAfter(end) || now.isBefore(end))) { && (mLastActivatedTime.after(endTime) || now.before(endTime))) { activate = mController.isActivated(); activate = mController.isActivated(); } } } } Loading @@ -475,14 +491,16 @@ public final class NightDisplayService extends SystemService if (mIsActivated == null || mIsActivated != activate) { if (mIsActivated == null || mIsActivated != activate) { mController.setActivated(activate); mController.setActivated(activate); } } updateNextAlarm(mIsActivated, now); updateNextAlarm(mIsActivated, now); } } private void updateNextAlarm(@Nullable Boolean activated, @NonNull Calendar now) { private void updateNextAlarm(@Nullable Boolean activated, @NonNull LocalDateTime now) { if (activated != null) { if (activated != null) { final Calendar next = activated ? mEndTime.getDateTimeAfter(now) final LocalDateTime next = activated ? getDateTimeAfter(mEndTime, now) : mStartTime.getDateTimeAfter(now); : getDateTimeAfter(mStartTime, now); mAlarmManager.setExact(AlarmManager.RTC, next.getTimeInMillis(), TAG, this, null); final long millis = next.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); mAlarmManager.setExact(AlarmManager.RTC, millis, TAG, this, null); } } } } Loading Loading @@ -512,18 +530,18 @@ public final class NightDisplayService extends SystemService @Override @Override public void onActivated(boolean activated) { public void onActivated(boolean activated) { mLastActivatedTime = mController.getLastActivatedTime(); mLastActivatedTime = mController.getLastActivatedTime(); updateNextAlarm(activated, Calendar.getInstance()); updateNextAlarm(activated, LocalDateTime.now()); } } @Override @Override public void onCustomStartTimeChanged(NightDisplayController.LocalTime startTime) { public void onCustomStartTimeChanged(LocalTime startTime) { mStartTime = startTime; mStartTime = startTime; mLastActivatedTime = null; mLastActivatedTime = null; updateActivated(); updateActivated(); } } @Override @Override public void onCustomEndTimeChanged(NightDisplayController.LocalTime endTime) { public void onCustomEndTimeChanged(LocalTime endTime) { mEndTime = endTime; mEndTime = endTime; mLastActivatedTime = null; mLastActivatedTime = null; updateActivated(); updateActivated(); Loading Loading @@ -552,15 +570,14 @@ public final class NightDisplayService extends SystemService } } boolean activate = state.isNight(); boolean activate = state.isNight(); final Calendar lastActivatedTime = mController.getLastActivatedTime(); final LocalDateTime lastActivatedTime = mController.getLastActivatedTime(); if (lastActivatedTime != null) { if (lastActivatedTime != null) { final Calendar now = Calendar.getInstance(); final LocalDateTime now = LocalDateTime.now(); final Calendar sunrise = state.sunrise(); final LocalDateTime sunrise = state.sunrise(); final Calendar sunset = state.sunset(); final LocalDateTime sunset = state.sunset(); // Maintain the existing activated state if within the current period. // Maintain the existing activated state if within the current period. if (lastActivatedTime.before(now) if (lastActivatedTime.isBefore(now) && (lastActivatedTime.isBefore(sunrise) && (lastActivatedTime.after(sunrise) ^ lastActivatedTime.after(sunset))) { ^ lastActivatedTime.isBefore(sunset))) { activate = mController.isActivated(); activate = mController.isActivated(); } } } } Loading Loading
config/compiled-classes-phone +0 −1 Original line number Original line Diff line number Diff line Loading @@ -5243,7 +5243,6 @@ com.android.internal.app.IVoiceInteractor com.android.internal.app.IVoiceInteractor$Stub com.android.internal.app.IVoiceInteractor$Stub com.android.internal.app.NightDisplayController com.android.internal.app.NightDisplayController com.android.internal.app.NightDisplayController$Callback com.android.internal.app.NightDisplayController$Callback com.android.internal.app.NightDisplayController$LocalTime com.android.internal.app.ProcessMap com.android.internal.app.ProcessMap com.android.internal.app.ResolverActivity com.android.internal.app.ResolverActivity com.android.internal.app.ToolbarActionBar com.android.internal.app.ToolbarActionBar Loading
config/preloaded-classes +0 −1 Original line number Original line Diff line number Diff line Loading @@ -2784,7 +2784,6 @@ com.android.internal.app.IVoiceInteractionManagerService$Stub com.android.internal.app.IVoiceInteractor com.android.internal.app.IVoiceInteractor com.android.internal.app.IVoiceInteractor$Stub com.android.internal.app.IVoiceInteractor$Stub com.android.internal.app.NightDisplayController com.android.internal.app.NightDisplayController com.android.internal.app.NightDisplayController$1 com.android.internal.appwidget.IAppWidgetService com.android.internal.appwidget.IAppWidgetService com.android.internal.appwidget.IAppWidgetService$Stub com.android.internal.appwidget.IAppWidgetService$Stub com.android.internal.appwidget.IAppWidgetService$Stub$Proxy com.android.internal.appwidget.IAppWidgetService$Stub$Proxy Loading
core/java/android/provider/Settings.java +3 −2 Original line number Original line Diff line number Diff line Loading @@ -6931,8 +6931,9 @@ public final class Settings { public static final String NIGHT_DISPLAY_CUSTOM_END_TIME = "night_display_custom_end_time"; public static final String NIGHT_DISPLAY_CUSTOM_END_TIME = "night_display_custom_end_time"; /** /** * Time in milliseconds (since epoch) when Night display was last activated. Use to decide * A String representing the LocalDateTime when Night display was last activated. Use to * whether to apply the current activated state after a reboot or user change. * decide whether to apply the current activated state after a reboot or user change. In * legacy cases, this is represented by the time in milliseconds (since epoch). * @hide * @hide */ */ public static final String NIGHT_DISPLAY_LAST_ACTIVATED_TIME = public static final String NIGHT_DISPLAY_LAST_ACTIVATED_TIME = Loading
core/java/com/android/internal/app/NightDisplayController.java +31 −119 Original line number Original line Diff line number Diff line Loading @@ -32,8 +32,12 @@ import com.android.internal.R; import java.lang.annotation.Retention; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy; import java.util.Calendar; import java.time.DateTimeException; import java.util.Locale; import java.time.Instant; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZoneId; import java.time.format.DateTimeParseException; /** /** * Controller for managing Night display settings. * Controller for managing Night display settings. Loading Loading @@ -116,8 +120,9 @@ public final class NightDisplayController { */ */ public boolean setActivated(boolean activated) { public boolean setActivated(boolean activated) { if (isActivated() != activated) { if (isActivated() != activated) { Secure.putLongForUser(mContext.getContentResolver(), Secure.putStringForUser(mContext.getContentResolver(), Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, System.currentTimeMillis(), Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, LocalDateTime.now().toString(), mUserId); mUserId); } } return Secure.putIntForUser(mContext.getContentResolver(), return Secure.putIntForUser(mContext.getContentResolver(), Loading @@ -128,17 +133,22 @@ public final class NightDisplayController { * Returns the time when Night display's activation state last changed, or {@code null} if it * Returns the time when Night display's activation state last changed, or {@code null} if it * has never been changed. * has never been changed. */ */ public Calendar getLastActivatedTime() { public LocalDateTime getLastActivatedTime() { final ContentResolver cr = mContext.getContentResolver(); final ContentResolver cr = mContext.getContentResolver(); final long lastActivatedTimeMillis = Secure.getLongForUser( final String lastActivatedTime = Secure.getStringForUser( cr, Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, -1, mUserId); cr, Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, mUserId); if (lastActivatedTimeMillis < 0) { if (lastActivatedTime != null) { return null; try { return LocalDateTime.parse(lastActivatedTime); } catch (DateTimeParseException ignored) {} // Uses the old epoch time. try { return LocalDateTime.ofInstant( Instant.ofEpochMilli(Long.parseLong(lastActivatedTime)), ZoneId.systemDefault()); } catch (DateTimeException|NumberFormatException ignored) {} } } return null; final Calendar lastActivatedTime = Calendar.getInstance(); lastActivatedTime.setTimeInMillis(lastActivatedTimeMillis); return lastActivatedTime; } } /** /** Loading Loading @@ -183,8 +193,10 @@ public final class NightDisplayController { } } if (getAutoMode() != autoMode) { if (getAutoMode() != autoMode) { Secure.putLongForUser(mContext.getContentResolver(), Secure.putStringForUser(mContext.getContentResolver(), Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, -1L, mUserId); Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, null, mUserId); } } return Secure.putIntForUser(mContext.getContentResolver(), return Secure.putIntForUser(mContext.getContentResolver(), Secure.NIGHT_DISPLAY_AUTO_MODE, autoMode, mUserId); Secure.NIGHT_DISPLAY_AUTO_MODE, autoMode, mUserId); Loading @@ -206,7 +218,7 @@ public final class NightDisplayController { R.integer.config_defaultNightDisplayCustomStartTime); R.integer.config_defaultNightDisplayCustomStartTime); } } return LocalTime.valueOf(startTimeValue); return LocalTime.ofSecondOfDay(startTimeValue / 1000); } } /** /** Loading @@ -221,7 +233,7 @@ public final class NightDisplayController { throw new IllegalArgumentException("startTime cannot be null"); throw new IllegalArgumentException("startTime cannot be null"); } } return Secure.putIntForUser(mContext.getContentResolver(), return Secure.putIntForUser(mContext.getContentResolver(), Secure.NIGHT_DISPLAY_CUSTOM_START_TIME, startTime.toMillis(), mUserId); Secure.NIGHT_DISPLAY_CUSTOM_START_TIME, startTime.toSecondOfDay() * 1000, mUserId); } } /** /** Loading @@ -240,7 +252,7 @@ public final class NightDisplayController { R.integer.config_defaultNightDisplayCustomEndTime); R.integer.config_defaultNightDisplayCustomEndTime); } } return LocalTime.valueOf(endTimeValue); return LocalTime.ofSecondOfDay(endTimeValue / 1000); } } /** /** Loading @@ -255,7 +267,7 @@ public final class NightDisplayController { throw new IllegalArgumentException("endTime cannot be null"); throw new IllegalArgumentException("endTime cannot be null"); } } return Secure.putIntForUser(mContext.getContentResolver(), return Secure.putIntForUser(mContext.getContentResolver(), Secure.NIGHT_DISPLAY_CUSTOM_END_TIME, endTime.toMillis(), mUserId); Secure.NIGHT_DISPLAY_CUSTOM_END_TIME, endTime.toSecondOfDay() * 1000, mUserId); } } /** /** Loading Loading @@ -378,106 +390,6 @@ public final class NightDisplayController { return context.getResources().getBoolean(R.bool.config_nightDisplayAvailable); return context.getResources().getBoolean(R.bool.config_nightDisplayAvailable); } } /** * A time without a time-zone or date. */ public static class LocalTime { /** * The hour of the day from 0 - 23. */ public final int hourOfDay; /** * The minute within the hour from 0 - 59. */ public final int minute; public LocalTime(int hourOfDay, int minute) { if (hourOfDay < 0 || hourOfDay > 23) { throw new IllegalArgumentException("Invalid hourOfDay: " + hourOfDay); } else if (minute < 0 || minute > 59) { throw new IllegalArgumentException("Invalid minute: " + minute); } this.hourOfDay = hourOfDay; this.minute = minute; } /** * Returns the first date time corresponding to this local time that occurs before the * provided date time. * * @param time the date time to compare against * @return the prior date time corresponding to this local time */ public Calendar getDateTimeBefore(Calendar time) { final Calendar c = Calendar.getInstance(); c.set(Calendar.YEAR, time.get(Calendar.YEAR)); c.set(Calendar.DAY_OF_YEAR, time.get(Calendar.DAY_OF_YEAR)); c.set(Calendar.HOUR_OF_DAY, hourOfDay); c.set(Calendar.MINUTE, minute); c.set(Calendar.SECOND, 0); c.set(Calendar.MILLISECOND, 0); // Check if the local time has past, if so return the same time tomorrow. if (c.after(time)) { c.add(Calendar.DATE, -1); } return c; } /** * Returns the first date time corresponding to this local time that occurs after the * provided date time. * * @param time the date time to compare against * @return the next date time corresponding to this local time */ public Calendar getDateTimeAfter(Calendar time) { final Calendar c = Calendar.getInstance(); c.set(Calendar.YEAR, time.get(Calendar.YEAR)); c.set(Calendar.DAY_OF_YEAR, time.get(Calendar.DAY_OF_YEAR)); c.set(Calendar.HOUR_OF_DAY, hourOfDay); c.set(Calendar.MINUTE, minute); c.set(Calendar.SECOND, 0); c.set(Calendar.MILLISECOND, 0); // Check if the local time has past, if so return the same time tomorrow. if (c.before(time)) { c.add(Calendar.DATE, 1); } return c; } /** * Returns a local time corresponding the given number of milliseconds from midnight. * * @param millis the number of milliseconds from midnight * @return the corresponding local time */ private static LocalTime valueOf(int millis) { final int hourOfDay = (millis / 3600000) % 24; final int minutes = (millis / 60000) % 60; return new LocalTime(hourOfDay, minutes); } /** * Returns the local time represented as milliseconds from midnight. */ private int toMillis() { return hourOfDay * 3600000 + minute * 60000; } @Override public String toString() { return String.format(Locale.US, "%02d:%02d", hourOfDay, minute); } } /** /** * Callback invoked whenever the Night display settings are changed. * Callback invoked whenever the Night display settings are changed. */ */ Loading
services/core/java/com/android/server/display/NightDisplayService.java +59 −42 Original line number Original line Diff line number Diff line Loading @@ -48,8 +48,10 @@ import com.android.server.twilight.TwilightListener; import com.android.server.twilight.TwilightManager; import com.android.server.twilight.TwilightManager; import com.android.server.twilight.TwilightState; import com.android.server.twilight.TwilightState; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZoneId; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean; import java.util.Calendar; import java.util.TimeZone; import java.util.TimeZone; import com.android.internal.R; import com.android.internal.R; Loading Loading @@ -308,7 +310,7 @@ public final class NightDisplayService extends SystemService } } @Override @Override public void onCustomStartTimeChanged(NightDisplayController.LocalTime startTime) { public void onCustomStartTimeChanged(LocalTime startTime) { Slog.d(TAG, "onCustomStartTimeChanged: startTime=" + startTime); Slog.d(TAG, "onCustomStartTimeChanged: startTime=" + startTime); if (mAutoMode != null) { if (mAutoMode != null) { Loading @@ -317,7 +319,7 @@ public final class NightDisplayService extends SystemService } } @Override @Override public void onCustomEndTimeChanged(NightDisplayController.LocalTime endTime) { public void onCustomEndTimeChanged(LocalTime endTime) { Slog.d(TAG, "onCustomEndTimeChanged: endTime=" + endTime); Slog.d(TAG, "onCustomEndTimeChanged: endTime=" + endTime); if (mAutoMode != null) { if (mAutoMode != null) { Loading Loading @@ -416,6 +418,36 @@ public final class NightDisplayService extends SystemService outTemp[10] = blue; outTemp[10] = blue; } } /** * Returns the first date time corresponding to the local time that occurs before the * provided date time. * * @param compareTime the LocalDateTime to compare against * @return the prior LocalDateTime corresponding to this local time */ public static LocalDateTime getDateTimeBefore(LocalTime localTime, LocalDateTime compareTime) { final LocalDateTime ldt = LocalDateTime.of(compareTime.getYear(), compareTime.getMonth(), compareTime.getDayOfMonth(), localTime.getHour(), localTime.getMinute()); // Check if the local time has passed, if so return the same time yesterday. return ldt.isAfter(compareTime) ? ldt.minusDays(1) : ldt; } /** * Returns the first date time corresponding to this local time that occurs after the * provided date time. * * @param compareTime the LocalDateTime to compare against * @return the next LocalDateTime corresponding to this local time */ public static LocalDateTime getDateTimeAfter(LocalTime localTime, LocalDateTime compareTime) { final LocalDateTime ldt = LocalDateTime.of(compareTime.getYear(), compareTime.getMonth(), compareTime.getDayOfMonth(), localTime.getHour(), localTime.getMinute()); // Check if the local time has passed, if so return the same time tomorrow. return ldt.isBefore(compareTime) ? ldt.plusDays(1) : ldt; } private abstract class AutoMode implements NightDisplayController.Callback { private abstract class AutoMode implements NightDisplayController.Callback { public abstract void onStart(); public abstract void onStart(); Loading @@ -427,10 +459,10 @@ public final class NightDisplayService extends SystemService private final AlarmManager mAlarmManager; private final AlarmManager mAlarmManager; private final BroadcastReceiver mTimeChangedReceiver; private final BroadcastReceiver mTimeChangedReceiver; private NightDisplayController.LocalTime mStartTime; private LocalTime mStartTime; private NightDisplayController.LocalTime mEndTime; private LocalTime mEndTime; private Calendar mLastActivatedTime; private LocalDateTime mLastActivatedTime; CustomAutoMode() { CustomAutoMode() { mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE); mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE); Loading @@ -443,31 +475,15 @@ public final class NightDisplayService extends SystemService } } private void updateActivated() { private void updateActivated() { final Calendar now = Calendar.getInstance(); final LocalDateTime now = LocalDateTime.now(); final Calendar startTime = mStartTime.getDateTimeBefore(now); final LocalDateTime start = getDateTimeBefore(mStartTime, now); final Calendar endTime = mEndTime.getDateTimeAfter(startTime); final LocalDateTime end = getDateTimeAfter(mEndTime, start); boolean activate = now.isBefore(end); boolean activate = now.before(endTime); if (mLastActivatedTime != null) { if (mLastActivatedTime != null) { // Convert mLastActivatedTime to the current timezone if needed. final TimeZone currentTimeZone = now.getTimeZone(); if (!currentTimeZone.equals(mLastActivatedTime.getTimeZone())) { final int year = mLastActivatedTime.get(Calendar.YEAR); final int dayOfYear = mLastActivatedTime.get(Calendar.DAY_OF_YEAR); final int hourOfDay = mLastActivatedTime.get(Calendar.HOUR_OF_DAY); final int minute = mLastActivatedTime.get(Calendar.MINUTE); mLastActivatedTime.setTimeZone(currentTimeZone); mLastActivatedTime.set(Calendar.YEAR, year); mLastActivatedTime.set(Calendar.DAY_OF_YEAR, dayOfYear); mLastActivatedTime.set(Calendar.HOUR_OF_DAY, hourOfDay); mLastActivatedTime.set(Calendar.MINUTE, minute); } // Maintain the existing activated state if within the current period. // Maintain the existing activated state if within the current period. if (mLastActivatedTime.before(now) if (mLastActivatedTime.isBefore(now) && mLastActivatedTime.isAfter(start) && mLastActivatedTime.after(startTime) && (mLastActivatedTime.isAfter(end) || now.isBefore(end))) { && (mLastActivatedTime.after(endTime) || now.before(endTime))) { activate = mController.isActivated(); activate = mController.isActivated(); } } } } Loading @@ -475,14 +491,16 @@ public final class NightDisplayService extends SystemService if (mIsActivated == null || mIsActivated != activate) { if (mIsActivated == null || mIsActivated != activate) { mController.setActivated(activate); mController.setActivated(activate); } } updateNextAlarm(mIsActivated, now); updateNextAlarm(mIsActivated, now); } } private void updateNextAlarm(@Nullable Boolean activated, @NonNull Calendar now) { private void updateNextAlarm(@Nullable Boolean activated, @NonNull LocalDateTime now) { if (activated != null) { if (activated != null) { final Calendar next = activated ? mEndTime.getDateTimeAfter(now) final LocalDateTime next = activated ? getDateTimeAfter(mEndTime, now) : mStartTime.getDateTimeAfter(now); : getDateTimeAfter(mStartTime, now); mAlarmManager.setExact(AlarmManager.RTC, next.getTimeInMillis(), TAG, this, null); final long millis = next.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); mAlarmManager.setExact(AlarmManager.RTC, millis, TAG, this, null); } } } } Loading Loading @@ -512,18 +530,18 @@ public final class NightDisplayService extends SystemService @Override @Override public void onActivated(boolean activated) { public void onActivated(boolean activated) { mLastActivatedTime = mController.getLastActivatedTime(); mLastActivatedTime = mController.getLastActivatedTime(); updateNextAlarm(activated, Calendar.getInstance()); updateNextAlarm(activated, LocalDateTime.now()); } } @Override @Override public void onCustomStartTimeChanged(NightDisplayController.LocalTime startTime) { public void onCustomStartTimeChanged(LocalTime startTime) { mStartTime = startTime; mStartTime = startTime; mLastActivatedTime = null; mLastActivatedTime = null; updateActivated(); updateActivated(); } } @Override @Override public void onCustomEndTimeChanged(NightDisplayController.LocalTime endTime) { public void onCustomEndTimeChanged(LocalTime endTime) { mEndTime = endTime; mEndTime = endTime; mLastActivatedTime = null; mLastActivatedTime = null; updateActivated(); updateActivated(); Loading Loading @@ -552,15 +570,14 @@ public final class NightDisplayService extends SystemService } } boolean activate = state.isNight(); boolean activate = state.isNight(); final Calendar lastActivatedTime = mController.getLastActivatedTime(); final LocalDateTime lastActivatedTime = mController.getLastActivatedTime(); if (lastActivatedTime != null) { if (lastActivatedTime != null) { final Calendar now = Calendar.getInstance(); final LocalDateTime now = LocalDateTime.now(); final Calendar sunrise = state.sunrise(); final LocalDateTime sunrise = state.sunrise(); final Calendar sunset = state.sunset(); final LocalDateTime sunset = state.sunset(); // Maintain the existing activated state if within the current period. // Maintain the existing activated state if within the current period. if (lastActivatedTime.before(now) if (lastActivatedTime.isBefore(now) && (lastActivatedTime.isBefore(sunrise) && (lastActivatedTime.after(sunrise) ^ lastActivatedTime.after(sunset))) { ^ lastActivatedTime.isBefore(sunset))) { activate = mController.isActivated(); activate = mController.isActivated(); } } } } Loading