1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 21c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * Timers schedule one-shot or recurring {@link TimerTask tasks} for execution. 22c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * Prefer {@link java.util.concurrent.ScheduledThreadPoolExecutor 23c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * ScheduledThreadPoolExecutor} for new code. 24f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 25c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * <p>Each timer has one thread on which tasks are executed sequentially. When 26c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * this thread is busy running a task, runnable tasks may be subject to delays. 27c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * 28c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * <p>One-shot are scheduled to run at an absolute time or after a relative 29c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * delay. 30c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * 31c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * <p>Recurring tasks are scheduled with either a fixed period or a fixed rate: 32c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * <ul> 33c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * <li>With the default <strong>fixed-period execution</strong>, each 34c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * successive run of a task is scheduled relative to the start time of 35c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * the previous run, so two runs are never fired closer together in time 36c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * than the specified {@code period}. 37c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * <li>With <strong>fixed-rate execution</strong>, the start time of each 38c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * successive run of a task is scheduled without regard for when the 39c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * previous run took place. This may result in a series of bunched-up runs 40c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * (one launched immediately after another) if delays prevent the timer 41c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * from starting tasks on time. 42c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * </ul> 43f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 44c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * <p>When a timer is no longer needed, users should call {@link #cancel}, which 45c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * releases the timer's thread and other resources. Timers not explicitly 46c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * cancelled may hold resources indefinitely. 47c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * 48c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * <p>This class does not offer guarantees about the real-time nature of task 49c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * scheduling. Multiple threads can share a single timer without 50c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * synchronization. 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class Timer { 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final class TimerImpl extends Thread { 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 56f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private static final class TimerHeap { 57f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private int DEFAULT_HEAP_SIZE = 256; 58f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 59f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private TimerTask[] timers = new TimerTask[DEFAULT_HEAP_SIZE]; 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 61f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private int size = 0; 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 63f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private int deletedCancelledNumber = 0; 64f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 65f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson public TimerTask minimum() { 66f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return timers[0]; 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 69f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson public boolean isEmpty() { 70f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return size == 0; 71f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 72f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 73f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson public void insert(TimerTask task) { 74f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (timers.length == size) { 75f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson TimerTask[] appendedTimers = new TimerTask[size * 2]; 76f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson System.arraycopy(timers, 0, appendedTimers, 0, size); 77f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson timers = appendedTimers; 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 79f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson timers[size++] = task; 80f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson upHeap(); 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 83f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson public void delete(int pos) { 84f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // posible to delete any position of the heap 85f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (pos >= 0 && pos < size) { 86f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson timers[pos] = timers[--size]; 87f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson timers[size] = null; 88f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson downHeap(pos); 89f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 90f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 92f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private void upHeap() { 93f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson int current = size - 1; 94f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson int parent = (current - 1) / 2; 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 96f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson while (timers[current].when < timers[parent].when) { 97f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // swap the two 98f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson TimerTask tmp = timers[current]; 99f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson timers[current] = timers[parent]; 100f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson timers[parent] = tmp; 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 102f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // update pos and current 103f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson current = parent; 104f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson parent = (current - 1) / 2; 105f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 108f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private void downHeap(int pos) { 109f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson int current = pos; 110f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson int child = 2 * current + 1; 111f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 112f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson while (child < size && size > 0) { 113f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // compare the children if they exist 114f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (child + 1 < size 115f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson && timers[child + 1].when < timers[child].when) { 116f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson child++; 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 118f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 119f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // compare selected child with parent 120f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (timers[current].when < timers[child].when) { 121f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson break; 122f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 123f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 124f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // swap the two 125f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson TimerTask tmp = timers[current]; 126f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson timers[current] = timers[child]; 127f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson timers[child] = tmp; 128f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 129f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // update pos and current 130f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson current = child; 131f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson child = 2 * current + 1; 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 135f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson public void reset() { 136f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson timers = new TimerTask[DEFAULT_HEAP_SIZE]; 137f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson size = 0; 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 140f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson public void adjustMinimum() { 141f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson downHeap(0); 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 144f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson public void deleteIfCancelled() { 145f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson for (int i = 0; i < size; i++) { 146f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (timers[i].cancelled) { 147f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson deletedCancelledNumber++; 148f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson delete(i); 149f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // re-try this point 150f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson i--; 151f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 155f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private int getTask(TimerTask task) { 156f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson for (int i = 0; i < timers.length; i++) { 157f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (timers[i] == task) { 158f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return i; 159f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 160f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 161f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return -1; 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 163f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * True if the method cancel() of the Timer was called or the !!!stop() 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method was invoked 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean cancelled; 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * True if the Timer has become garbage 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean finished; 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1782feeee4119506ed1511942f80fc2f7eb431afab7Elliott Hughes * Contains scheduled events, sorted according to 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code when} field of TaskScheduled object. 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 181f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private TimerHeap tasks = new TimerHeap(); 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Starts a new timer. 185f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 186a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson * @param name thread's name 187a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson * @param isDaemon daemon thread or not 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project TimerImpl(String name, boolean isDaemon) { 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.setName(name); 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.setDaemon(isDaemon); 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.start(); 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method will be launched on separate thread for each Timer 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * object. 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void run() { 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (true) { 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project TimerTask task; 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (this) { 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // need to check cancelled inside the synchronized block 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (cancelled) { 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (tasks.isEmpty()) { 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (finished) { 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // no tasks scheduled -- sleep until any task appear 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.wait(); 21555392539fea537abfb6581b474918f9d611fba27Jesse Wilson } catch (InterruptedException ignored) { 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long currentTime = System.currentTimeMillis(); 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 222f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson task = tasks.minimum(); 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long timeToSleep; 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (task.lock) { 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (task.cancelled) { 227f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson tasks.delete(0); 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // check the time to sleep for the first task scheduled 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project timeToSleep = task.when - currentTime; 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (timeToSleep > 0) { 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // sleep! 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.wait(timeToSleep); 23955392539fea537abfb6581b474918f9d611fba27Jesse Wilson } catch (InterruptedException ignored) { 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // no sleep is necessary before launching the task 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (task.lock) { 247f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson int pos = 0; 248f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (tasks.minimum().when != task.when) { 249f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson pos = tasks.getTask(task); 250f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (task.cancelled) { 252f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson tasks.delete(tasks.getTask(task)); 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // set time to schedule 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project task.setScheduledTime(task.when); 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // remove task from queue 260f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson tasks.delete(pos); 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // set when the next task should be launched 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (task.period >= 0) { 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // this is a repeating task, 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (task.fixedRate) { 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // task is scheduled at fixed rate 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project task.when = task.when + task.period; 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // task is scheduled at fixed delay 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project task.when = System.currentTimeMillis() 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project + task.period; 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // insert this task into queue 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project insertTask(task); 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project task.when = 0; 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 28255392539fea537abfb6581b474918f9d611fba27Jesse Wilson boolean taskCompletedNormally = false; 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project task.run(); 28555392539fea537abfb6581b474918f9d611fba27Jesse Wilson taskCompletedNormally = true; 28655392539fea537abfb6581b474918f9d611fba27Jesse Wilson } finally { 28755392539fea537abfb6581b474918f9d611fba27Jesse Wilson if (!taskCompletedNormally) { 28855392539fea537abfb6581b474918f9d611fba27Jesse Wilson synchronized (this) { 28955392539fea537abfb6581b474918f9d611fba27Jesse Wilson cancelled = true; 29055392539fea537abfb6581b474918f9d611fba27Jesse Wilson } 29155392539fea537abfb6581b474918f9d611fba27Jesse Wilson } 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void insertTask(TimerTask newTask) { 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // callers are synchronized 298f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson tasks.insert(newTask); 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.notify(); 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Cancels timer. 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public synchronized void cancel() { 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project cancelled = true; 307f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson tasks.reset(); 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.notify(); 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int purge() { 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (tasks.isEmpty()) { 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // callers are synchronized 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project tasks.deletedCancelledNumber = 0; 317f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson tasks.deleteIfCancelled(); 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return tasks.deletedCancelledNumber; 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 322f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 323d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes private static final class FinalizerHelper { 324d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes private final TimerImpl impl; 325f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 326d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes FinalizerHelper(TimerImpl impl) { 327d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes this.impl = impl; 328d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes } 329f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 330e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom @Override protected void finalize() throws Throwable { 331e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom try { 332e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom synchronized (impl) { 333e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom impl.finished = true; 334e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom impl.notify(); 335e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom } 336e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom } finally { 337e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom super.finalize(); 338d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes } 339d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes } 340d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes } 341f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 342d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes private static long timerId; 343f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 344d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes private synchronized static long nextId() { 345d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes return timerId++; 346d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes } 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* This object will be used in synchronization purposes */ 349a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson private final TimerImpl impl; 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Used to finalize thread 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @SuppressWarnings("unused") 353a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson private final FinalizerHelper finalizer; 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new named {@code Timer} which may be specified to be run as a 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * daemon thread. 358f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 359a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson * @param name the name of the {@code Timer}. 360a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson * @param isDaemon true if {@code Timer}'s thread should be a daemon thread. 361a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson * @throws NullPointerException is {@code name} is {@code null} 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Timer(String name, boolean isDaemon) { 36432c2297a959b72abdb18743f0519e1d8b7c7ea88Elliott Hughes if (name == null) { 36586acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("name == null"); 366d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes } 367a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson this.impl = new TimerImpl(name, isDaemon); 368a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson this.finalizer = new FinalizerHelper(impl); 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 370f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new named {@code Timer} which does not run as a daemon thread. 373f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 374a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson * @param name the name of the Timer. 375a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson * @throws NullPointerException is {@code name} is {@code null} 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Timer(String name) { 378a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson this(name, false); 379a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson } 380f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 381a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson /** 382a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson * Creates a new {@code Timer} which may be specified to be run as a daemon thread. 383a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson * 384a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson * @param isDaemon {@code true} if the {@code Timer}'s thread should be a daemon thread. 385a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson */ 386a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson public Timer(boolean isDaemon) { 387a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson this("Timer-" + Timer.nextId(), isDaemon); 388f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 389f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 390a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson /** 391a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson * Creates a new non-daemon {@code Timer}. 392a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson */ 393a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson public Timer() { 394a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson this(false); 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 398c38102eb6f7a01fe70094a63054337f53ab5283dJesse Wilson * Cancels the {@code Timer} and all scheduled tasks. If there is a 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * currently running task it is not affected. No more tasks may be scheduled 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * on this {@code Timer}. Subsequent calls do nothing. 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void cancel() { 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project impl.cancel(); 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Removes all canceled tasks from the task queue. If there are no 408f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * other references on the tasks, then after this call they are free 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to be garbage collected. 410f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of canceled tasks that were removed from the task 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * queue. 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int purge() { 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (impl) { 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return impl.purge(); 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Schedule a task for single execution. If {@code when} is less than the 422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * current time, it will be scheduled to be executed as soon as possible. 423f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param task 425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the task to schedule. 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param when 427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * time of execution. 428f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws IllegalArgumentException 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code when.getTime() < 0}. 430f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws IllegalStateException 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the {@code Timer} has been canceled, or if the task has been 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * scheduled or canceled. 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void schedule(TimerTask task, Date when) { 435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (when.getTime() < 0) { 436cff1616012dc0d56c2da9af2b9b1183e76c7e044Elliott Hughes throw new IllegalArgumentException("when < 0: " + when.getTime()); 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long delay = when.getTime() - System.currentTimeMillis(); 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project scheduleImpl(task, delay < 0 ? 0 : delay, -1, false); 440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Schedule a task for single execution after a specified delay. 444f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param task 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the task to schedule. 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param delay 448a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson * amount of time in milliseconds before execution. 449f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws IllegalArgumentException 450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code delay < 0}. 451f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws IllegalStateException 452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the {@code Timer} has been canceled, or if the task has been 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * scheduled or canceled. 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void schedule(TimerTask task, long delay) { 456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (delay < 0) { 457cff1616012dc0d56c2da9af2b9b1183e76c7e044Elliott Hughes throw new IllegalArgumentException("delay < 0: " + delay); 458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project scheduleImpl(task, delay, -1, false); 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Schedule a task for repeated fixed-delay execution after a specific delay. 464f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param task 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the task to schedule. 467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param delay 468a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson * amount of time in milliseconds before first execution. 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param period 470a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson * amount of time in milliseconds between subsequent executions. 471f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws IllegalArgumentException 472723f75d03dd4a6c51e9e1ff67847b10fe0cb16e6Jesse Wilson * if {@code delay < 0} or {@code period <= 0}. 473f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws IllegalStateException 474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the {@code Timer} has been canceled, or if the task has been 475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * scheduled or canceled. 476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void schedule(TimerTask task, long delay, long period) { 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (delay < 0 || period <= 0) { 479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project scheduleImpl(task, delay, period, false); 482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Schedule a task for repeated fixed-delay execution after a specific time 486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * has been reached. 487f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param task 489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the task to schedule. 490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param when 491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * time of first execution. 492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param period 493a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson * amount of time in milliseconds between subsequent executions. 494f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws IllegalArgumentException 495723f75d03dd4a6c51e9e1ff67847b10fe0cb16e6Jesse Wilson * if {@code when.getTime() < 0} or {@code period <= 0}. 496f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws IllegalStateException 497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the {@code Timer} has been canceled, or if the task has been 498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * scheduled or canceled. 499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void schedule(TimerTask task, Date when, long period) { 501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (period <= 0 || when.getTime() < 0) { 502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long delay = when.getTime() - System.currentTimeMillis(); 505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project scheduleImpl(task, delay < 0 ? 0 : delay, period, false); 506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Schedule a task for repeated fixed-rate execution after a specific delay 510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * has passed. 511f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param task 513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the task to schedule. 514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param delay 515a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson * amount of time in milliseconds before first execution. 516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param period 517a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson * amount of time in milliseconds between subsequent executions. 518f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws IllegalArgumentException 519723f75d03dd4a6c51e9e1ff67847b10fe0cb16e6Jesse Wilson * if {@code delay < 0} or {@code period <= 0}. 520f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws IllegalStateException 521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the {@code Timer} has been canceled, or if the task has been 522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * scheduled or canceled. 523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void scheduleAtFixedRate(TimerTask task, long delay, long period) { 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (delay < 0 || period <= 0) { 526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project scheduleImpl(task, delay, period, true); 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Schedule a task for repeated fixed-rate execution after a specific time 533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * has been reached. 534f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param task 536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the task to schedule. 537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param when 538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * time of first execution. 539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param period 540a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson * amount of time in milliseconds between subsequent executions. 541f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws IllegalArgumentException 542723f75d03dd4a6c51e9e1ff67847b10fe0cb16e6Jesse Wilson * if {@code when.getTime() < 0} or {@code period <= 0}. 543f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws IllegalStateException 544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the {@code Timer} has been canceled, or if the task has been 545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * scheduled or canceled. 546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void scheduleAtFixedRate(TimerTask task, Date when, long period) { 548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (period <= 0 || when.getTime() < 0) { 549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long delay = when.getTime() - System.currentTimeMillis(); 55255392539fea537abfb6581b474918f9d611fba27Jesse Wilson scheduleImpl(task, delay, period, true); 553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 555f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /* 556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Schedule a task. 557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 558b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes private void scheduleImpl(TimerTask task, long delay, long period, boolean fixed) { 559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (impl) { 560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (impl.cancelled) { 561b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalStateException("Timer was canceled"); 562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long when = delay + System.currentTimeMillis(); 565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (when < 0) { 567b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("Illegal delay to start the TimerTask: " + when); 568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (task.lock) { 571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (task.isScheduled()) { 572b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalStateException("TimerTask is scheduled already"); 573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (task.cancelled) { 576b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalStateException("TimerTask is canceled"); 577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project task.when = when; 580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project task.period = period; 581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project task.fixedRate = fixed; 582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // insert the newTask into queue 585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project impl.insertTask(task); 586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 589