1 /* 2 * Copyright (C) 2019 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.systemui.util.time; 18 19 import com.android.systemui.util.concurrency.FakeExecutor; 20 21 import java.util.ArrayList; 22 import java.util.List; 23 24 /** 25 * A fake {@link SystemClock} for use with {@link FakeExecutor}. 26 * 27 * Attempts to simulate the behavior of a real system clock. Time can be moved forward but not 28 * backwards. uptimeMillis, elapsedRealtime, and currentThreadTimeMillis are all kept in sync. 29 * 30 * Unless otherwise specified, uptimeMillis and elapsedRealtime will advance the same amount with 31 * every call to {@link #advanceTime(long)}. Thread time always lags by 50% of the uptime 32 * advancement to simulate time loss due to scheduling. 33 */ 34 public class FakeSystemClock implements SystemClock { 35 private long mUptimeMillis = 10000; 36 private long mElapsedRealtime = 10000; 37 private long mCurrentThreadTimeMillis = 10000; 38 39 private long mCurrentTimeMillis = 1555555500000L; 40 41 private final List<ClockTickListener> mListeners = new ArrayList<>(); 42 @Override uptimeMillis()43 public long uptimeMillis() { 44 return mUptimeMillis; 45 } 46 47 @Override elapsedRealtime()48 public long elapsedRealtime() { 49 return mElapsedRealtime; 50 } 51 52 @Override elapsedRealtimeNanos()53 public long elapsedRealtimeNanos() { 54 return mElapsedRealtime * 1000000 + 447; 55 } 56 57 @Override currentThreadTimeMillis()58 public long currentThreadTimeMillis() { 59 return mCurrentThreadTimeMillis; 60 } 61 62 @Override currentTimeMillis()63 public long currentTimeMillis() { 64 return mCurrentTimeMillis; 65 } 66 setUptimeMillis(long uptime)67 public void setUptimeMillis(long uptime) { 68 advanceTime(uptime - mUptimeMillis); 69 } 70 setCurrentTimeMillis(long millis)71 public void setCurrentTimeMillis(long millis) { 72 mCurrentTimeMillis = millis; 73 } 74 advanceTime(long uptime)75 public void advanceTime(long uptime) { 76 advanceTime(uptime, 0); 77 } 78 advanceTime(long uptime, long sleepTime)79 public void advanceTime(long uptime, long sleepTime) { 80 if (uptime < 0 || sleepTime < 0) { 81 throw new IllegalArgumentException("Time cannot go backwards"); 82 } 83 84 if (uptime > 0 || sleepTime > 0) { 85 mUptimeMillis += uptime; 86 mElapsedRealtime += uptime + sleepTime; 87 mCurrentTimeMillis += uptime + sleepTime; 88 89 mCurrentThreadTimeMillis += Math.ceil(uptime * 0.5); 90 91 for (ClockTickListener listener : mListeners) { 92 listener.onClockTick(); 93 } 94 } 95 } 96 addListener(ClockTickListener listener)97 public void addListener(ClockTickListener listener) { 98 mListeners.add(listener); 99 } 100 removeListener(ClockTickListener listener)101 public void removeListener(ClockTickListener listener) { 102 mListeners.remove(listener); 103 } 104 105 public interface ClockTickListener { onClockTick()106 void onClockTick(); 107 } 108 109 private static final long START_TIME = 10000; 110 } 111