1 /* 2 * Copyright 2018 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.internal.telephony; 18 19 import android.annotation.NonNull; 20 import android.content.ContentResolver; 21 import android.content.Context; 22 import android.os.SystemClock; 23 import android.os.SystemProperties; 24 import android.provider.Settings; 25 26 import com.android.internal.util.IndentingPrintWriter; 27 28 import java.io.FileDescriptor; 29 import java.io.PrintWriter; 30 31 /** 32 * An interface for the Android component that handles NITZ and related signals for time and time 33 * zone detection. 34 * 35 * {@hide} 36 */ 37 public interface NitzStateMachine { 38 39 /** 40 * Called when the country suitable for time zone detection is detected. 41 * 42 * @param countryIsoCode the countryIsoCode to use for time zone detection, may be "" for test 43 * cells only, otherwise {@link #handleCountryUnavailable()} should be called 44 */ handleCountryDetected(@onNull String countryIsoCode)45 void handleCountryDetected(@NonNull String countryIsoCode); 46 47 /** 48 * Informs the {@link NitzStateMachine} that the network has become available. 49 */ handleNetworkAvailable()50 void handleNetworkAvailable(); 51 52 /** 53 * Informs the {@link NitzStateMachine} that the network has become unavailable. Any network 54 * state, i.e. NITZ, should be cleared. 55 */ handleNetworkUnavailable()56 void handleNetworkUnavailable(); 57 58 /** 59 * Informs the {@link NitzStateMachine} that any previously detected country supplied via 60 * {@link #handleCountryDetected(String)} is no longer valid. 61 */ handleCountryUnavailable()62 void handleCountryUnavailable(); 63 64 /** 65 * Handle a new NITZ signal being received. 66 */ handleNitzReceived(@onNull NitzSignal nitzSignal)67 void handleNitzReceived(@NonNull NitzSignal nitzSignal); 68 69 /** 70 * Handle the user putting the device into or out of airplane mode 71 * @param on true if airplane mode has been turned on, false if it's been turned off. 72 */ handleAirplaneModeChanged(boolean on)73 void handleAirplaneModeChanged(boolean on); 74 75 /** 76 * Dumps the current in-memory state to the supplied PrintWriter. 77 */ dumpState(PrintWriter pw)78 void dumpState(PrintWriter pw); 79 80 /** 81 * Dumps the time / time zone logs to the supplied IndentingPrintWriter. 82 */ dumpLogs(FileDescriptor fd, IndentingPrintWriter ipw, String[] args)83 void dumpLogs(FileDescriptor fd, IndentingPrintWriter ipw, String[] args); 84 85 /** 86 * A proxy over read-only device state that allows things like system properties, elapsed 87 * realtime clock to be faked for tests. 88 */ 89 interface DeviceState { 90 91 /** 92 * If the elapsed realtime between two NITZ signals is greater than this value then the 93 * second signal cannot be ignored. 94 */ getNitzUpdateSpacingMillis()95 int getNitzUpdateSpacingMillis(); 96 97 /** 98 * If Unix epoch time between two NITZ signals is greater than this value then the second 99 * signal cannot be ignored. 100 */ getNitzUpdateDiffMillis()101 int getNitzUpdateDiffMillis(); 102 103 /** 104 * If the device connects to a telephony network and was disconnected from a telephony 105 * network for less than this time, a previously received NITZ signal can be restored. 106 * 107 * <p>The restored NITZ may not be from the same network as the current network. It is 108 * intended to be a relatively small value to allow for brief disconnections. Larger values 109 * increase the likelihood that the device has moved to a different network and/or time 110 * zone. 111 */ getNitzNetworkDisconnectRetentionMillis()112 int getNitzNetworkDisconnectRetentionMillis(); 113 114 /** 115 * Returns true if the {@code gsm.ignore-nitz} system property is set to "yes". 116 */ getIgnoreNitz()117 boolean getIgnoreNitz(); 118 119 /** 120 * Returns the same value as {@link SystemClock#elapsedRealtime()}. 121 */ elapsedRealtimeMillis()122 long elapsedRealtimeMillis(); 123 124 /** 125 * Returns the same value as {@link System#currentTimeMillis()}. 126 */ currentTimeMillis()127 long currentTimeMillis(); 128 } 129 130 /** 131 * The real implementation of {@link DeviceState}. 132 * 133 * {@hide} 134 */ 135 class DeviceStateImpl implements DeviceState { 136 137 /** The default value to use for {@link #getNitzUpdateSpacingMillis()}. 10 minutes. */ 138 private static final int NITZ_UPDATE_SPACING_MILLIS_DEFAULT = 1000 * 60 * 10; 139 private final int mNitzUpdateSpacingMillis; 140 141 /** The default value to use for {@link #getNitzUpdateDiffMillis()}. 2 seconds. */ 142 private static final int NITZ_UPDATE_DIFF_MILLIS_DEFAULT = 2000; 143 private final int mNitzUpdateDiffMillis; 144 145 /** 146 * The default value to use for {@link #getNitzNetworkDisconnectRetentionMillis()}. 147 * 5 minutes. 148 */ 149 private static final int NITZ_NETWORK_DISCONNECT_RETENTION_MILLIS_DEFAULT = 1000 * 60 * 5; 150 private final int mNitzNetworkDisconnectRetentionMillis; 151 152 private final ContentResolver mCr; 153 DeviceStateImpl(Phone phone)154 public DeviceStateImpl(Phone phone) { 155 Context context = phone.getContext(); 156 mCr = context.getContentResolver(); 157 mNitzUpdateSpacingMillis = 158 SystemProperties.getInt("ro.nitz_update_spacing", 159 NITZ_UPDATE_SPACING_MILLIS_DEFAULT); 160 mNitzUpdateDiffMillis = 161 SystemProperties.getInt("ro.nitz_update_diff", NITZ_UPDATE_DIFF_MILLIS_DEFAULT); 162 mNitzNetworkDisconnectRetentionMillis = 163 SystemProperties.getInt("ro.nitz_network_disconnect_retention", 164 NITZ_NETWORK_DISCONNECT_RETENTION_MILLIS_DEFAULT); 165 } 166 167 @Override getNitzUpdateSpacingMillis()168 public int getNitzUpdateSpacingMillis() { 169 return Settings.Global.getInt(mCr, Settings.Global.NITZ_UPDATE_SPACING, 170 mNitzUpdateSpacingMillis); 171 } 172 173 @Override getNitzUpdateDiffMillis()174 public int getNitzUpdateDiffMillis() { 175 return Settings.Global.getInt(mCr, Settings.Global.NITZ_UPDATE_DIFF, 176 mNitzUpdateDiffMillis); 177 } 178 179 @Override getNitzNetworkDisconnectRetentionMillis()180 public int getNitzNetworkDisconnectRetentionMillis() { 181 return Settings.Global.getInt(mCr, Settings.Global.NITZ_NETWORK_DISCONNECT_RETENTION, 182 mNitzNetworkDisconnectRetentionMillis); 183 } 184 185 @Override getIgnoreNitz()186 public boolean getIgnoreNitz() { 187 String ignoreNitz = SystemProperties.get("gsm.ignore-nitz"); 188 return ignoreNitz != null && ignoreNitz.equals("yes"); 189 } 190 191 @Override elapsedRealtimeMillis()192 public long elapsedRealtimeMillis() { 193 return SystemClock.elapsedRealtime(); 194 } 195 196 @Override currentTimeMillis()197 public long currentTimeMillis() { 198 return System.currentTimeMillis(); 199 } 200 } 201 } 202