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.os.TimestampedValue; 25 import android.provider.Settings; 26 27 import com.android.internal.util.IndentingPrintWriter; 28 29 import java.io.FileDescriptor; 30 import java.io.PrintWriter; 31 32 /** 33 * An interface for the Android component that handles NITZ and related signals for time and time 34 * zone detection. 35 * 36 * {@hide} 37 */ 38 public interface NitzStateMachine { 39 40 /** 41 * Called when the country suitable for time zone detection is detected. 42 * 43 * @param countryIsoCode the countryIsoCode to use for time zone detection, may be "" for test 44 * cells only, otherwise {@link #handleCountryUnavailable()} should be called 45 */ handleCountryDetected(@onNull String countryIsoCode)46 void handleCountryDetected(@NonNull String countryIsoCode); 47 48 /** 49 * Informs the {@link NitzStateMachine} that the network has become available. 50 */ handleNetworkAvailable()51 void handleNetworkAvailable(); 52 53 /** 54 * Informs the {@link NitzStateMachine} that the network has become unavailable. Any network 55 * state, i.e. NITZ, should be cleared. 56 */ handleNetworkUnavailable()57 void handleNetworkUnavailable(); 58 59 /** 60 * Informs the {@link NitzStateMachine} that any previously detected country supplied via 61 * {@link #handleCountryDetected(String)} is no longer valid. 62 */ handleCountryUnavailable()63 void handleCountryUnavailable(); 64 65 /** 66 * Handle a new NITZ signal being received. 67 */ handleNitzReceived(@onNull TimestampedValue<NitzData> nitzSignal)68 void handleNitzReceived(@NonNull TimestampedValue<NitzData> nitzSignal); 69 70 /** 71 * Handle the user putting the device into or out of airplane mode 72 * @param on true if airplane mode has been turned on, false if it's been turned off. 73 */ handleAirplaneModeChanged(boolean on)74 void handleAirplaneModeChanged(boolean on); 75 76 /** 77 * Dumps the current in-memory state to the supplied PrintWriter. 78 */ dumpState(PrintWriter pw)79 void dumpState(PrintWriter pw); 80 81 /** 82 * Dumps the time / time zone logs to the supplied IndentingPrintWriter. 83 */ dumpLogs(FileDescriptor fd, IndentingPrintWriter ipw, String[] args)84 void dumpLogs(FileDescriptor fd, IndentingPrintWriter ipw, String[] args); 85 86 /** 87 * A proxy over read-only device state that allows things like system properties, elapsed 88 * realtime clock to be faked for tests. 89 */ 90 interface DeviceState { 91 92 /** 93 * If time between NITZ updates is less than {@link #getNitzUpdateSpacingMillis()} the 94 * update may be ignored. 95 */ getNitzUpdateSpacingMillis()96 int getNitzUpdateSpacingMillis(); 97 98 /** 99 * If {@link #getNitzUpdateSpacingMillis()} hasn't been exceeded but update is > 100 * {@link #getNitzUpdateDiffMillis()} do the update 101 */ getNitzUpdateDiffMillis()102 int getNitzUpdateDiffMillis(); 103 104 /** 105 * Returns true if the {@code gsm.ignore-nitz} system property is set to "yes". 106 */ getIgnoreNitz()107 boolean getIgnoreNitz(); 108 109 /** 110 * Returns the same value as {@link SystemClock#elapsedRealtime()}. 111 */ elapsedRealtime()112 long elapsedRealtime(); 113 114 /** 115 * Returns the same value as {@link System#currentTimeMillis()}. 116 */ currentTimeMillis()117 long currentTimeMillis(); 118 } 119 120 /** 121 * The real implementation of {@link DeviceState}. 122 * 123 * {@hide} 124 */ 125 class DeviceStateImpl implements DeviceState { 126 private static final int NITZ_UPDATE_SPACING_DEFAULT = 1000 * 60 * 10; 127 private final int mNitzUpdateSpacing; 128 129 private static final int NITZ_UPDATE_DIFF_DEFAULT = 2000; 130 private final int mNitzUpdateDiff; 131 132 private final ContentResolver mCr; 133 DeviceStateImpl(Phone phone)134 public DeviceStateImpl(Phone phone) { 135 Context context = phone.getContext(); 136 mCr = context.getContentResolver(); 137 mNitzUpdateSpacing = 138 SystemProperties.getInt("ro.nitz_update_spacing", NITZ_UPDATE_SPACING_DEFAULT); 139 mNitzUpdateDiff = 140 SystemProperties.getInt("ro.nitz_update_diff", NITZ_UPDATE_DIFF_DEFAULT); 141 } 142 143 @Override getNitzUpdateSpacingMillis()144 public int getNitzUpdateSpacingMillis() { 145 return Settings.Global.getInt(mCr, Settings.Global.NITZ_UPDATE_SPACING, 146 mNitzUpdateSpacing); 147 } 148 149 @Override getNitzUpdateDiffMillis()150 public int getNitzUpdateDiffMillis() { 151 return Settings.Global.getInt(mCr, Settings.Global.NITZ_UPDATE_DIFF, mNitzUpdateDiff); 152 } 153 154 @Override getIgnoreNitz()155 public boolean getIgnoreNitz() { 156 String ignoreNitz = SystemProperties.get("gsm.ignore-nitz"); 157 return ignoreNitz != null && ignoreNitz.equals("yes"); 158 } 159 160 @Override elapsedRealtime()161 public long elapsedRealtime() { 162 return SystemClock.elapsedRealtime(); 163 } 164 165 @Override currentTimeMillis()166 public long currentTimeMillis() { 167 return System.currentTimeMillis(); 168 } 169 } 170 } 171