1 /* 2 * Copyright 2022 Google LLC 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 package com.google.android.libraries.mobiledatadownload.testing; 17 18 import com.google.android.libraries.mobiledatadownload.TimeSource; 19 import com.google.errorprone.annotations.CanIgnoreReturnValue; 20 import java.util.concurrent.TimeUnit; 21 import java.util.concurrent.atomic.AtomicLong; 22 23 /** Fake implementation of {@link TimeSource} for testing. */ 24 public final class FakeTimeSource implements TimeSource { 25 26 private final AtomicLong currentMillis = new AtomicLong(); 27 private final AtomicLong elapsedNanos = new AtomicLong(); 28 29 @Override currentTimeMillis()30 public long currentTimeMillis() { 31 return currentMillis.get(); 32 } 33 34 @Override elapsedRealtimeNanos()35 public long elapsedRealtimeNanos() { 36 return elapsedNanos.get(); 37 } 38 39 /** Advances the current time and returns {@code this}. */ 40 @CanIgnoreReturnValue advance(long interval, TimeUnit units)41 public FakeTimeSource advance(long interval, TimeUnit units) { 42 long millis = units.toMillis(interval); 43 if (millis < 0) { 44 throw new IllegalArgumentException("Can't advance negative duration: " + millis); 45 } 46 currentMillis.getAndAdd(millis); 47 long nanos = units.toNanos(interval); 48 if (nanos < 0) { 49 throw new IllegalArgumentException("Can't advance negative duration: " + nanos); 50 } 51 elapsedNanos.getAndAdd(nanos); 52 return this; 53 } 54 55 /** Sets the current time and returns {@code this}. */ 56 @CanIgnoreReturnValue set(long millis)57 public FakeTimeSource set(long millis) { 58 if (millis < 0) { 59 throw new IllegalArgumentException("Can't set before unix epoch:" + millis); 60 } 61 currentMillis.set(millis); 62 return this; 63 } 64 65 /** Sets the elapsed time and returns {@code this}. */ 66 @CanIgnoreReturnValue setElapsedNanos(long nanos)67 public FakeTimeSource setElapsedNanos(long nanos) { 68 if (nanos < 0) { 69 throw new IllegalArgumentException("Negative elapsed time: " + nanos); 70 } 71 elapsedNanos.set(nanos); 72 return this; 73 } 74 } 75