blob: 9d08fc0ab522e6794c6ec03d9e96a3349d30902e [file] [log] [blame]
package com.android.contacts.location;
import android.content.Context;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import java.util.Locale;
/**
* This class is used to detect the country where the user is. It is a simplified version of the
* country detector service in the framework. The sources of country location are queried in the
* following order of reliability:
* <ul>
* <li>Mobile network</li>
* <li>SIM's country</li>
* <li>User's default locale</li>
* </ul>
*
* As far as possible this class tries to replicate the behavior of the system's country detector
* service:
* 1) Order in priority of sources of country location
* 2) Mobile network information provided by CDMA phones is ignored
*/
public class CountryDetector {
private static final String TAG = "CountryDetector";
private static CountryDetector sInstance;
private final Context mContext;
private final LocaleProvider mLocaleProvider;
private final TelephonyManager mTelephonyManager;
// Used as a default country code when all the sources of country data have failed in the
// exceedingly rare event that the device does not have a default locale set for some reason.
private final String DEFAULT_COUNTRY_ISO = "US";
/**
* Class that can be used to return the user's default locale. This is in its own class so that
* it can be mocked out.
*/
public static class LocaleProvider {
public Locale getDefaultLocale() {
return Locale.getDefault();
}
}
private CountryDetector(Context context) {
this (context, (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE),
new LocaleProvider());
}
private CountryDetector(Context context, TelephonyManager telephonyManager,
LocaleProvider localeProvider) {
mTelephonyManager = telephonyManager;
mLocaleProvider = localeProvider;
mContext = context;
}
/**
* Factory method for {@link CountryDetector} that allows the caller to provide mock objects.
*/
public CountryDetector getInstanceForTest(Context context, TelephonyManager telephonyManager,
LocaleProvider localeProvider) {
return new CountryDetector(context, telephonyManager, localeProvider);
}
/**
* Returns the instance of the country detector. {@link #initialize(Context)} must have been
* called previously.
*
* @return the initialized country detector.
*/
public synchronized static CountryDetector getInstance(Context context) {
if (sInstance == null) {
sInstance = new CountryDetector(context.getApplicationContext());
}
return sInstance;
}
public String getCurrentCountryIso() {
String result = null;
if (isNetworkCountryCodeAvailable()) {
result = getNetworkBasedCountryIso();
}
if (TextUtils.isEmpty(result)) {
result = getSimBasedCountryIso();
}
if (TextUtils.isEmpty(result)) {
result = getLocaleBasedCountryIso();
}
if (TextUtils.isEmpty(result)) {
result = DEFAULT_COUNTRY_ISO;
}
return result.toUpperCase(Locale.US);
}
/**
* @return the country code of the current telephony network the user is connected to.
*/
private String getNetworkBasedCountryIso() {
return mTelephonyManager.getNetworkCountryIso();
}
/**
* @return the country code of the SIM card currently inserted in the device.
*/
private String getSimBasedCountryIso() {
return mTelephonyManager.getSimCountryIso();
}
/**
* @return the country code of the user's currently selected locale.
*/
private String getLocaleBasedCountryIso() {
Locale defaultLocale = mLocaleProvider.getDefaultLocale();
if (defaultLocale != null) {
return defaultLocale.getCountry();
}
return null;
}
private boolean isNetworkCountryCodeAvailable() {
// On CDMA TelephonyManager.getNetworkCountryIso() just returns the SIM's country code.
return mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM;
}
}