1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.documentsui.testing; 18 19 import java.lang.IllegalStateException; 20 import java.util.Date; 21 import java.util.Iterator; 22 import java.util.LinkedList; 23 import java.util.ListIterator; 24 import java.util.Timer; 25 import java.util.TimerTask; 26 27 /** 28 * A {@link Timer} for testing that can dial its clock hands to any future time. 29 */ 30 public class TestTimer extends Timer { 31 32 private boolean mIsCancelled; 33 private long mNow = 0; 34 35 private final LinkedList<Task> mTaskList = new LinkedList<>(); 36 getNow()37 public long getNow() { 38 return mNow; 39 } 40 fastForwardTo(long time)41 public void fastForwardTo(long time) { 42 if (time < mNow) { 43 throw new IllegalArgumentException("Can't fast forward to past."); 44 } 45 46 mNow = time; 47 while (!mTaskList.isEmpty() && mTaskList.getFirst().mExecuteTime <= mNow) { 48 Task task = mTaskList.getFirst(); 49 if (!task.isCancelled()) { 50 task.run(); 51 } 52 mTaskList.removeFirst(); 53 } 54 } 55 hasScheduledTask()56 public boolean hasScheduledTask() { 57 return !mTaskList.isEmpty(); 58 } 59 fastForwardToNextTask()60 public void fastForwardToNextTask() { 61 if (!hasScheduledTask()) { 62 throw new IllegalStateException("There is no scheduled task!"); 63 } 64 fastForwardTo(mTaskList.getFirst().mExecuteTime); 65 } 66 67 @Override cancel()68 public void cancel() { 69 mIsCancelled = true; 70 mTaskList.clear(); 71 } 72 73 @Override purge()74 public int purge() { 75 int count = 0; 76 Iterator<Task> iter = mTaskList.iterator(); 77 while (iter.hasNext()) { 78 Task task = iter.next(); 79 if (task.isCancelled()) { 80 iter.remove(); 81 ++count; 82 } 83 } 84 return count; 85 } 86 87 @Override schedule(TimerTask task, Date time)88 public void schedule(TimerTask task, Date time) { 89 long executeTime = time.getTime(); 90 scheduleAtTime(task, executeTime); 91 } 92 93 @Override schedule(TimerTask task, Date firstTime, long period)94 public void schedule(TimerTask task, Date firstTime, long period) { 95 throw new UnsupportedOperationException(); 96 } 97 98 @Override schedule(TimerTask task, long delay)99 public void schedule(TimerTask task, long delay) { 100 long executeTime = mNow + delay; 101 scheduleAtTime(task, executeTime); 102 } 103 104 @Override schedule(TimerTask task, long delay, long period)105 public void schedule(TimerTask task, long delay, long period) { 106 throw new UnsupportedOperationException(); 107 } 108 109 @Override scheduleAtFixedRate(TimerTask task, Date firstTime, long period)110 public void scheduleAtFixedRate(TimerTask task, Date firstTime, long period) { 111 throw new UnsupportedOperationException(); 112 } 113 114 @Override scheduleAtFixedRate(TimerTask task, long delay, long period)115 public void scheduleAtFixedRate(TimerTask task, long delay, long period) { 116 throw new UnsupportedOperationException(); 117 } 118 scheduleAtTime(TimerTask task, long executeTime)119 public void scheduleAtTime(TimerTask task, long executeTime) { 120 if (mIsCancelled) { 121 throw new IllegalStateException("Timer already cancelled."); 122 } 123 Task testTimerTask = (Task) task; 124 testTimerTask.mExecuteTime = executeTime; 125 126 ListIterator<Task> iter = mTaskList.listIterator(0); 127 while (iter.hasNext()) { 128 if (iter.next().mExecuteTime >= executeTime) { 129 break; 130 } 131 } 132 iter.add(testTimerTask); 133 } 134 135 public static class Task extends TimerTask { 136 private boolean mIsCancelled; 137 private long mExecuteTime; 138 139 private TimerTask mDelegate; 140 Task(TimerTask delegate)141 public Task(TimerTask delegate) { 142 mDelegate = delegate; 143 } 144 145 @Override cancel()146 public boolean cancel() { 147 mIsCancelled = true; 148 return mDelegate.cancel(); 149 } 150 151 @Override run()152 public void run() { 153 mDelegate.run(); 154 } 155 isCancelled()156 boolean isCancelled() { 157 return mIsCancelled; 158 } 159 } 160 } 161