Promote MccTable to telephony and use it for both gsm/cdma

This adds timezone/locale/wifi-regulator-channels initialization to cdma (gsm already had it).

bug: 2071211
This commit is contained in:
Robert Greenwalt
2009-09-01 09:44:43 -07:00
parent e1da8be501
commit 1c1ffa0cab
9 changed files with 173 additions and 150 deletions

View File

@@ -31,7 +31,7 @@ import java.util.ArrayList;
public abstract class IccRecords extends Handler implements IccConstants {
protected static final boolean DBG = true;
//***** Instance Variables
// ***** Instance Variables
protected PhoneBase phone;
protected RegistrantList recordsLoadedRegistrants = new RegistrantList();
@@ -40,7 +40,7 @@ public abstract class IccRecords extends Handler implements IccConstants {
protected AdnRecordCache adnCache;
//***** Cached SIM State; cleared on channel close
// ***** Cached SIM State; cleared on channel close
protected boolean recordsRequested = false; // true if we've made requests for the sim records
@@ -54,23 +54,26 @@ public abstract class IccRecords extends Handler implements IccConstants {
protected boolean isVoiceMailFixed = false;
protected int countVoiceMessages = 0;
protected int mncLength = 0; // 0 is used to indicate that the value
// is not initialized
protected int mncLength = UNINITIALIZED;
protected int mailboxIndex = 0; // 0 is no mailbox dailing number associated
protected String spn;
protected int spnDisplayCondition;
//***** Constants
// ***** Constants
// Markers for mncLength
protected static final int UNINITIALIZED = -1;
protected static final int UNKNOWN = 0;
// Bitmasks for SPN display rules.
protected static final int SPN_RULE_SHOW_SPN = 0x01;
protected static final int SPN_RULE_SHOW_PLMN = 0x02;
//***** Event Constants
// ***** Event Constants
protected static final int EVENT_SET_MSISDN_DONE = 30;
//***** Constructor
// ***** Constructor
public IccRecords(PhoneBase p) {
this.phone = p;
@@ -234,4 +237,3 @@ public abstract class IccRecords extends Handler implements IccConstants {
protected abstract void log(String s);
}

View File

@@ -14,7 +14,17 @@
* limitations under the License.
*/
package com.android.internal.telephony.gsm;
package com.android.internal.telephony;
import android.app.ActivityManagerNative;
import android.app.AlarmManager;
import android.content.Context;
import android.content.res.Configuration;
import android.net.wifi.WifiManager;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.provider.Settings;
import android.util.Log;
import java.util.Arrays;
@@ -475,8 +485,10 @@ public final class MccTable
0x65630400, 0x67660400, 0x70790400, 0x73720400, 0x75790400, 0x666b0400
};
static final String LOG_TAG = "MccTable";
/**
* Given a GSM Mobile Country Code, returns a default time zone ID
* Given a Mobile Country Code, returns a default time zone ID
* if available. Returns null if unavailable.
*/
public static String defaultTimeZoneForMcc(int mcc) {
@@ -494,7 +506,7 @@ public final class MccTable
}
/**
* Given a GSM Mobile Country Code, returns an ISO two-character
* Given a Mobile Country Code, returns an ISO two-character
* country code if available. Returns "" if unavailable.
*/
public static String countryCodeForMcc(int mcc) {
@@ -553,4 +565,95 @@ public final class MccTable
return wifi;
}
/**
* Updates MCC and MNC device configuration information for application retrieving
* correct version of resources. If either MCC or MNC is 0, they will be ignored (not set).
* @param phone PhoneBae to act on.
* @param mccmnc truncated imsi with just the MCC and MNC - MNC assumed to be from 4th to end
*/
public static void updateMccMncConfiguration(PhoneBase phone, String mccmnc) {
Configuration config = new Configuration();
int mcc, mnc;
try {
mcc = Integer.parseInt(mccmnc.substring(0,3));
mnc = Integer.parseInt(mccmnc.substring(3));
} catch (NumberFormatException e) {
Log.e(LOG_TAG, "Error parsing IMSI");
return;
}
Log.d(LOG_TAG, "updateMccMncConfiguration: mcc=" + mcc + ", mnc=" + mnc);
if (mcc != 0) {
config.mcc = mcc;
setTimezoneFromMccIfNeeded(phone, mcc);
setLocaleFromMccIfNeeded(phone, mcc);
setWifiChannelsFromMccIfNeeded(phone, mcc);
}
if (mnc != 0) {
config.mnc = mnc;
}
try {
ActivityManagerNative.getDefault().updateConfiguration(config);
} catch (RemoteException e) {
Log.e(LOG_TAG, "Can't update configuration", e);
}
}
/**
* If the timezone is not already set, set it based on the MCC of the SIM.
* @param phone PhoneBase to act on (get context from).
* @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA)
*/
private static void setTimezoneFromMccIfNeeded(PhoneBase phone, int mcc) {
String timezone = SystemProperties.get(ServiceStateTracker.TIMEZONE_PROPERTY);
if (timezone == null || timezone.length() == 0) {
String zoneId = defaultTimeZoneForMcc(mcc);
if (zoneId != null && zoneId.length() > 0) {
Context context = phone.getContext();
// Set time zone based on MCC
AlarmManager alarm =
(AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarm.setTimeZone(zoneId);
Log.d(LOG_TAG, "timezone set to "+zoneId);
}
}
}
/**
* If the locale is not already set, set it based on the MCC of the SIM.
* @param phone PhoneBase to act on.
* @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA)
*/
private static void setLocaleFromMccIfNeeded(PhoneBase phone, int mcc) {
String language = MccTable.defaultLanguageForMcc(mcc);
String country = MccTable.countryCodeForMcc(mcc);
Log.d(LOG_TAG, "locale set to "+language+"_"+country);
phone.setSystemLocale(language, country);
}
/**
* If the number of allowed wifi channels has not been set, set it based on
* the MCC of the SIM.
* @param phone PhoneBase to act on (get context from).
* @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA)
*/
private static void setWifiChannelsFromMccIfNeeded(PhoneBase phone, int mcc) {
int wifiChannels = MccTable.wifiChannelsForMcc(mcc);
if (wifiChannels != 0) {
Context context = phone.getContext();
// only set to this default if the user hasn't manually set it
try {
Settings.Secure.getInt(context.getContentResolver(),
Settings.Secure.WIFI_NUM_ALLOWED_CHANNELS);
} catch (Settings.SettingNotFoundException e) {
Log.d(LOG_TAG, "WIFI_NUM_ALLOWED_CHANNESL set to " + wifiChannels);
WifiManager wM = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
// don't persist
wM.setNumAllowedChannels(wifiChannels, false);
}
}
}
}

View File

@@ -48,10 +48,7 @@ import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.DataConnection;
// TODO(Moto): need to move MccTable from telephony.gsm to telephony
// since there is no difference between CDMA and GSM for MccTable and
// CDMA uses gsm's MccTable is not good.
import com.android.internal.telephony.gsm.MccTable;
import com.android.internal.telephony.MccTable;
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.IccException;
import com.android.internal.telephony.IccFileHandler;
@@ -203,7 +200,7 @@ public class CDMAPhone extends PhoneBase {
updateCurrentCarrierInProvider(operatorNumeric);
// Updates MCC MNC device configuration information
updateMccMncConfiguration(operatorNumeric);
MccTable.updateMccMncConfiguration(this, operatorNumeric);
// Notify voicemails.
@@ -1406,21 +1403,4 @@ public class CDMAPhone extends PhoneBase {
return false;
}
/**
* Updates MCC and MNC device configuration information for application retrieving
* correct version of resources
*
*/
private void updateMccMncConfiguration(String operatorNumeric) {
if (operatorNumeric.length() >= 5) {
Configuration config = new Configuration();
config.mcc = Integer.parseInt(operatorNumeric.substring(0,3));
config.mnc = Integer.parseInt(operatorNumeric.substring(3));
try {
ActivityManagerNative.getDefault().updateConfiguration(config);
} catch (RemoteException e) {
Log.e(LOG_TAG, "Can't update configuration", e);
}
}
}
}

View File

@@ -45,9 +45,8 @@ import android.util.TimeUtils;
import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.gsm.MccTable;
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.MccTable;
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.TelephonyEventLog;
import com.android.internal.telephony.TelephonyIntents;

View File

@@ -28,7 +28,7 @@ import com.android.internal.telephony.AdnRecordLoader;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.telephony.cdma.RuimCard;
import com.android.internal.telephony.gsm.MccTable;
import com.android.internal.telephony.MccTable;
// can't be used since VoiceMailConstants is not public
//import com.android.internal.telephony.gsm.VoiceMailConstants;
@@ -47,7 +47,7 @@ public final class RuimRecords extends IccRecords {
private static final boolean DBG = true;
private boolean m_ota_commited=false;
//***** Instance Variables
// ***** Instance Variables
private String mImsi;
private String mMyMobileNumber;
@@ -55,7 +55,7 @@ public final class RuimRecords extends IccRecords {
private String mPrlVersion;
//***** Event Constants
// ***** Event Constants
private static final int EVENT_RUIM_READY = 1;
private static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 2;
@@ -109,7 +109,7 @@ public final class RuimRecords extends IccRecords {
@Override
protected void onRadioOffOrNotAvailable() {
countVoiceMessages = 0;
mncLength = 0;
mncLength = UNINITIALIZED;
iccid = null;
adnCache.reset();
@@ -167,7 +167,7 @@ public final class RuimRecords extends IccRecords {
}
// TODO(Moto): mncLength is not set anywhere.
if (mncLength != 0) {
if (mncLength != UNINITIALIZED && mncLength != UNKNOWN) {
// Length = length of MCC + length of MNC
// TODO: change spec name
// length of mcc = 3 (3GPP2 C.S0005 - Section 2.3)

View File

@@ -49,6 +49,7 @@ import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.MccTable;
import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.TelephonyEventLog;

View File

@@ -19,13 +19,10 @@ package com.android.internal.telephony.gsm;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
import android.app.AlarmManager;
import android.content.Context;
import android.net.wifi.WifiManager;
import android.os.AsyncResult;
import android.os.Message;
import android.os.SystemProperties;
import android.provider.Settings;
import android.util.Log;
import com.android.internal.telephony.AdnRecord;
@@ -37,6 +34,7 @@ import com.android.internal.telephony.IccRecords;
import com.android.internal.telephony.IccUtils;
import com.android.internal.telephony.IccVmFixedException;
import com.android.internal.telephony.IccVmNotSupportedException;
import com.android.internal.telephony.MccTable;
import java.util.ArrayList;
@@ -51,14 +49,14 @@ public final class SIMRecords extends IccRecords {
private static final boolean DBG = true;
//***** Instance Variables
// ***** Instance Variables
VoiceMailConstants mVmConfig;
SpnOverride mSpnOverride;
//***** Cached SIM State; cleared on channel close
// ***** Cached SIM State; cleared on channel close
String imsi;
boolean callForwardingEnabled;
@@ -88,7 +86,7 @@ public final class SIMRecords extends IccRecords {
String pnnHomeName = null;
//***** Constants
// ***** Constants
// Bitmasks for SPN display rules.
static final int SPN_RULE_SHOW_SPN = 0x01;
@@ -113,7 +111,7 @@ public final class SIMRecords extends IccRecords {
private static final int CPHS_SST_MBN_MASK = 0x30;
private static final int CPHS_SST_MBN_ENABLED = 0x30;
//***** Event Constants
// ***** Event Constants
private static final int EVENT_SIM_READY = 1;
private static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 2;
@@ -143,9 +141,7 @@ public final class SIMRecords extends IccRecords {
private static final int EVENT_SIM_REFRESH = 31;
private static final int EVENT_GET_CFIS_DONE = 32;
private static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
//***** Constructor
// ***** Constructor
SIMRecords(GSMPhone p) {
super(p);
@@ -188,7 +184,7 @@ public final class SIMRecords extends IccRecords {
msisdn = null;
voiceMailNum = null;
countVoiceMessages = 0;
mncLength = 0;
mncLength = UNINITIALIZED;
iccid = null;
// -1 means no EF_SPN found; treat accordingly.
spnDisplayCondition = -1;
@@ -453,79 +449,16 @@ public final class SIMRecords extends IccRecords {
* provided the SIM card. Returns null of SIM is not yet ready
*/
String getSIMOperatorNumeric() {
if (imsi == null) {
if (imsi == null || mncLength == UNINITIALIZED || mncLength == UNKNOWN) {
return null;
}
if (mncLength != 0) {
// Length = length of MCC + length of MNC
// length of mcc = 3 (TS 23.003 Section 2.2)
return imsi.substring(0, 3 + mncLength);
}
// Guess the MNC length based on the MCC if we don't
// have a valid value in ef[ad]
int mcc;
mcc = Integer.parseInt(imsi.substring(0,3));
return imsi.substring(0, 3 + MccTable.smallestDigitsMccForMnc(mcc));
// Length = length of MCC + length of MNC
// length of mcc = 3 (TS 23.003 Section 2.2)
return imsi.substring(0, 3 + mncLength);
}
/**
* If the timezone is not already set, set it based on the MCC of the SIM.
* @param mcc Mobile Country Code of the SIM
*/
private void setTimezoneFromMccIfNeeded(int mcc) {
String timezone = SystemProperties.get(TIMEZONE_PROPERTY);
if (timezone == null || timezone.length() == 0) {
String zoneId = MccTable.defaultTimeZoneForMcc(mcc);
if (zoneId != null && zoneId.length() > 0) {
// Set time zone based on MCC
AlarmManager alarm =
(AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE);
alarm.setTimeZone(zoneId);
}
}
}
/**
* If the locale is not already set, set it based on the MCC of the SIM.
* @param mcc Mobile Country Code of the SIM
*/
private void setLocaleFromMccIfNeeded(int mcc) {
String language = MccTable.defaultLanguageForMcc(mcc);
String country = MccTable.countryCodeForMcc(mcc);
phone.setSystemLocale(language, country);
}
/**
* If the number of allowed wifi channels has not been set, set it based on
* the MCC of the SIM.
* @param mcc Mobile Country Code of the SIM
*/
private void setWifiChannelsFromMccIfNeeded(int mcc) {
int wifiChannels = MccTable.wifiChannelsForMcc(mcc);
if (wifiChannels != 0) {
Context context = phone.getContext();
// only set to this default if the user hasn't manually set it
try {
Settings.Secure.getInt(context.getContentResolver(),
Settings.Secure.WIFI_NUM_ALLOWED_CHANNELS);
} catch (Settings.SettingNotFoundException e) {
WifiManager wM = (WifiManager)
context.getSystemService(Context.WIFI_SERVICE);
// don't persist
wM.setNumAllowedChannels(wifiChannels, false);
}
}
}
//***** Overridden from Handler
// ***** Overridden from Handler
public void handleMessage(Message msg) {
AsyncResult ar;
AdnRecord adn;
@@ -564,14 +497,25 @@ public final class SIMRecords extends IccRecords {
}
Log.d(LOG_TAG, "IMSI: " + imsi.substring(0, 6) + "xxxxxxxxx");
((GSMPhone) phone).mSimCard.updateImsiConfiguration(imsi);
if (mncLength == UNKNOWN) {
// the SIM has told us all it knows, but it didn't know the mnc length.
// guess using the mcc
try {
int mcc = Integer.parseInt(imsi.substring(0,3));
mncLength = MccTable.smallestDigitsMccForMnc(mcc);
} catch (NumberFormatException e) {
mncLength = UNKNOWN;
Log.e(LOG_TAG, "SIMRecords: Corrupt IMSI!");
}
}
if (mncLength != UNKNOWN && mncLength != UNINITIALIZED) {
// finally have both the imsi and the mncLength and can parse the imsi properly
MccTable.updateMccMncConfiguration(phone, imsi.substring(0, 3 + mncLength));
}
((GSMPhone) phone).mSimCard.broadcastIccStateChangedIntent(
SimCard.INTENT_VALUE_ICC_IMSI, null);
int mcc = Integer.parseInt(imsi.substring(0, 3));
setTimezoneFromMccIfNeeded(mcc);
setLocaleFromMccIfNeeded(mcc);
setWifiChannelsFromMccIfNeeded(mcc);
break;
case EVENT_GET_MBI_DONE:
@@ -794,12 +738,25 @@ public final class SIMRecords extends IccRecords {
mncLength = (int)data[3] & 0xf;
if (mncLength == 0xf) {
// Resetting mncLength to 0 to indicate that it is not
// initialised
mncLength = 0;
if (imsi != null) {
try {
int mcc = Integer.parseInt(imsi.substring(0,3));
Log.d(LOG_TAG, "SIMRecords: MNC length not present in EF_AD");
break;
mncLength = MccTable.smallestDigitsMccForMnc(mcc);
} catch (NumberFormatException e) {
mncLength = UNKNOWN;
Log.e(LOG_TAG, "SIMRecords: Corrupt IMSI!");
}
} else {
// Indicate we got this info, but it didn't contain the length.
mncLength = UNKNOWN;
Log.d(LOG_TAG, "SIMRecords: MNC length not present in EF_AD");
}
}
if (imsi != null && mncLength != UNKNOWN) {
// finally have both imsi and the length of the mnc and can parse it properly
MccTable.updateMccMncConfiguration(phone, imsi.substring(0, 3 + mncLength));
}
break;

View File

@@ -16,9 +16,6 @@
package com.android.internal.telephony.gsm;
import android.app.ActivityManagerNative;
import android.content.res.Configuration;
import android.os.RemoteException;
import android.util.Log;
import com.android.internal.telephony.IccCard;
@@ -50,20 +47,4 @@ public final class SimCard extends IccCard {
return ((GSMPhone)mPhone).mSIMRecords.getServiceProviderName();
}
public void updateImsiConfiguration(String imsi) {
if (imsi.length() >= 6) {
Configuration config = new Configuration();
config.mcc = ((imsi.charAt(0)-'0')*100)
+ ((imsi.charAt(1)-'0')*10)
+ (imsi.charAt(2)-'0');
config.mnc = ((imsi.charAt(3)-'0')*100)
+ ((imsi.charAt(4)-'0')*10)
+ (imsi.charAt(5)-'0');
try {
ActivityManagerNative.getDefault().updateConfiguration(config);
} catch (RemoteException e) {
Log.e(mLogTag, "[SimCard] Remote Exception when updating imsi configuration");
}
}
}
}

View File

@@ -16,7 +16,7 @@
package com.android.unit_tests;
import com.android.internal.telephony.gsm.MccTable;
import com.android.internal.telephony.MccTable;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;