Loading src/java/com/android/internal/telephony/LocaleTracker.java +110 −103 Original line number Diff line number Diff line Loading @@ -57,13 +57,19 @@ public class LocaleTracker extends Handler { private static final String TAG = LocaleTracker.class.getSimpleName(); /** Event for getting cell info from the modem */ private static final int EVENT_GET_CELL_INFO = 1; /** Event for operator numeric update */ private static final int EVENT_UPDATE_OPERATOR_NUMERIC = 2; private static final int EVENT_REQUEST_CELL_INFO = 1; /** Event for service state changed */ private static final int EVENT_SERVICE_STATE_CHANGED = 3; private static final int EVENT_SERVICE_STATE_CHANGED = 2; /** Event for sim state changed */ private static final int EVENT_SIM_STATE_CHANGED = 3; /** Event for incoming unsolicited cell info */ private static final int EVENT_UNSOL_CELL_INFO = 4; /** Event for incoming cell info */ private static final int EVENT_RESPONSE_CELL_INFO = 5; // Todo: Read this from Settings. /** The minimum delay to get cell info from the modem */ Loading Loading @@ -98,7 +104,9 @@ public class LocaleTracker extends Handler { private String mCurrentCountryIso; /** Current service state. Must be one of ServiceState.STATE_XXX. */ private int mLastServiceState = -1; private int mLastServiceState = ServiceState.STATE_POWER_OFF; private boolean mIsTracking = false; private final LocalLog mLocalLog = new LocalLog(50); Loading @@ -109,8 +117,9 @@ public class LocaleTracker extends Handler { if (TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED.equals(intent.getAction())) { int phoneId = intent.getIntExtra(PhoneConstants.PHONE_KEY, 0); if (phoneId == mPhone.getPhoneId()) { onSimCardStateChanged(intent.getIntExtra(TelephonyManager.EXTRA_SIM_STATE, TelephonyManager.SIM_STATE_UNKNOWN)); obtainMessage(EVENT_SIM_STATE_CHANGED, intent.getIntExtra(TelephonyManager.EXTRA_SIM_STATE, TelephonyManager.SIM_STATE_UNKNOWN), 0).sendToTarget(); } } } Loading @@ -124,19 +133,32 @@ public class LocaleTracker extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case EVENT_GET_CELL_INFO: synchronized (this) { getCellInfo(); updateLocale(); } case EVENT_REQUEST_CELL_INFO: mPhone.getAllCellInfo(null, obtainMessage(EVENT_RESPONSE_CELL_INFO)); break; case EVENT_UPDATE_OPERATOR_NUMERIC: updateOperatorNumericSync((String) msg.obj); case EVENT_UNSOL_CELL_INFO: processCellInfo((AsyncResult) msg.obj); // If the unsol happened to be useful, use it; otherwise, pretend it didn't happen. if (mCellInfo != null && mCellInfo.size() > 0) requestNextCellInfo(true); break; case EVENT_RESPONSE_CELL_INFO: processCellInfo((AsyncResult) msg.obj); // If the cellInfo was non-empty then it's business as usual. Either way, this // cell info was requested by us, so it's our trigger to schedule another one. requestNextCellInfo(mCellInfo != null && mCellInfo.size() > 0); break; case EVENT_SERVICE_STATE_CHANGED: AsyncResult ar = (AsyncResult) msg.obj; onServiceStateChanged((ServiceState) ar.result); break; case EVENT_SIM_STATE_CHANGED: onSimCardStateChanged(msg.arg1); break; default: throw new IllegalStateException("Unexpected message arrives. msg = " + msg.what); } Loading @@ -158,6 +180,7 @@ public class LocaleTracker extends Handler { mPhone.getContext().registerReceiver(mBroadcastReceiver, filter); mPhone.registerForServiceStateChanged(this, EVENT_SERVICE_STATE_CHANGED, null); mPhone.registerForCellInfo(this, EVENT_UNSOL_CELL_INFO, null); } /** Loading @@ -166,7 +189,7 @@ public class LocaleTracker extends Handler { * @return The device's current country. Empty string if the information is not available. */ @NonNull public synchronized String getCurrentCountry() { public String getCurrentCountry() { return (mCurrentCountryIso != null) ? mCurrentCountryIso : ""; } Loading Loading @@ -216,12 +239,9 @@ public class LocaleTracker extends Handler { * @param state SIM card state. Must be one of TelephonyManager.SIM_STATE_XXX. */ private synchronized void onSimCardStateChanged(int state) { if (mSimState != state && state == TelephonyManager.SIM_STATE_ABSENT) { if (DBG) log("Sim absent. Get latest cell info from the modem."); getCellInfo(); updateLocale(); } mSimState = state; updateLocale(); updateTrackingStatus(); } /** Loading @@ -230,71 +250,57 @@ public class LocaleTracker extends Handler { * @param serviceState Service state */ private void onServiceStateChanged(ServiceState serviceState) { int state = serviceState.getState(); if (state != mLastServiceState) { if (state != ServiceState.STATE_POWER_OFF && TextUtils.isEmpty(mOperatorNumeric)) { // When the device is out of airplane mode or powered on, and network's MCC/MNC is // not available, we get cell info from the modem. String msg = "Service state " + ServiceState.rilServiceStateToString(state) + ". Get cell info now."; if (DBG) log(msg); mLocalLog.log(msg); getCellInfo(); } else if (state == ServiceState.STATE_POWER_OFF) { // Clear the cell info when the device is in airplane mode. if (mCellInfo != null) mCellInfo.clear(); stopCellInfoRetry(); } mLastServiceState = serviceState.getState(); updateLocale(); mLastServiceState = state; } updateTrackingStatus(); } /** * Update MCC/MNC from network service state synchronously. Note if this is called from phone * process's main thread and if the update operation requires getting cell info from the modem, * the cached cell info will be used to determine the locale. If the cached cell info is not * acceptable, use {@link #updateOperatorNumericAsync(String)} instead. * Update MCC/MNC from network service state. * * @param operatorNumeric MCC/MNC of the operator */ public synchronized void updateOperatorNumericSync(String operatorNumeric) { public void updateOperatorNumeric(String operatorNumeric) { // Check if the operator numeric changes. if (DBG) log("updateOperatorNumericSync. mcc/mnc=" + operatorNumeric); if (!Objects.equals(mOperatorNumeric, operatorNumeric)) { String msg = "Operator numeric changes to " + operatorNumeric; if (DBG) log(msg); mLocalLog.log(msg); mOperatorNumeric = operatorNumeric; // If the operator numeric becomes unavailable, we need to get the latest cell info so // that we can get MCC from it. if (TextUtils.isEmpty(mOperatorNumeric)) { if (DBG) { log("Operator numeric unavailable. Get latest cell info from the modem."); updateLocale(); } getCellInfo(); } else { // If operator numeric is available, that means we camp on network. So we should // clear the cell info and stop cell info retry. if (mCellInfo != null) mCellInfo.clear(); stopCellInfoRetry(); } updateLocale(); private void processCellInfo(AsyncResult ar) { if (ar == null || ar.exception != null) { mCellInfo = null; return; } mCellInfo = (List<CellInfo>) ar.result; String msg = "getCellInfo: cell info=" + mCellInfo; if (DBG) log(msg); mLocalLog.log(msg); updateLocale(); } /** * Update MCC/MNC from network service state asynchronously. The update operation will run * in locale tracker's handler's thread, which can get cell info synchronously from service * state tracker. Note that the country code will not be available immediately after calling * this method. * * @param operatorNumeric MCC/MNC of the operator */ public void updateOperatorNumericAsync(String operatorNumeric) { if (DBG) log("updateOperatorNumericAsync. mcc/mnc=" + operatorNumeric); sendMessage(obtainMessage(EVENT_UPDATE_OPERATOR_NUMERIC, operatorNumeric)); private void requestNextCellInfo(boolean succeeded) { if (!mIsTracking) return; removeMessages(EVENT_REQUEST_CELL_INFO); if (succeeded) { resetCellInfoRetry(); // Now we need to get the cell info from the modem periodically // even if we already got the cell info because the user can move. removeMessages(EVENT_UNSOL_CELL_INFO); removeMessages(EVENT_RESPONSE_CELL_INFO); sendMessageDelayed(obtainMessage(EVENT_REQUEST_CELL_INFO), CELL_INFO_PERIODIC_POLLING_DELAY_MS); } else { // If we can't get a valid cell info. Try it again later. long delay = getCellInfoDelayTime(++mFailCellInfoCount); if (DBG) log("Can't get cell info. Try again in " + delay / 1000 + " secs."); sendMessageDelayed(obtainMessage(EVENT_REQUEST_CELL_INFO), delay); } } /** Loading @@ -319,52 +325,47 @@ public class LocaleTracker extends Handler { * Stop retrying getting cell info from the modem. It cancels any scheduled cell info retrieving * request. */ private void stopCellInfoRetry() { private void resetCellInfoRetry() { mFailCellInfoCount = 0; removeMessages(EVENT_GET_CELL_INFO); removeMessages(EVENT_REQUEST_CELL_INFO); } /** * Get cell info from the modem. */ private void getCellInfo() { String msg; if (!mPhone.getServiceStateTracker().getDesiredPowerState()) { msg = "Radio is off. Stopped cell info retry. Cleared the previous cached cell info."; if (mCellInfo != null) mCellInfo.clear(); if (DBG) log(msg); mLocalLog.log(msg); stopCellInfoRetry(); return; private void updateTrackingStatus() { boolean shouldTrackLocale = (mSimState == TelephonyManager.SIM_STATE_ABSENT || TextUtils.isEmpty(mOperatorNumeric)) && (mLastServiceState == ServiceState.STATE_OUT_OF_SERVICE || mLastServiceState == ServiceState.STATE_EMERGENCY_ONLY); if (shouldTrackLocale) { startTracking(); } else { stopTracking(); } } // FIXME: This needs to use the async version of getAllCellInfo() mCellInfo = mPhone.getAllCellInfo(); msg = "getCellInfo: cell info=" + mCellInfo; private void stopTracking() { if (!mIsTracking) return; mIsTracking = false; String msg = "Stopping LocaleTracker"; if (DBG) log(msg); mLocalLog.log(msg); if (mCellInfo == null || mCellInfo.size() == 0) { // If we can't get a valid cell info. Try it again later. long delay = getCellInfoDelayTime(++mFailCellInfoCount); if (DBG) log("Can't get cell info. Try again in " + delay / 1000 + " secs."); removeMessages(EVENT_GET_CELL_INFO); sendMessageDelayed(obtainMessage(EVENT_GET_CELL_INFO), delay); } else { // We successfully got cell info from the modem. We should stop cell info retry. stopCellInfoRetry(); // Now we need to get the cell info from the modem periodically even if we already got // the cell info because the user can move. sendMessageDelayed(obtainMessage(EVENT_GET_CELL_INFO), CELL_INFO_PERIODIC_POLLING_DELAY_MS); mCellInfo = null; resetCellInfoRetry(); } private void startTracking() { if (mIsTracking) return; String msg = "Starting LocaleTracker"; mLocalLog.log(msg); if (DBG) log(msg); mIsTracking = true; sendMessage(obtainMessage(EVENT_REQUEST_CELL_INFO)); } /** * Update the device's current locale */ private void updateLocale() { private synchronized void updateLocale() { // If MCC is available from network service state, use it first. String mcc = null; String countryIso = ""; Loading Loading @@ -405,6 +406,11 @@ public class LocaleTracker extends Handler { } } /** Exposed for testing purposes */ public boolean isTracking() { return mIsTracking; } private void log(String msg) { Rlog.d(TAG, msg); } Loading @@ -424,6 +430,7 @@ public class LocaleTracker extends Handler { final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); pw.println("LocaleTracker:"); ipw.increaseIndent(); ipw.println("mIsTracking = " + mIsTracking); ipw.println("mOperatorNumeric = " + mOperatorNumeric); ipw.println("mSimState = " + mSimState); ipw.println("mCellInfo = " + mCellInfo); Loading src/java/com/android/internal/telephony/Phone.java +24 −0 Original line number Diff line number Diff line Loading @@ -348,6 +348,8 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { protected final RegistrantList mEmergencyCallToggledRegistrants = new RegistrantList(); private final RegistrantList mCellInfoRegistrants = new RegistrantList(); protected Registrant mPostDialHandler; private Looper mLooper; /* to insure registrants are in correct thread*/ Loading Loading @@ -873,6 +875,7 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { migrate(mMmiRegistrants, from.mMmiRegistrants); migrate(mUnknownConnectionRegistrants, from.mUnknownConnectionRegistrants); migrate(mSuppServiceFailedRegistrants, from.mSuppServiceFailedRegistrants); migrate(mCellInfoRegistrants, from.mCellInfoRegistrants); if (from.isInEmergencyCall()) { setIsInEmergencyCall(); } Loading Loading @@ -1485,6 +1488,24 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { mCi.unregisterForResendIncallMute(h); } /** * Registers for CellInfo changed. * Message.obj will contain an AsyncResult. * AsyncResult.result will be a List<CellInfo> instance */ public void registerForCellInfo( Handler h, int what, Object obj) { mCellInfoRegistrants.add(h, what, obj); } /** * Unregisters for CellInfo notification. * Extraneous calls are tolerated silently */ public void unregisterForCellInfo(Handler h) { mCellInfoRegistrants.remove(h); } /** * Enables or disables echo suppression. */ Loading Loading @@ -2178,6 +2199,9 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { } public void notifyCellInfo(List<CellInfo> cellInfo) { AsyncResult ar = new AsyncResult(null, cellInfo, null); mCellInfoRegistrants.notifyRegistrants(ar); mNotifier.notifyCellInfo(this, cellInfo); } Loading src/java/com/android/internal/telephony/ServiceStateTracker.java +3 −10 Original line number Diff line number Diff line Loading @@ -37,7 +37,6 @@ import android.os.AsyncResult; import android.os.BaseBundle; import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; import android.os.PersistableBundle; import android.os.Registrant; Loading Loading @@ -278,7 +277,6 @@ public class ServiceStateTracker extends Handler { private final RatRatcheter mRatRatcheter; private final HandlerThread mHandlerThread; private final LocaleTracker mLocaleTracker; private final LocalLog mRoamingLog = new LocalLog(10); Loading Loading @@ -522,12 +520,8 @@ public class ServiceStateTracker extends Handler { this, EVENT_NETWORK_STATE_CHANGED, null); } // Create a new handler thread dedicated for locale tracker because the blocking // getAllCellInfo call requires clients calling from a different thread. mHandlerThread = new HandlerThread(LocaleTracker.class.getSimpleName()); mHandlerThread.start(); mLocaleTracker = TelephonyComponentFactory.getInstance().makeLocaleTracker( mPhone, mHandlerThread.getLooper()); mPhone, getLooper()); mCi.registerForImsNetworkStateChanged(this, EVENT_IMS_STATE_CHANGED, null); mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null); Loading Loading @@ -683,7 +677,6 @@ public class ServiceStateTracker extends Handler { mCi.unregisterForPhysicalChannelConfiguration(this); mSubscriptionManager .removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener); mHandlerThread.quit(); mCi.unregisterForImsNetworkStateChanged(this); mPhone.getCarrierActionAgent().unregisterForCarrierAction(this, CARRIER_ACTION_SET_RADIO_ENABLED); Loading Loading @@ -2994,7 +2987,7 @@ public class ServiceStateTracker extends Handler { // Passing empty string is important for the first update. The initial value of // operator numeric in locale tracker is null. The async update will allow getting // cell info from the modem instead of using the cached one. mLocaleTracker.updateOperatorNumericAsync(""); mLocaleTracker.updateOperatorNumeric(""); mNitzState.handleNetworkUnavailable(); } else if (mSS.getRilDataRadioTechnology() != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN) { // If the device is on IWLAN, modems manufacture a ServiceState with the MCC/MNC of Loading @@ -3006,7 +2999,7 @@ public class ServiceStateTracker extends Handler { setOperatorIdd(operatorNumeric); } mLocaleTracker.updateOperatorNumericSync(operatorNumeric); mLocaleTracker.updateOperatorNumeric(operatorNumeric); String countryIsoCode = mLocaleTracker.getCurrentCountry(); // Update Time Zone. Loading tests/telephonytests/src/com/android/internal/telephony/LocaleTrackerTest.java +58 −57 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
src/java/com/android/internal/telephony/LocaleTracker.java +110 −103 Original line number Diff line number Diff line Loading @@ -57,13 +57,19 @@ public class LocaleTracker extends Handler { private static final String TAG = LocaleTracker.class.getSimpleName(); /** Event for getting cell info from the modem */ private static final int EVENT_GET_CELL_INFO = 1; /** Event for operator numeric update */ private static final int EVENT_UPDATE_OPERATOR_NUMERIC = 2; private static final int EVENT_REQUEST_CELL_INFO = 1; /** Event for service state changed */ private static final int EVENT_SERVICE_STATE_CHANGED = 3; private static final int EVENT_SERVICE_STATE_CHANGED = 2; /** Event for sim state changed */ private static final int EVENT_SIM_STATE_CHANGED = 3; /** Event for incoming unsolicited cell info */ private static final int EVENT_UNSOL_CELL_INFO = 4; /** Event for incoming cell info */ private static final int EVENT_RESPONSE_CELL_INFO = 5; // Todo: Read this from Settings. /** The minimum delay to get cell info from the modem */ Loading Loading @@ -98,7 +104,9 @@ public class LocaleTracker extends Handler { private String mCurrentCountryIso; /** Current service state. Must be one of ServiceState.STATE_XXX. */ private int mLastServiceState = -1; private int mLastServiceState = ServiceState.STATE_POWER_OFF; private boolean mIsTracking = false; private final LocalLog mLocalLog = new LocalLog(50); Loading @@ -109,8 +117,9 @@ public class LocaleTracker extends Handler { if (TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED.equals(intent.getAction())) { int phoneId = intent.getIntExtra(PhoneConstants.PHONE_KEY, 0); if (phoneId == mPhone.getPhoneId()) { onSimCardStateChanged(intent.getIntExtra(TelephonyManager.EXTRA_SIM_STATE, TelephonyManager.SIM_STATE_UNKNOWN)); obtainMessage(EVENT_SIM_STATE_CHANGED, intent.getIntExtra(TelephonyManager.EXTRA_SIM_STATE, TelephonyManager.SIM_STATE_UNKNOWN), 0).sendToTarget(); } } } Loading @@ -124,19 +133,32 @@ public class LocaleTracker extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case EVENT_GET_CELL_INFO: synchronized (this) { getCellInfo(); updateLocale(); } case EVENT_REQUEST_CELL_INFO: mPhone.getAllCellInfo(null, obtainMessage(EVENT_RESPONSE_CELL_INFO)); break; case EVENT_UPDATE_OPERATOR_NUMERIC: updateOperatorNumericSync((String) msg.obj); case EVENT_UNSOL_CELL_INFO: processCellInfo((AsyncResult) msg.obj); // If the unsol happened to be useful, use it; otherwise, pretend it didn't happen. if (mCellInfo != null && mCellInfo.size() > 0) requestNextCellInfo(true); break; case EVENT_RESPONSE_CELL_INFO: processCellInfo((AsyncResult) msg.obj); // If the cellInfo was non-empty then it's business as usual. Either way, this // cell info was requested by us, so it's our trigger to schedule another one. requestNextCellInfo(mCellInfo != null && mCellInfo.size() > 0); break; case EVENT_SERVICE_STATE_CHANGED: AsyncResult ar = (AsyncResult) msg.obj; onServiceStateChanged((ServiceState) ar.result); break; case EVENT_SIM_STATE_CHANGED: onSimCardStateChanged(msg.arg1); break; default: throw new IllegalStateException("Unexpected message arrives. msg = " + msg.what); } Loading @@ -158,6 +180,7 @@ public class LocaleTracker extends Handler { mPhone.getContext().registerReceiver(mBroadcastReceiver, filter); mPhone.registerForServiceStateChanged(this, EVENT_SERVICE_STATE_CHANGED, null); mPhone.registerForCellInfo(this, EVENT_UNSOL_CELL_INFO, null); } /** Loading @@ -166,7 +189,7 @@ public class LocaleTracker extends Handler { * @return The device's current country. Empty string if the information is not available. */ @NonNull public synchronized String getCurrentCountry() { public String getCurrentCountry() { return (mCurrentCountryIso != null) ? mCurrentCountryIso : ""; } Loading Loading @@ -216,12 +239,9 @@ public class LocaleTracker extends Handler { * @param state SIM card state. Must be one of TelephonyManager.SIM_STATE_XXX. */ private synchronized void onSimCardStateChanged(int state) { if (mSimState != state && state == TelephonyManager.SIM_STATE_ABSENT) { if (DBG) log("Sim absent. Get latest cell info from the modem."); getCellInfo(); updateLocale(); } mSimState = state; updateLocale(); updateTrackingStatus(); } /** Loading @@ -230,71 +250,57 @@ public class LocaleTracker extends Handler { * @param serviceState Service state */ private void onServiceStateChanged(ServiceState serviceState) { int state = serviceState.getState(); if (state != mLastServiceState) { if (state != ServiceState.STATE_POWER_OFF && TextUtils.isEmpty(mOperatorNumeric)) { // When the device is out of airplane mode or powered on, and network's MCC/MNC is // not available, we get cell info from the modem. String msg = "Service state " + ServiceState.rilServiceStateToString(state) + ". Get cell info now."; if (DBG) log(msg); mLocalLog.log(msg); getCellInfo(); } else if (state == ServiceState.STATE_POWER_OFF) { // Clear the cell info when the device is in airplane mode. if (mCellInfo != null) mCellInfo.clear(); stopCellInfoRetry(); } mLastServiceState = serviceState.getState(); updateLocale(); mLastServiceState = state; } updateTrackingStatus(); } /** * Update MCC/MNC from network service state synchronously. Note if this is called from phone * process's main thread and if the update operation requires getting cell info from the modem, * the cached cell info will be used to determine the locale. If the cached cell info is not * acceptable, use {@link #updateOperatorNumericAsync(String)} instead. * Update MCC/MNC from network service state. * * @param operatorNumeric MCC/MNC of the operator */ public synchronized void updateOperatorNumericSync(String operatorNumeric) { public void updateOperatorNumeric(String operatorNumeric) { // Check if the operator numeric changes. if (DBG) log("updateOperatorNumericSync. mcc/mnc=" + operatorNumeric); if (!Objects.equals(mOperatorNumeric, operatorNumeric)) { String msg = "Operator numeric changes to " + operatorNumeric; if (DBG) log(msg); mLocalLog.log(msg); mOperatorNumeric = operatorNumeric; // If the operator numeric becomes unavailable, we need to get the latest cell info so // that we can get MCC from it. if (TextUtils.isEmpty(mOperatorNumeric)) { if (DBG) { log("Operator numeric unavailable. Get latest cell info from the modem."); updateLocale(); } getCellInfo(); } else { // If operator numeric is available, that means we camp on network. So we should // clear the cell info and stop cell info retry. if (mCellInfo != null) mCellInfo.clear(); stopCellInfoRetry(); } updateLocale(); private void processCellInfo(AsyncResult ar) { if (ar == null || ar.exception != null) { mCellInfo = null; return; } mCellInfo = (List<CellInfo>) ar.result; String msg = "getCellInfo: cell info=" + mCellInfo; if (DBG) log(msg); mLocalLog.log(msg); updateLocale(); } /** * Update MCC/MNC from network service state asynchronously. The update operation will run * in locale tracker's handler's thread, which can get cell info synchronously from service * state tracker. Note that the country code will not be available immediately after calling * this method. * * @param operatorNumeric MCC/MNC of the operator */ public void updateOperatorNumericAsync(String operatorNumeric) { if (DBG) log("updateOperatorNumericAsync. mcc/mnc=" + operatorNumeric); sendMessage(obtainMessage(EVENT_UPDATE_OPERATOR_NUMERIC, operatorNumeric)); private void requestNextCellInfo(boolean succeeded) { if (!mIsTracking) return; removeMessages(EVENT_REQUEST_CELL_INFO); if (succeeded) { resetCellInfoRetry(); // Now we need to get the cell info from the modem periodically // even if we already got the cell info because the user can move. removeMessages(EVENT_UNSOL_CELL_INFO); removeMessages(EVENT_RESPONSE_CELL_INFO); sendMessageDelayed(obtainMessage(EVENT_REQUEST_CELL_INFO), CELL_INFO_PERIODIC_POLLING_DELAY_MS); } else { // If we can't get a valid cell info. Try it again later. long delay = getCellInfoDelayTime(++mFailCellInfoCount); if (DBG) log("Can't get cell info. Try again in " + delay / 1000 + " secs."); sendMessageDelayed(obtainMessage(EVENT_REQUEST_CELL_INFO), delay); } } /** Loading @@ -319,52 +325,47 @@ public class LocaleTracker extends Handler { * Stop retrying getting cell info from the modem. It cancels any scheduled cell info retrieving * request. */ private void stopCellInfoRetry() { private void resetCellInfoRetry() { mFailCellInfoCount = 0; removeMessages(EVENT_GET_CELL_INFO); removeMessages(EVENT_REQUEST_CELL_INFO); } /** * Get cell info from the modem. */ private void getCellInfo() { String msg; if (!mPhone.getServiceStateTracker().getDesiredPowerState()) { msg = "Radio is off. Stopped cell info retry. Cleared the previous cached cell info."; if (mCellInfo != null) mCellInfo.clear(); if (DBG) log(msg); mLocalLog.log(msg); stopCellInfoRetry(); return; private void updateTrackingStatus() { boolean shouldTrackLocale = (mSimState == TelephonyManager.SIM_STATE_ABSENT || TextUtils.isEmpty(mOperatorNumeric)) && (mLastServiceState == ServiceState.STATE_OUT_OF_SERVICE || mLastServiceState == ServiceState.STATE_EMERGENCY_ONLY); if (shouldTrackLocale) { startTracking(); } else { stopTracking(); } } // FIXME: This needs to use the async version of getAllCellInfo() mCellInfo = mPhone.getAllCellInfo(); msg = "getCellInfo: cell info=" + mCellInfo; private void stopTracking() { if (!mIsTracking) return; mIsTracking = false; String msg = "Stopping LocaleTracker"; if (DBG) log(msg); mLocalLog.log(msg); if (mCellInfo == null || mCellInfo.size() == 0) { // If we can't get a valid cell info. Try it again later. long delay = getCellInfoDelayTime(++mFailCellInfoCount); if (DBG) log("Can't get cell info. Try again in " + delay / 1000 + " secs."); removeMessages(EVENT_GET_CELL_INFO); sendMessageDelayed(obtainMessage(EVENT_GET_CELL_INFO), delay); } else { // We successfully got cell info from the modem. We should stop cell info retry. stopCellInfoRetry(); // Now we need to get the cell info from the modem periodically even if we already got // the cell info because the user can move. sendMessageDelayed(obtainMessage(EVENT_GET_CELL_INFO), CELL_INFO_PERIODIC_POLLING_DELAY_MS); mCellInfo = null; resetCellInfoRetry(); } private void startTracking() { if (mIsTracking) return; String msg = "Starting LocaleTracker"; mLocalLog.log(msg); if (DBG) log(msg); mIsTracking = true; sendMessage(obtainMessage(EVENT_REQUEST_CELL_INFO)); } /** * Update the device's current locale */ private void updateLocale() { private synchronized void updateLocale() { // If MCC is available from network service state, use it first. String mcc = null; String countryIso = ""; Loading Loading @@ -405,6 +406,11 @@ public class LocaleTracker extends Handler { } } /** Exposed for testing purposes */ public boolean isTracking() { return mIsTracking; } private void log(String msg) { Rlog.d(TAG, msg); } Loading @@ -424,6 +430,7 @@ public class LocaleTracker extends Handler { final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); pw.println("LocaleTracker:"); ipw.increaseIndent(); ipw.println("mIsTracking = " + mIsTracking); ipw.println("mOperatorNumeric = " + mOperatorNumeric); ipw.println("mSimState = " + mSimState); ipw.println("mCellInfo = " + mCellInfo); Loading
src/java/com/android/internal/telephony/Phone.java +24 −0 Original line number Diff line number Diff line Loading @@ -348,6 +348,8 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { protected final RegistrantList mEmergencyCallToggledRegistrants = new RegistrantList(); private final RegistrantList mCellInfoRegistrants = new RegistrantList(); protected Registrant mPostDialHandler; private Looper mLooper; /* to insure registrants are in correct thread*/ Loading Loading @@ -873,6 +875,7 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { migrate(mMmiRegistrants, from.mMmiRegistrants); migrate(mUnknownConnectionRegistrants, from.mUnknownConnectionRegistrants); migrate(mSuppServiceFailedRegistrants, from.mSuppServiceFailedRegistrants); migrate(mCellInfoRegistrants, from.mCellInfoRegistrants); if (from.isInEmergencyCall()) { setIsInEmergencyCall(); } Loading Loading @@ -1485,6 +1488,24 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { mCi.unregisterForResendIncallMute(h); } /** * Registers for CellInfo changed. * Message.obj will contain an AsyncResult. * AsyncResult.result will be a List<CellInfo> instance */ public void registerForCellInfo( Handler h, int what, Object obj) { mCellInfoRegistrants.add(h, what, obj); } /** * Unregisters for CellInfo notification. * Extraneous calls are tolerated silently */ public void unregisterForCellInfo(Handler h) { mCellInfoRegistrants.remove(h); } /** * Enables or disables echo suppression. */ Loading Loading @@ -2178,6 +2199,9 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { } public void notifyCellInfo(List<CellInfo> cellInfo) { AsyncResult ar = new AsyncResult(null, cellInfo, null); mCellInfoRegistrants.notifyRegistrants(ar); mNotifier.notifyCellInfo(this, cellInfo); } Loading
src/java/com/android/internal/telephony/ServiceStateTracker.java +3 −10 Original line number Diff line number Diff line Loading @@ -37,7 +37,6 @@ import android.os.AsyncResult; import android.os.BaseBundle; import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; import android.os.PersistableBundle; import android.os.Registrant; Loading Loading @@ -278,7 +277,6 @@ public class ServiceStateTracker extends Handler { private final RatRatcheter mRatRatcheter; private final HandlerThread mHandlerThread; private final LocaleTracker mLocaleTracker; private final LocalLog mRoamingLog = new LocalLog(10); Loading Loading @@ -522,12 +520,8 @@ public class ServiceStateTracker extends Handler { this, EVENT_NETWORK_STATE_CHANGED, null); } // Create a new handler thread dedicated for locale tracker because the blocking // getAllCellInfo call requires clients calling from a different thread. mHandlerThread = new HandlerThread(LocaleTracker.class.getSimpleName()); mHandlerThread.start(); mLocaleTracker = TelephonyComponentFactory.getInstance().makeLocaleTracker( mPhone, mHandlerThread.getLooper()); mPhone, getLooper()); mCi.registerForImsNetworkStateChanged(this, EVENT_IMS_STATE_CHANGED, null); mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null); Loading Loading @@ -683,7 +677,6 @@ public class ServiceStateTracker extends Handler { mCi.unregisterForPhysicalChannelConfiguration(this); mSubscriptionManager .removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener); mHandlerThread.quit(); mCi.unregisterForImsNetworkStateChanged(this); mPhone.getCarrierActionAgent().unregisterForCarrierAction(this, CARRIER_ACTION_SET_RADIO_ENABLED); Loading Loading @@ -2994,7 +2987,7 @@ public class ServiceStateTracker extends Handler { // Passing empty string is important for the first update. The initial value of // operator numeric in locale tracker is null. The async update will allow getting // cell info from the modem instead of using the cached one. mLocaleTracker.updateOperatorNumericAsync(""); mLocaleTracker.updateOperatorNumeric(""); mNitzState.handleNetworkUnavailable(); } else if (mSS.getRilDataRadioTechnology() != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN) { // If the device is on IWLAN, modems manufacture a ServiceState with the MCC/MNC of Loading @@ -3006,7 +2999,7 @@ public class ServiceStateTracker extends Handler { setOperatorIdd(operatorNumeric); } mLocaleTracker.updateOperatorNumericSync(operatorNumeric); mLocaleTracker.updateOperatorNumeric(operatorNumeric); String countryIsoCode = mLocaleTracker.getCurrentCountry(); // Update Time Zone. Loading
tests/telephonytests/src/com/android/internal/telephony/LocaleTrackerTest.java +58 −57 File changed.Preview size limit exceeded, changes collapsed. Show changes