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) { 451998ee56285419ff7fea0ec9a247e31d1d27a0abJulia Reynolds if (mSchedule.exitAtAlarm && now > mSchedule.nextAlarm) { 461998ee56285419ff7fea0ec9a247e31d1d27a0abJulia Reynolds mSchedule.nextAlarm = nextAlarm; 47530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 48530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 49530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 50530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock 51530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock public void setTimeZone(TimeZone tz) { 52530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock mCalendar.setTimeZone(tz); 53530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 54530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock 55b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock public long getNextChangeTime(long now) { 56b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock if (mSchedule == null) return 0; 57b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock final long nextStart = getNextTime(now, mSchedule.startHour, mSchedule.startMinute); 58b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock final long nextEnd = getNextTime(now, mSchedule.endHour, mSchedule.endMinute); 591998ee56285419ff7fea0ec9a247e31d1d27a0abJulia Reynolds long nextScheduleTime = Math.min(nextStart, nextEnd); 601998ee56285419ff7fea0ec9a247e31d1d27a0abJulia Reynolds 619eb2c1e85cd5def851ebe833a7f56a49f00e448fJulia Reynolds return nextScheduleTime; 62b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock } 63b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock 64b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock private long getNextTime(long now, int hr, int min) { 65530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock final long time = getTime(now, hr, min); 66530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock return time <= now ? addDays(time, 1) : time; 67530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 68530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock 69530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock private long getTime(long millis, int hour, int min) { 70530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock mCalendar.setTimeInMillis(millis); 71530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock mCalendar.set(Calendar.HOUR_OF_DAY, hour); 72530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock mCalendar.set(Calendar.MINUTE, min); 73530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock mCalendar.set(Calendar.SECOND, 0); 74530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock mCalendar.set(Calendar.MILLISECOND, 0); 75530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock return mCalendar.getTimeInMillis(); 76530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 77530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock 78b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock public boolean isInSchedule(long time) { 79b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock if (mSchedule == null || mDays.size() == 0) return false; 80b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock final long start = getTime(time, mSchedule.startHour, mSchedule.startMinute); 81b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock long end = getTime(time, mSchedule.endHour, mSchedule.endMinute); 82530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock if (end <= start) { 83530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock end = addDays(end, 1); 84530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 851998ee56285419ff7fea0ec9a247e31d1d27a0abJulia Reynolds boolean isInSchedule = 861998ee56285419ff7fea0ec9a247e31d1d27a0abJulia Reynolds isInSchedule(-1, time, start, end) || isInSchedule(0, time, start, end); 871998ee56285419ff7fea0ec9a247e31d1d27a0abJulia Reynolds if (isInSchedule && mSchedule.exitAtAlarm 881998ee56285419ff7fea0ec9a247e31d1d27a0abJulia Reynolds && mSchedule.nextAlarm != 0 891998ee56285419ff7fea0ec9a247e31d1d27a0abJulia Reynolds && time >= mSchedule.nextAlarm) { 901998ee56285419ff7fea0ec9a247e31d1d27a0abJulia Reynolds return false; 911998ee56285419ff7fea0ec9a247e31d1d27a0abJulia Reynolds } else { 921998ee56285419ff7fea0ec9a247e31d1d27a0abJulia Reynolds return isInSchedule; 931998ee56285419ff7fea0ec9a247e31d1d27a0abJulia Reynolds } 94530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 95530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock 96b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock private boolean isInSchedule(int daysOffset, long time, long start, long end) { 97530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock final int n = Calendar.SATURDAY; 98530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock final int day = ((getDayOfWeek(time) - 1) + (daysOffset % n) + n) % n + 1; 99530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock start = addDays(start, daysOffset); 100530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock end = addDays(end, daysOffset); 101530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock return mDays.contains(day) && time >= start && time < end; 102530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 103530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock 104530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock private int getDayOfWeek(long time) { 105530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock mCalendar.setTimeInMillis(time); 106530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock return mCalendar.get(Calendar.DAY_OF_WEEK); 107530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 108530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock 109530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock private void updateDays() { 110530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock mDays.clear(); 111b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock if (mSchedule != null && mSchedule.days != null) { 112b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock for (int i = 0; i < mSchedule.days.length; i++) { 113b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06John Spurlock mDays.add(mSchedule.days[i]); 114530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 115530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 116530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 117530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock 118530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock private long addDays(long time, int days) { 119530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock mCalendar.setTimeInMillis(time); 120530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock mCalendar.add(Calendar.DATE, days); 121530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock return mCalendar.getTimeInMillis(); 122530052a2fe3b6a6a4246ce28ab0ced647fe7f470John Spurlock } 1239eb2c1e85cd5def851ebe833a7f56a49f00e448fJulia Reynolds} 124