NtpTrustedTime.java revision b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7c
1b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey/* 2b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey * Copyright (C) 2011 The Android Open Source Project 3b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey * 4b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 5b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey * you may not use this file except in compliance with the License. 6b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey * You may obtain a copy of the License at 7b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey * 8b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 9b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey * 10b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey * Unless required by applicable law or agreed to in writing, software 11b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 12b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey * See the License for the specific language governing permissions and 14b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey * limitations under the License. 15b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey */ 16b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey 17b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkeypackage android.util; 18b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey 19b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkeyimport android.net.SntpClient; 20b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkeyimport android.os.SystemClock; 21b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey 22b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey/** 23b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey * {@link TrustedTime} that connects with a remote NTP server as its remote 24b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey * trusted time source. 25b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey * 26b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey * @hide 27b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey */ 28b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkeypublic class NtpTrustedTime implements TrustedTime { 29b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey private String mNtpServer; 30b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey private long mNtpTimeout; 31b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey 32b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey private boolean mHasCache; 33b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey private long mCachedNtpTime; 34b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey private long mCachedNtpElapsedRealtime; 35b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey private long mCachedNtpCertainty; 36b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey 37b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey public NtpTrustedTime() { 38b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 39b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey 40b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey public void setNtpServer(String server, long timeout) { 41b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey mNtpServer = server; 42b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey mNtpTimeout = timeout; 43b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 44b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey 45b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey /** {@inheritDoc} */ 46b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey public boolean forceRefresh() { 47b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey if (mNtpServer == null) { 48b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey throw new IllegalStateException("Missing NTP server"); 49b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 50b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey 51b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey final SntpClient client = new SntpClient(); 52b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey if (client.requestTime(mNtpServer, (int) mNtpTimeout)) { 53b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey mHasCache = true; 54b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey mCachedNtpTime = client.getNtpTime(); 55b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey mCachedNtpElapsedRealtime = client.getNtpTimeReference(); 56b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey mCachedNtpCertainty = client.getRoundTripTime() / 2; 57b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey return true; 58b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } else { 59b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey return false; 60b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 61b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 62b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey 63b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey /** {@inheritDoc} */ 64b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey public boolean hasCache() { 65b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey return mHasCache; 66b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 67b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey 68b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey /** {@inheritDoc} */ 69b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey public long getCacheAge() { 70b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey if (mHasCache) { 71b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey return SystemClock.elapsedRealtime() - mCachedNtpElapsedRealtime; 72b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } else { 73b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey return Long.MAX_VALUE; 74b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 75b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 76b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey 77b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey /** {@inheritDoc} */ 78b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey public long getCacheCertainty() { 79b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey if (mHasCache) { 80b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey return mCachedNtpCertainty; 81b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } else { 82b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey return Long.MAX_VALUE; 83b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 84b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 85b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey 86b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey /** {@inheritDoc} */ 87b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey public long currentTimeMillis() { 88b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey if (!mHasCache) { 89b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey throw new IllegalStateException("Missing authoritative time source"); 90b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 91b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey 92b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey // current time is age after the last ntp cache; callers who 93b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey // want fresh values will hit makeAuthoritative() first. 94b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey return mCachedNtpTime + getCacheAge(); 95b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 96b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey} 97