Loading location/java/android/location/GnssCapabilities.java +5 −1 Original line number Diff line number Diff line Loading @@ -240,7 +240,11 @@ public final class GnssCapabilities implements Parcelable { } /** * Returns {@code true} if GNSS chipset supports on demand time, {@code false} otherwise. * Returns {@code true} if GNSS chipset requests periodic time signal injection from the * platform in addition to on-demand and occasional time updates, {@code false} otherwise. * * <p><em>Note: The naming of this capability and the behavior it controls differ substantially. * This is the result of a historic implementation bug, b/73893222.</em> */ public boolean hasOnDemandTime() { return (mTopFlags & TOP_HAL_CAPABILITY_ON_DEMAND_TIME) != 0; Loading services/core/java/com/android/server/location/gnss/GnssLocationProvider.java +25 −18 Original line number Diff line number Diff line Loading @@ -113,9 +113,8 @@ import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.HexDump; import com.android.server.FgThread; import com.android.server.location.gnss.GnssSatelliteBlocklistHelper.GnssSatelliteBlocklistCallback; import com.android.server.location.gnss.NtpTimeHelper.InjectNtpTimeCallback; import com.android.server.location.gnss.NetworkTimeHelper.InjectTimeCallback; import com.android.server.location.gnss.hal.GnssNative; import com.android.server.location.injector.Injector; import com.android.server.location.provider.AbstractLocationProvider; import java.io.FileDescriptor; Loading @@ -138,7 +137,7 @@ import java.util.concurrent.TimeUnit; * {@hide} */ public class GnssLocationProvider extends AbstractLocationProvider implements InjectNtpTimeCallback, GnssSatelliteBlocklistCallback, GnssNative.BaseCallbacks, InjectTimeCallback, GnssSatelliteBlocklistCallback, GnssNative.BaseCallbacks, GnssNative.LocationCallbacks, GnssNative.SvStatusCallbacks, GnssNative.AGpsCallbacks, GnssNative.PsdsCallbacks, GnssNative.NotificationCallbacks, GnssNative.LocationRequestCallbacks, GnssNative.TimeCallbacks { Loading Loading @@ -307,7 +306,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements private boolean mSuplEsEnabled = false; private final LocationExtras mLocationExtras = new LocationExtras(); private final NtpTimeHelper mNtpTimeHelper; private final NetworkTimeHelper mNetworkTimeHelper; private final GnssSatelliteBlocklistHelper mGnssSatelliteBlocklistHelper; // Available only on GNSS HAL 2.0 implementations and later. Loading Loading @@ -398,7 +397,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } } public GnssLocationProvider(Context context, Injector injector, GnssNative gnssNative, public GnssLocationProvider(Context context, GnssNative gnssNative, GnssMetrics gnssMetrics) { super(FgThread.getExecutor(), CallerIdentity.fromContext(context), PROPERTIES, Collections.emptySet()); Loading Loading @@ -470,7 +469,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements GnssLocationProvider.this::onNetworkAvailable, mHandler.getLooper(), mNIHandler); mNtpTimeHelper = new NtpTimeHelper(mContext, mHandler.getLooper(), this); mNetworkTimeHelper = NetworkTimeHelper.create(mContext, mHandler.getLooper(), this); mGnssSatelliteBlocklistHelper = new GnssSatelliteBlocklistHelper(mContext, mHandler.getLooper(), this); Loading Loading @@ -647,18 +646,19 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } /** * Implements {@link InjectNtpTimeCallback#injectTime} * Implements {@link InjectTimeCallback#injectTime} */ @Override public void injectTime(long time, long timeReference, int uncertainty) { mGnssNative.injectTime(time, timeReference, uncertainty); public void injectTime(long unixEpochTimeMillis, long elapsedRealtimeMillis, int uncertaintyMillis) { mGnssNative.injectTime(unixEpochTimeMillis, elapsedRealtimeMillis, uncertaintyMillis); } /** * Implements {@link GnssNetworkConnectivityHandler.GnssNetworkListener#onNetworkAvailable()} */ private void onNetworkAvailable() { mNtpTimeHelper.onNetworkAvailable(); mNetworkTimeHelper.onNetworkAvailable(); // Download only if supported, (prevents an unnecessary on-boot download) if (mSupportsPsds) { synchronized (mLock) { Loading Loading @@ -1145,7 +1145,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements if ("delete_aiding_data".equals(command)) { deleteAidingData(extras); } else if ("force_time_injection".equals(command)) { requestUtcTime(); demandUtcTimeInjection(); } else if ("force_psds_injection".equals(command)) { if (mSupportsPsds) { postWithWakeLockHeld(() -> handleDownloadPsdsData( Loading Loading @@ -1514,9 +1514,9 @@ public class GnssLocationProvider extends AbstractLocationProvider implements /* userResponse= */ 0); } private void requestUtcTime() { if (DEBUG) Log.d(TAG, "utcTimeRequest"); postWithWakeLockHeld(mNtpTimeHelper::retrieveAndInjectNtpTime); private void demandUtcTimeInjection() { if (DEBUG) Log.d(TAG, "demandUtcTimeInjection"); postWithWakeLockHeld(mNetworkTimeHelper::demandUtcTimeInjection); } Loading Loading @@ -1721,9 +1721,16 @@ public class GnssLocationProvider extends AbstractLocationProvider implements public void onCapabilitiesChanged(GnssCapabilities oldCapabilities, GnssCapabilities newCapabilities) { mHandler.post(() -> { if (mGnssNative.getCapabilities().hasOnDemandTime()) { mNtpTimeHelper.enablePeriodicTimeInjection(); requestUtcTime(); boolean useOnDemandTimeInjection = mGnssNative.getCapabilities().hasOnDemandTime(); // b/73893222: There is a historic bug on Android, which means that the capability // "on demand time" is interpreted as "enable periodic injection" elsewhere but an // on-demand injection is done here. GNSS developers may have come to rely on the // periodic behavior, so it has been kept and all methods named to reflect what is // actually done. "On demand" requests are supported regardless of the capability. mNetworkTimeHelper.setPeriodicTimeInjectionMode(useOnDemandTimeInjection); if (useOnDemandTimeInjection) { demandUtcTimeInjection(); } restartLocationRequest(); Loading Loading @@ -1857,7 +1864,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements @Override public void onRequestUtcTime() { requestUtcTime(); demandUtcTimeInjection(); } @Override Loading services/core/java/com/android/server/location/gnss/GnssManagerService.java +1 −2 Original line number Diff line number Diff line Loading @@ -83,8 +83,7 @@ public class GnssManagerService { mGnssMetrics = new GnssMetrics(mContext, IBatteryStats.Stub.asInterface( ServiceManager.getService(BatteryStats.SERVICE_NAME)), mGnssNative); mGnssLocationProvider = new GnssLocationProvider(mContext, injector, mGnssNative, mGnssMetrics); mGnssLocationProvider = new GnssLocationProvider(mContext, mGnssNative, mGnssMetrics); mGnssStatusProvider = new GnssStatusProvider(injector, mGnssNative); mGnssNmeaProvider = new GnssNmeaProvider(injector, mGnssNative); mGnssMeasurementsProvider = new GnssMeasurementsProvider(injector, mGnssNative); Loading services/core/java/com/android/server/location/gnss/NetworkTimeHelper.java 0 → 100644 +75 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.location.gnss; import android.content.Context; import android.os.Looper; /** * An abstraction for use by {@link GnssLocationProvider}. This class allows switching between * implementations with a compile-time constant change, which is less risky than rolling back a * whole class. When there is a single implementation again this class can be replaced by that * implementation. */ abstract class NetworkTimeHelper { /** * The callback interface used by {@link NetworkTimeHelper} to report the time to {@link * GnssLocationProvider}. The callback can happen at any time using the thread associated with * the looper passed to {@link #create(Context, Looper, InjectTimeCallback)}. */ interface InjectTimeCallback { void injectTime(long unixEpochTimeMillis, long elapsedRealtimeMillis, int uncertaintyMillis); } /** * Creates the {@link NetworkTimeHelper} instance for use by {@link GnssLocationProvider}. */ static NetworkTimeHelper create( Context context, Looper looper, InjectTimeCallback injectTimeCallback) { return new NtpNetworkTimeHelper(context, looper, injectTimeCallback); } /** * Sets the "on demand time injection" mode. * * <p>Called by {@link GnssLocationProvider} to set the expected time injection behavior. * When {@code enablePeriodicTimeInjection == true}, the time helper should periodically send * the time on an undefined schedule. The time can be injected at other times for other reasons * as well as be requested via {@link #demandUtcTimeInjection()}. * * @param periodicTimeInjectionEnabled {@code true} if the GNSS implementation requires periodic * time signals */ abstract void setPeriodicTimeInjectionMode(boolean periodicTimeInjectionEnabled); /** * Requests an asynchronous time injection via {@link InjectTimeCallback#injectTime}, if a * network time is available. {@link InjectTimeCallback#injectTime} may not be called if a * network time is not available. */ abstract void demandUtcTimeInjection(); /** * Notifies that network connectivity has been established. * * <p>Called by {@link GnssLocationProvider} when the device establishes a data network * connection. */ abstract void onNetworkAvailable(); } services/core/java/com/android/server/location/gnss/NtpTimeHelper.java→services/core/java/com/android/server/location/gnss/NtpNetworkTimeHelper.java +26 −27 Original line number Diff line number Diff line Loading @@ -30,14 +30,11 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; /** * Handles inject NTP time to GNSS. * * <p>The client is responsible to call {@link #onNetworkAvailable()} when network is available * for retrieving NTP Time. * Handles injecting network time to GNSS by explicitly making NTP requests when needed. */ class NtpTimeHelper { class NtpNetworkTimeHelper extends NetworkTimeHelper { private static final String TAG = "NtpTimeHelper"; private static final String TAG = "NtpNetworkTimeHelper"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); // states for injecting ntp Loading Loading @@ -71,23 +68,19 @@ class NtpTimeHelper { private final WakeLock mWakeLock; private final Handler mHandler; private final InjectNtpTimeCallback mCallback; private final InjectTimeCallback mCallback; // flags to trigger NTP when network becomes available // initialized to STATE_PENDING_NETWORK so we do NTP when the network comes up after booting @GuardedBy("this") private int mInjectNtpTimeState = STATE_PENDING_NETWORK; // set to true if the GPS engine requested on-demand NTP time requests // Enables periodic time injection in addition to injection for other reasons. @GuardedBy("this") private boolean mOnDemandTimeInjection; interface InjectNtpTimeCallback { void injectTime(long time, long timeReference, int uncertainty); } private boolean mPeriodicTimeInjection; @VisibleForTesting NtpTimeHelper(Context context, Looper looper, InjectNtpTimeCallback callback, NtpNetworkTimeHelper(Context context, Looper looper, InjectTimeCallback callback, NtpTrustedTime ntpTime) { mConnMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); mCallback = callback; Loading @@ -97,14 +90,23 @@ class NtpTimeHelper { mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY); } NtpTimeHelper(Context context, Looper looper, InjectNtpTimeCallback callback) { NtpNetworkTimeHelper(Context context, Looper looper, InjectTimeCallback callback) { this(context, looper, callback, NtpTrustedTime.getInstance(context)); } synchronized void enablePeriodicTimeInjection() { mOnDemandTimeInjection = true; @Override synchronized void setPeriodicTimeInjectionMode(boolean periodicTimeInjectionEnabled) { if (periodicTimeInjectionEnabled) { mPeriodicTimeInjection = true; } } @Override void demandUtcTimeInjection() { retrieveAndInjectNtpTime(); } @Override synchronized void onNetworkAvailable() { if (mInjectNtpTimeState == STATE_PENDING_NETWORK) { retrieveAndInjectNtpTime(); Loading @@ -120,7 +122,7 @@ class NtpTimeHelper { return activeNetworkInfo != null && activeNetworkInfo.isConnected(); } synchronized void retrieveAndInjectNtpTime() { private synchronized void retrieveAndInjectNtpTime() { if (mInjectNtpTimeState == STATE_RETRIEVING_AND_INJECTING) { // already downloading data return; Loading Loading @@ -166,18 +168,15 @@ class NtpTimeHelper { if (DEBUG) { Log.d(TAG, String.format( "onDemandTimeInjection=%s, refreshSuccess=%s, delay=%s", mOnDemandTimeInjection, "mPeriodicTimeInjection=%s, refreshSuccess=%s, delay=%s", mPeriodicTimeInjection, refreshSuccess, delay)); } // TODO(b/73893222): reconcile Capabilities bit 'on demand' name vs. de facto periodic // injection. if (mOnDemandTimeInjection || !refreshSuccess) { /* Schedule next NTP injection. * Since this is delayed, the wake lock is released right away, and will be held * again when the delayed task runs. */ if (mPeriodicTimeInjection || !refreshSuccess) { // Schedule next NTP injection. // Since this is delayed, the wake lock is released right away, and will be held // again when the delayed task runs. mHandler.postDelayed(this::retrieveAndInjectNtpTime, delay); } } Loading Loading
location/java/android/location/GnssCapabilities.java +5 −1 Original line number Diff line number Diff line Loading @@ -240,7 +240,11 @@ public final class GnssCapabilities implements Parcelable { } /** * Returns {@code true} if GNSS chipset supports on demand time, {@code false} otherwise. * Returns {@code true} if GNSS chipset requests periodic time signal injection from the * platform in addition to on-demand and occasional time updates, {@code false} otherwise. * * <p><em>Note: The naming of this capability and the behavior it controls differ substantially. * This is the result of a historic implementation bug, b/73893222.</em> */ public boolean hasOnDemandTime() { return (mTopFlags & TOP_HAL_CAPABILITY_ON_DEMAND_TIME) != 0; Loading
services/core/java/com/android/server/location/gnss/GnssLocationProvider.java +25 −18 Original line number Diff line number Diff line Loading @@ -113,9 +113,8 @@ import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.HexDump; import com.android.server.FgThread; import com.android.server.location.gnss.GnssSatelliteBlocklistHelper.GnssSatelliteBlocklistCallback; import com.android.server.location.gnss.NtpTimeHelper.InjectNtpTimeCallback; import com.android.server.location.gnss.NetworkTimeHelper.InjectTimeCallback; import com.android.server.location.gnss.hal.GnssNative; import com.android.server.location.injector.Injector; import com.android.server.location.provider.AbstractLocationProvider; import java.io.FileDescriptor; Loading @@ -138,7 +137,7 @@ import java.util.concurrent.TimeUnit; * {@hide} */ public class GnssLocationProvider extends AbstractLocationProvider implements InjectNtpTimeCallback, GnssSatelliteBlocklistCallback, GnssNative.BaseCallbacks, InjectTimeCallback, GnssSatelliteBlocklistCallback, GnssNative.BaseCallbacks, GnssNative.LocationCallbacks, GnssNative.SvStatusCallbacks, GnssNative.AGpsCallbacks, GnssNative.PsdsCallbacks, GnssNative.NotificationCallbacks, GnssNative.LocationRequestCallbacks, GnssNative.TimeCallbacks { Loading Loading @@ -307,7 +306,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements private boolean mSuplEsEnabled = false; private final LocationExtras mLocationExtras = new LocationExtras(); private final NtpTimeHelper mNtpTimeHelper; private final NetworkTimeHelper mNetworkTimeHelper; private final GnssSatelliteBlocklistHelper mGnssSatelliteBlocklistHelper; // Available only on GNSS HAL 2.0 implementations and later. Loading Loading @@ -398,7 +397,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } } public GnssLocationProvider(Context context, Injector injector, GnssNative gnssNative, public GnssLocationProvider(Context context, GnssNative gnssNative, GnssMetrics gnssMetrics) { super(FgThread.getExecutor(), CallerIdentity.fromContext(context), PROPERTIES, Collections.emptySet()); Loading Loading @@ -470,7 +469,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements GnssLocationProvider.this::onNetworkAvailable, mHandler.getLooper(), mNIHandler); mNtpTimeHelper = new NtpTimeHelper(mContext, mHandler.getLooper(), this); mNetworkTimeHelper = NetworkTimeHelper.create(mContext, mHandler.getLooper(), this); mGnssSatelliteBlocklistHelper = new GnssSatelliteBlocklistHelper(mContext, mHandler.getLooper(), this); Loading Loading @@ -647,18 +646,19 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } /** * Implements {@link InjectNtpTimeCallback#injectTime} * Implements {@link InjectTimeCallback#injectTime} */ @Override public void injectTime(long time, long timeReference, int uncertainty) { mGnssNative.injectTime(time, timeReference, uncertainty); public void injectTime(long unixEpochTimeMillis, long elapsedRealtimeMillis, int uncertaintyMillis) { mGnssNative.injectTime(unixEpochTimeMillis, elapsedRealtimeMillis, uncertaintyMillis); } /** * Implements {@link GnssNetworkConnectivityHandler.GnssNetworkListener#onNetworkAvailable()} */ private void onNetworkAvailable() { mNtpTimeHelper.onNetworkAvailable(); mNetworkTimeHelper.onNetworkAvailable(); // Download only if supported, (prevents an unnecessary on-boot download) if (mSupportsPsds) { synchronized (mLock) { Loading Loading @@ -1145,7 +1145,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements if ("delete_aiding_data".equals(command)) { deleteAidingData(extras); } else if ("force_time_injection".equals(command)) { requestUtcTime(); demandUtcTimeInjection(); } else if ("force_psds_injection".equals(command)) { if (mSupportsPsds) { postWithWakeLockHeld(() -> handleDownloadPsdsData( Loading Loading @@ -1514,9 +1514,9 @@ public class GnssLocationProvider extends AbstractLocationProvider implements /* userResponse= */ 0); } private void requestUtcTime() { if (DEBUG) Log.d(TAG, "utcTimeRequest"); postWithWakeLockHeld(mNtpTimeHelper::retrieveAndInjectNtpTime); private void demandUtcTimeInjection() { if (DEBUG) Log.d(TAG, "demandUtcTimeInjection"); postWithWakeLockHeld(mNetworkTimeHelper::demandUtcTimeInjection); } Loading Loading @@ -1721,9 +1721,16 @@ public class GnssLocationProvider extends AbstractLocationProvider implements public void onCapabilitiesChanged(GnssCapabilities oldCapabilities, GnssCapabilities newCapabilities) { mHandler.post(() -> { if (mGnssNative.getCapabilities().hasOnDemandTime()) { mNtpTimeHelper.enablePeriodicTimeInjection(); requestUtcTime(); boolean useOnDemandTimeInjection = mGnssNative.getCapabilities().hasOnDemandTime(); // b/73893222: There is a historic bug on Android, which means that the capability // "on demand time" is interpreted as "enable periodic injection" elsewhere but an // on-demand injection is done here. GNSS developers may have come to rely on the // periodic behavior, so it has been kept and all methods named to reflect what is // actually done. "On demand" requests are supported regardless of the capability. mNetworkTimeHelper.setPeriodicTimeInjectionMode(useOnDemandTimeInjection); if (useOnDemandTimeInjection) { demandUtcTimeInjection(); } restartLocationRequest(); Loading Loading @@ -1857,7 +1864,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements @Override public void onRequestUtcTime() { requestUtcTime(); demandUtcTimeInjection(); } @Override Loading
services/core/java/com/android/server/location/gnss/GnssManagerService.java +1 −2 Original line number Diff line number Diff line Loading @@ -83,8 +83,7 @@ public class GnssManagerService { mGnssMetrics = new GnssMetrics(mContext, IBatteryStats.Stub.asInterface( ServiceManager.getService(BatteryStats.SERVICE_NAME)), mGnssNative); mGnssLocationProvider = new GnssLocationProvider(mContext, injector, mGnssNative, mGnssMetrics); mGnssLocationProvider = new GnssLocationProvider(mContext, mGnssNative, mGnssMetrics); mGnssStatusProvider = new GnssStatusProvider(injector, mGnssNative); mGnssNmeaProvider = new GnssNmeaProvider(injector, mGnssNative); mGnssMeasurementsProvider = new GnssMeasurementsProvider(injector, mGnssNative); Loading
services/core/java/com/android/server/location/gnss/NetworkTimeHelper.java 0 → 100644 +75 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.location.gnss; import android.content.Context; import android.os.Looper; /** * An abstraction for use by {@link GnssLocationProvider}. This class allows switching between * implementations with a compile-time constant change, which is less risky than rolling back a * whole class. When there is a single implementation again this class can be replaced by that * implementation. */ abstract class NetworkTimeHelper { /** * The callback interface used by {@link NetworkTimeHelper} to report the time to {@link * GnssLocationProvider}. The callback can happen at any time using the thread associated with * the looper passed to {@link #create(Context, Looper, InjectTimeCallback)}. */ interface InjectTimeCallback { void injectTime(long unixEpochTimeMillis, long elapsedRealtimeMillis, int uncertaintyMillis); } /** * Creates the {@link NetworkTimeHelper} instance for use by {@link GnssLocationProvider}. */ static NetworkTimeHelper create( Context context, Looper looper, InjectTimeCallback injectTimeCallback) { return new NtpNetworkTimeHelper(context, looper, injectTimeCallback); } /** * Sets the "on demand time injection" mode. * * <p>Called by {@link GnssLocationProvider} to set the expected time injection behavior. * When {@code enablePeriodicTimeInjection == true}, the time helper should periodically send * the time on an undefined schedule. The time can be injected at other times for other reasons * as well as be requested via {@link #demandUtcTimeInjection()}. * * @param periodicTimeInjectionEnabled {@code true} if the GNSS implementation requires periodic * time signals */ abstract void setPeriodicTimeInjectionMode(boolean periodicTimeInjectionEnabled); /** * Requests an asynchronous time injection via {@link InjectTimeCallback#injectTime}, if a * network time is available. {@link InjectTimeCallback#injectTime} may not be called if a * network time is not available. */ abstract void demandUtcTimeInjection(); /** * Notifies that network connectivity has been established. * * <p>Called by {@link GnssLocationProvider} when the device establishes a data network * connection. */ abstract void onNetworkAvailable(); }
services/core/java/com/android/server/location/gnss/NtpTimeHelper.java→services/core/java/com/android/server/location/gnss/NtpNetworkTimeHelper.java +26 −27 Original line number Diff line number Diff line Loading @@ -30,14 +30,11 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; /** * Handles inject NTP time to GNSS. * * <p>The client is responsible to call {@link #onNetworkAvailable()} when network is available * for retrieving NTP Time. * Handles injecting network time to GNSS by explicitly making NTP requests when needed. */ class NtpTimeHelper { class NtpNetworkTimeHelper extends NetworkTimeHelper { private static final String TAG = "NtpTimeHelper"; private static final String TAG = "NtpNetworkTimeHelper"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); // states for injecting ntp Loading Loading @@ -71,23 +68,19 @@ class NtpTimeHelper { private final WakeLock mWakeLock; private final Handler mHandler; private final InjectNtpTimeCallback mCallback; private final InjectTimeCallback mCallback; // flags to trigger NTP when network becomes available // initialized to STATE_PENDING_NETWORK so we do NTP when the network comes up after booting @GuardedBy("this") private int mInjectNtpTimeState = STATE_PENDING_NETWORK; // set to true if the GPS engine requested on-demand NTP time requests // Enables periodic time injection in addition to injection for other reasons. @GuardedBy("this") private boolean mOnDemandTimeInjection; interface InjectNtpTimeCallback { void injectTime(long time, long timeReference, int uncertainty); } private boolean mPeriodicTimeInjection; @VisibleForTesting NtpTimeHelper(Context context, Looper looper, InjectNtpTimeCallback callback, NtpNetworkTimeHelper(Context context, Looper looper, InjectTimeCallback callback, NtpTrustedTime ntpTime) { mConnMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); mCallback = callback; Loading @@ -97,14 +90,23 @@ class NtpTimeHelper { mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY); } NtpTimeHelper(Context context, Looper looper, InjectNtpTimeCallback callback) { NtpNetworkTimeHelper(Context context, Looper looper, InjectTimeCallback callback) { this(context, looper, callback, NtpTrustedTime.getInstance(context)); } synchronized void enablePeriodicTimeInjection() { mOnDemandTimeInjection = true; @Override synchronized void setPeriodicTimeInjectionMode(boolean periodicTimeInjectionEnabled) { if (periodicTimeInjectionEnabled) { mPeriodicTimeInjection = true; } } @Override void demandUtcTimeInjection() { retrieveAndInjectNtpTime(); } @Override synchronized void onNetworkAvailable() { if (mInjectNtpTimeState == STATE_PENDING_NETWORK) { retrieveAndInjectNtpTime(); Loading @@ -120,7 +122,7 @@ class NtpTimeHelper { return activeNetworkInfo != null && activeNetworkInfo.isConnected(); } synchronized void retrieveAndInjectNtpTime() { private synchronized void retrieveAndInjectNtpTime() { if (mInjectNtpTimeState == STATE_RETRIEVING_AND_INJECTING) { // already downloading data return; Loading Loading @@ -166,18 +168,15 @@ class NtpTimeHelper { if (DEBUG) { Log.d(TAG, String.format( "onDemandTimeInjection=%s, refreshSuccess=%s, delay=%s", mOnDemandTimeInjection, "mPeriodicTimeInjection=%s, refreshSuccess=%s, delay=%s", mPeriodicTimeInjection, refreshSuccess, delay)); } // TODO(b/73893222): reconcile Capabilities bit 'on demand' name vs. de facto periodic // injection. if (mOnDemandTimeInjection || !refreshSuccess) { /* Schedule next NTP injection. * Since this is delayed, the wake lock is released right away, and will be held * again when the delayed task runs. */ if (mPeriodicTimeInjection || !refreshSuccess) { // Schedule next NTP injection. // Since this is delayed, the wake lock is released right away, and will be held // again when the delayed task runs. mHandler.postDelayed(this::retrieveAndInjectNtpTime, delay); } } Loading