1530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock/** 2530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock * Copyright (c) 2014, The Android Open Source Project 3530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock * 4530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock * Licensed under the Apache License, Version 2.0 (the "License"); 5530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock * you may not use this file except in compliance with the License. 6530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock * You may obtain a copy of the License at 7530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock * 8530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock * http://www.apache.org/licenses/LICENSE-2.0 9530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock * 10530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock * Unless required by applicable law or agreed to in writing, software 11530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock * distributed under the License is distributed on an "AS IS" BASIS, 12530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock * See the License for the specific language governing permissions and 14530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock * limitations under the License. 15530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock */ 16530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock 17530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlockpackage com.android.server.notification; 18530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock 19b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlockimport android.service.notification.ZenModeConfig.ScheduleInfo; 20b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlockimport android.util.ArraySet; 21b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock 22530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlockimport java.util.Calendar; 23530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlockimport java.util.Objects; 24530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlockimport java.util.TimeZone; 25530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock 26b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlockpublic class ScheduleCalendar { 27530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock private final ArraySet<Integer> mDays = new ArraySet<Integer>(); 28530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock private final Calendar mCalendar = Calendar.getInstance(); 29530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock 30b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock private ScheduleInfo mSchedule; 31530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock 32530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock @Override 33530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock public String toString() { 347f73308f50791740beb380fecc17903301054ad3Julia Reynolds return "ScheduleCalendar[mDays=" + mDays + ", mSchedule=" + mSchedule + "]"; 35530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 36530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock 37b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock public void setSchedule(ScheduleInfo schedule) { 38b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock if (Objects.equals(mSchedule, schedule)) return; 39b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock mSchedule = schedule; 40530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock updateDays(); 41530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 42530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock 431998ee56285419ff7fea0ec9a247e31d1d27a0abJulia Reynolds public void maybeSetNextAlarm(long now, long nextAlarm) { 441998ee56285419ff7fea0ec9a247e31d1d27a0abJulia Reynolds if (mSchedule != null) { 45837697a82f65e9a6865d9a37dda4ec6520d1e6ccJulia Reynolds if (mSchedule.exitAtAlarm 46837697a82f65e9a6865d9a37dda4ec6520d1e6ccJulia Reynolds && (now > mSchedule.nextAlarm || nextAlarm < mSchedule.nextAlarm)) { 471998ee56285419ff7fea0ec9a247e31d1d27a0abJulia Reynolds mSchedule.nextAlarm = nextAlarm; 48530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 49530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 50530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 51530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock 52530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock public void setTimeZone(TimeZone tz) { 53530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock mCalendar.setTimeZone(tz); 54530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 55530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock 56b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock public long getNextChangeTime(long now) { 57b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock if (mSchedule == null) return 0; 58b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock final long nextStart = getNextTime(now, mSchedule.startHour, mSchedule.startMinute); 59b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock final long nextEnd = getNextTime(now, mSchedule.endHour, mSchedule.endMinute); 601998ee56285419ff7fea0ec9a247e31d1d27a0abJulia Reynolds long nextScheduleTime = Math.min(nextStart, nextEnd); 611998ee56285419ff7fea0ec9a247e31d1d27a0abJulia Reynolds 629eb2c1e85cd5def851ebe833a7f56a49f00e448fJulia Reynolds return nextScheduleTime; 63b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock } 64b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock 65b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock private long getNextTime(long now, int hr, int min) { 66530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock final long time = getTime(now, hr, min); 67530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock return time <= now ? addDays(time, 1) : time; 68530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 69530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock 70530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock private long getTime(long millis, int hour, int min) { 71530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock mCalendar.setTimeInMillis(millis); 72530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock mCalendar.set(Calendar.HOUR_OF_DAY, hour); 73530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock mCalendar.set(Calendar.MINUTE, min); 74530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock mCalendar.set(Calendar.SECOND, 0); 75530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock mCalendar.set(Calendar.MILLISECOND, 0); 76530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock return mCalendar.getTimeInMillis(); 77530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 78530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock 79b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock public boolean isInSchedule(long time) { 80b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock if (mSchedule == null || mDays.size() == 0) return false; 81b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock final long start = getTime(time, mSchedule.startHour, mSchedule.startMinute); 82b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock long end = getTime(time, mSchedule.endHour, mSchedule.endMinute); 83530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock if (end <= start) { 84530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock end = addDays(end, 1); 85530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 86fe58f1f3862eb98837d2da6826dc17b67bf029cfJulia Reynolds return isInSchedule(-1, time, start, end) || isInSchedule(0, time, start, end); 87fe58f1f3862eb98837d2da6826dc17b67bf029cfJulia Reynolds } 88fe58f1f3862eb98837d2da6826dc17b67bf029cfJulia Reynolds 89fe58f1f3862eb98837d2da6826dc17b67bf029cfJulia Reynolds public boolean shouldExitForAlarm(long time) { 90fe58f1f3862eb98837d2da6826dc17b67bf029cfJulia Reynolds return mSchedule.exitAtAlarm 911998ee56285419ff7fea0ec9a247e31d1d27a0abJulia Reynolds && mSchedule.nextAlarm != 0 92fe58f1f3862eb98837d2da6826dc17b67bf029cfJulia Reynolds && time >= mSchedule.nextAlarm; 93530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 94530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock 95b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock private boolean isInSchedule(int daysOffset, long time, long start, long end) { 96530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock final int n = Calendar.SATURDAY; 97530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock final int day = ((getDayOfWeek(time) - 1) + (daysOffset % n) + n) % n + 1; 98530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock start = addDays(start, daysOffset); 99530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock end = addDays(end, daysOffset); 100530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock return mDays.contains(day) && time >= start && time < end; 101530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 102530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock 103530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock private int getDayOfWeek(long time) { 104530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock mCalendar.setTimeInMillis(time); 105530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock return mCalendar.get(Calendar.DAY_OF_WEEK); 106530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 107530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock 108530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock private void updateDays() { 109530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock mDays.clear(); 110b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock if (mSchedule != null && mSchedule.days != null) { 111b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock for (int i = 0; i < mSchedule.days.length; i++) { 112b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock mDays.add(mSchedule.days[i]); 113530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 114530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 115530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 116530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock 117530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock private long addDays(long time, int days) { 118530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock mCalendar.setTimeInMillis(time); 119530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock mCalendar.add(Calendar.DATE, days); 120530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock return mCalendar.getTimeInMillis(); 121530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 1229eb2c1e85cd5def851ebe833a7f56a49f00e448fJulia Reynolds} 123