搜网列表显示由 NetworkSettingList.java 的getNetworkTitle方法实现
private String getNetworkTitle(OperatorInfo ni) {
if (!TextUtils.isEmpty(ni.getOperatorAlphaLong())) {
return ni.getOperatorAlphaLong();
} else if (!TextUtils.isEmpty(ni.getOperatorAlphaShort())) {
return ni.getOperatorAlphaShort();
} else {
return ni.getOperatorNumeric();
}
}
OperatorInfo 由 networksListLoaded()传过来
/**
* networksListLoaded has been rewritten to take an array of
* OperatorInfo objects and a status field, instead of an
* AsyncResult. Otherwise, the functionality which takes the
* OperatorInfo array and creates a list of preferences from it,
* remains unchanged.
*/
private void networksListLoaded(List result, int status) {
if (DBG) {
log("networks list loaded");
}
// update the state of the preferences.
if (DBG) {
log("hideProgressPanel");
}
/// M: add for dismiss the dialog is showing @{
removeDialog(DIALOG_NETWORK_LIST_LOAD);
setScreenEnabled(true);
/// @}
clearList();
/// M: service query done.
mIsServiceQueryDone = true;
if (status != NetworkQueryService.QUERY_OK) {
if (DBG) {
log("error while querying available networks");
}
displayNetworkQueryFailed(status);
displayEmptyNetworkList(true);
} else {
if (result != null) {
displayEmptyNetworkList(false);
// create a preference for each item in the list.
// just use the operator name instead of the mildly
// confusing mcc/mnc.
/// M: add forbidden at the end of operator name
int forbiddenCount = 0;
for (OperatorInfo ni : result) {
Preference carrier = new Preference(this, null);
/// M: add forbidden at the end of operator name @{
String forbidden = "";
if (ni.getState() == OperatorInfo.State.FORBIDDEN) {
forbidden = "(" + getResources().getString(R.string.network_forbidden) + ")";
forbiddenCount++;
}
//增加搜网列表网络的其他状态
if(com.mediatek.common.featureoption.FeatureOption.CKT_CUSTOMIZE_COMMON_NETWORK_LIST_DISPLAY){
if (ni.getState() == OperatorInfo.State.AVAILABLE) {
forbidden = "(" + getResources().getString(R.string.network_available) + ")";
//forbiddenCount++;
}
if (ni.getState() == OperatorInfo.State.CURRENT) {
forbidden = "(" + getResources().getString(R.string.network_current) + ")";
//forbiddenCount++;
}
if (ni.getState() == OperatorInfo.State.UNKNOWN) {
forbidden = "(" + getResources().getString(R.string.network_unknown) + ")";
//forbiddenCount++;
}
}
if(com.mediatek.common.featureoption.FeatureOption.CKT_CUSTOMIZE_RUSSIA_NETWORK_DISPLAY){
if (ni.getState() == OperatorInfo.State.FORBIDDEN) {
carrier.setIcon(R.drawable.ic_net_disable);
}
if (ni.getState() == OperatorInfo.State.AVAILABLE) {
carrier.setIcon(R.drawable.ic_net_available);
}
if (ni.getState() == OperatorInfo.State.CURRENT) {
carrier.setIcon(R.drawable.ic_net_present);
}
if (ni.getState() == OperatorInfo.State.UNKNOWN) {
carrier.setIcon(R.drawable.ic_net_unknown);
}
carrier.setLayoutResource(R.layout.preference_list);
}
carrier.setTitle(getNetworkTitle(ni) + forbidden);
carrier.setPersistent(false);
mNetworkList.addPreference(carrier);
mNetworkMap.put(carrier, ni);
/// M: add forbidden at the end of operator name @{
if (forbiddenCount == result.size()) {
showDialog(DIALOG_ALL_FORBIDDEN);
}
/// @}
if (DBG) {
log(" " + ni);
}
}
} else {
displayEmptyNetworkList(true);
}
}
/// M: add for dismiss the dialog is showing @{
try {
mNetworkQueryService.stopNetworkQuery(mCallback);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
/// @}
}
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
AsyncResult ar;
switch (msg.what) {
case EVENT_NETWORK_SCAN_COMPLETED:
/// M: add for gemini phone @{
log("EVENT_NETWORK_SCAN_COMPLETED" + " || mSlotId:" + mSlotId);
if (GeminiUtils.isGeminiSupport() && mSlotId != PhoneConstants.GEMINI_SIM_1) {
return;
}
/// @}
networksListLoaded((List
)msg.obj, msg.arg1);
break;
/// M: add for gemini phone @{
case EVENT_NETWORK_SCAN_COMPLETED_2:
log("EVENT_NETWORK_SCAN_COMPLETED_2" + " || mSlotId:" + mSlotId);
//see if we need to do any work
if (GeminiUtils.isGeminiSupport() && mSlotId != PhoneConstants.GEMINI_SIM_2) {
return;
}
networksListLoaded((List)msg.obj, msg.arg1);
break;
/// @}
case EVENT_NETWORK_SCAN_COMPLETED_3:
log("EVENT_NETWORK_SCAN_COMPLETED_3" + " || mSlotId:" + mSlotId);
//see if we need to do any work
if (GeminiUtils.isGeminiSupport() && mSlotId != PhoneConstants.GEMINI_SIM_3) {
return;
}
networksListLoaded((List)msg.obj, msg.arg1);
break;
case EVENT_NETWORK_SCAN_COMPLETED_4:
log("EVENT_NETWORK_SCAN_COMPLETED_4" + " || mSlotId:" + mSlotId);
//see if we need to do any work
if (GeminiUtils.isGeminiSupport() && mSlotId != PhoneConstants.GEMINI_SIM_4) {
return;
}
networksListLoaded((List)msg.obj, msg.arg1);
break;
case EVENT_NETWORK_SELECTION_DONE:
/// M: dismiss all dialog when manual select done @{
if (DBG) {
log("hideProgressPanel");
}
removeDialog(DIALOG_NETWORK_SELECTION);
/// @}
ar = (AsyncResult) msg.obj;
if (ar.exception != null) {
if (DBG) {
log("manual network selection: failed!");
}
displayNetworkSelectionFailed(ar.exception);
} else {
if (DBG) {
log("manual network selection: succeeded!");
}
displayNetworkSelectionSucceeded();
}
break;
case EVENT_SERVICE_STATE_CHANGED:
Log.d(LOG_TAG, "EVENT_SERVICE_STATE_CHANGED");
setScreenEnabled(true);
break;
default:
break;
/// @}
}
return;
}
};
这个Handler 在回调函数中获得消息
/**
* This implementation of INetworkQueryServiceCallback is used to receive
* callback notifications from the network query service.
*/
private final INetworkQueryServiceCallback mCallback = new INetworkQueryServiceCallback.Stub() {
/** place the message on the looper queue upon query completion. */
public void onQueryComplete(List networkInfoArray, int status) {
if (DBG) {
log("notifying message loop of query completion.");
}
Message msg;
///M: modify for Gemini+ {
int what = EVENT_NETWORK_SCAN_COMPLETED;
switch (mSlotId) {
case PhoneConstants.GEMINI_SIM_1:
what = EVENT_NETWORK_SCAN_COMPLETED;
break;
case PhoneConstants.GEMINI_SIM_2:
what = EVENT_NETWORK_SCAN_COMPLETED_2;
break;
case PhoneConstants.GEMINI_SIM_3:
what = EVENT_NETWORK_SCAN_COMPLETED_3;
break;
case PhoneConstants.GEMINI_SIM_4:
what = EVENT_NETWORK_SCAN_COMPLETED_4;
break;
default:
log("mSlotId = " + mSlotId + " error!");
break;
}
///@}
msg = mHandler.obtainMessage(what, status, 0, networkInfoArray);
msg.sendToTarget();
}
};
回调方法在loadNetworksList中开始调用
loadNetworksList(){
...
mNetworkQueryService.startNetworkQuery(mCallback);
...
}
OperatorInfo.java的构造方法
OperatorInfo(String operatorAlphaLong,
String operatorAlphaShort,
String operatorNumeric,
State state) {
mOperatorAlphaLong = operatorAlphaLong;
mOperatorAlphaShort = operatorAlphaShort;
mOperatorNumeric = operatorNumeric;
mState = state;
}
OperatorInfo 实际是在 RIL.java获取的
private Object
responseOperatorInfos(Parcel p) {
String strings[] = (String [])responseStrings(p);
ArrayList ret;
if (FeatureOption.MTK_3GDONGLE_SUPPORT){
if (strings.length % 4 != 0) {
throw new RuntimeException(
"RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: invalid response. Got "
+ strings.length + " strings, expected multible of 4");
}
ret = new ArrayList(strings.length / 4);
for (int i = 0 ; i < strings.length ; i += 4) {
ret.add (
new OperatorInfo(
strings[i+0],
strings[i+1],
strings[i+2],
strings[i+3]));
}
} else {
if (strings.length % 5 != 0) {
throw new RuntimeException(
"RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: invalid response. Got "
+ strings.length + " strings, expected multible of 5");
}
// ALPS00353868 START
String lacStr = SystemProperties.get("gsm.cops.lac");
boolean lacValid = false;
int lacIndex=0;
Rlog.d(RILJ_LOG_TAG, "lacStr = " + lacStr+" lacStr.length="+lacStr.length()+" strings.length="+strings.length);
if((lacStr.length() > 0) && (lacStr.length()%4 == 0) && ((lacStr.length()/4) == (strings.length/5 ))){
Rlog.d(RILJ_LOG_TAG, "lacValid set to true");
lacValid = true;
}
SystemProperties.set("gsm.cops.lac",""); //reset property
// ALPS00353868 END
ret = new ArrayList(strings.length / 5);
for (int i = 0 ; i < strings.length ; i += 5) {
/* ALPS00273663 handle UCS2 format name : prefix + hex string ex: "uCs2806F767C79D1" */
if((strings[i+0] != null) && (strings[i+0].startsWith("uCs2") == true))
{
riljLog("responseOperatorInfos handling UCS2 format name");
try{
strings[i+0] = new String(hexStringToBytes(strings[i+0].substring(4)), "UTF-16");
}catch(UnsupportedEncodingException ex){
riljLog("responseOperatorInfos UnsupportedEncodingException");
}
}
// ALPS00353868 START
if((lacValid == true) && (strings[i+0] != null) && (mPhone!= null)){
UiccController uiccController = UiccController.getInstance(mPhone.getMySimId());
IccRecords iccRecords = uiccController.getIccRecords(UiccController.APP_FAM_3GPP);
int lacValue = -1;
String sEons = null;
String lac = lacStr.substring(lacIndex,lacIndex+4);
Rlog.d(RILJ_LOG_TAG, "lacIndex="+lacIndex+" lacValue="+lacValue+" lac="+lac+" plmn numeric="+strings[i+2]+" plmn name"+strings[i+0]);
if(lac != ""){
lacValue = Integer.parseInt(lac, 16);
lacIndex += 4;
if(lacValue != 0xfffe){
sEons = iccRecords.getEonsIfExist(strings[i+2],lacValue,true);
if(sEons != null){
strings[i+0] = sEons;
Rlog.d(RILJ_LOG_TAG, "plmn name update to Eons: "+strings[i+0]);
}
}else{
Rlog.d(RILJ_LOG_TAG, "invalid lac ignored");
}
}
}
// ALPS00353868 END
//这个是如果mOperatorAlphaLong(即strings[i+0])和mOperatorNumeric(即strings[i+2])相同,则再去
//通过lookupOperatorName获取真正的网络名称
if (strings[i+0] != null && (strings[i+0].equals("") || strings[i+0].equals(strings[i+2]))) {
riljLog("lookup RIL responseOperatorInfos()");
strings[i+0] = lookupOperatorName(strings[i+2], true);
strings[i+1] = lookupOperatorName(strings[i+2], false);
}
//1 and 2 is 2g. above 2 is 3g
String property_name = "gsm.baseband.capability";
if(mySimId > PhoneConstants.GEMINI_SIM_1){
property_name = property_name + (mySimId+1) ;
}
int basebandCapability = SystemProperties.getInt(property_name, 3); /* ALPS00352231 */
Rlog.d(RILJ_LOG_TAG, "property_name="+property_name+",basebandCapability=" + basebandCapability);
if( 3 < basebandCapability){
strings[i+0] = strings[i+0].concat(" " + strings[i+4]);
strings[i+1] = strings[i+1].concat(" " + strings[i+4]);
}
ret.add (
new OperatorInfo(
strings[i+0],
strings[i+1],
strings[i+2],
strings[i+3]));
}
}
return ret;
}
public String lookupOperatorName(String numeric, boolean desireLongName) {
Context context = mContext;
String operName = numeric;
// MVNO-API
String mvnoOperName = null;
mSpnOverride = SpnOverride.getInstance();
if (mSpnOverride != null) { //获取虚拟运营商的SPN
mvnoOperName = mSpnOverride.getSpnByEfSpn(numeric,
mPhone.getMvnoPattern(PhoneConstants.MVNO_TYPE_SPN));
riljLog("the result of searching mvnoOperName by EF_SPN: " + mvnoOperName);
if(mvnoOperName == null) // determine by IMSI
mvnoOperName = mSpnOverride.getSpnByImsi(numeric, mPhone.getSubscriberId());
riljLog("the result of searching mvnoOperName by IMSI: " + mvnoOperName);
if(mvnoOperName == null)
mvnoOperName = mSpnOverride.getSpnByEfPnn(numeric,
mPhone.getMvnoPattern(PhoneConstants.MVNO_TYPE_PNN));
riljLog("the result of searching mvnoOperName by EF_PNN: " + mvnoOperName);
if(mvnoOperName == null)
mvnoOperName = mSpnOverride.getSpnByEfGid1(numeric,
mPhone.getMvnoPattern(PhoneConstants.MVNO_TYPE_GID));
riljLog("the result of searching mvnoOperName by EF_GID1: " + mvnoOperName);
// like add start
if(mvnoOperName == null) {
String pattern = mPhone.getMvnoPattern(PhoneConstants.MVNO_TYPE_FILE);
mvnoOperName = mSpnOverride.getSpnByFile(numeric, pattern);
riljLog("the result of searching mvnoOperName by EF_FILE: " + mvnoOperName);
}
// like add end
if(mvnoOperName != null)
operName = mvnoOperName;
}
if (FeatureOption.CKT_CUSTOMIZE_NANTAI_TAIWAN_OPERATOR_DISPLAY)
{
if (mvnoOperName == null && desireLongName) { // MVNO-API
// ALFMS00040828 - add "46008"
if ((numeric.equals("46000")) || (numeric.equals("46002")) || (numeric.equals("46007")) || (numeric.equals("46008"))) {
operName = context.getText(com.mediatek.R.string.oper_long_46000).toString();
} else if ((numeric.equals("46001")) || (numeric.equals("46009"))) {
operName = context.getText(com.mediatek.R.string.oper_long_46001).toString();
}
.....
}
......
}
else
{
if (mvnoOperName == null && desireLongName) { // MVNO-API
// ALFMS00040828 - add "46008"
if ((numeric.equals("46000")) || (numeric.equals("46002")) || (numeric.equals("46007")) || (numeric.equals("46008"))) {
operName = context.getText(com.mediatek.R.string.oper_long_46000).toString();
} else if (numeric.equals("46001")) {
operName = context.getText(com.mediatek.R.string.oper_long_46001).toString();
} else if (numeric.equals("46003")) {
operName = context.getText(com.mediatek.R.string.oper_long_46003).toString();
} else if (numeric.equals("46601")) {
operName = context.getText(com.mediatek.R.string.oper_long_46601).toString();
} else if (numeric.equals("46692")) {
operName = context.getText(com.mediatek.R.string.oper_long_46692).toString();
} else if (numeric.equals("46697")) {
operName = context.getText(com.mediatek.R.string.oper_long_46697).toString();
} else if (numeric.equals("99998")) {
operName = context.getText(com.mediatek.R.string.oper_long_99998).toString();
} else if (numeric.equals("99999")) {
operName = context.getText(com.mediatek.R.string.oper_long_99999).toString();
} else {
// If can't found corresspoding operator in string resource, lookup from spn_conf.xml
mSpnOverride = SpnOverride.getInstance();
if (mSpnOverride.containsCarrier(numeric)) {
operName = mSpnOverride.getSpn(numeric); //获取普通MCCMNC 的 SPN
} else {
riljLog("Can't find long operator name for " + numeric);
}
}
}
else if (mvnoOperName == null && desireLongName == false) // MVNO-API
{
// ALFMS00040828 - add "46008"
if ((numeric.equals("46000")) || (numeric.equals("46002")) || (numeric.equals("46007")) || (numeric.equals("46008"))) {
operName = context.getText(com.mediatek.R.string.oper_short_46000).toString();
} else if (numeric.equals("46001")) {
operName = context.getText(com.mediatek.R.string.oper_short_46001).toString();
} else if (numeric.equals("46003")) {
operName = context.getText(com.mediatek.R.string.oper_short_46003).toString();
} else if (numeric.equals("46601")) {
operName = context.getText(com.mediatek.R.string.oper_short_46601).toString();
} else if (numeric.equals("46692")) {
operName = context.getText(com.mediatek.R.string.oper_short_46692).toString();
} else if (numeric.equals("46697")) {
operName = context.getText(com.mediatek.R.string.oper_short_46697).toString();
} else if (numeric.equals("99997")) {
operName = context.getText(com.mediatek.R.string.oper_short_99997).toString();
} else if (numeric.equals("99999")) {
operName = context.getText(com.mediatek.R.string.oper_short_99999).toString();
} else {
riljLog("Can't find short operator name for " + numeric);
}
}
}
return operName;
}
SpnOverride.java 中提供获取虚拟运营商SPN 和 普通SPN的方法
public String getSpnByImsi(String mccmnc, String imsi) {
if(mccmnc == null || imsi == null || mccmnc.isEmpty() || imsi.isEmpty())
return null;
// like add for automatedtesting start
if(FeatureOption.CKT_AUTOMATED_TESTING_VIRTUALNET && imsi.startsWith(mccmnc)){
for (String pattern : mVirtualNetsConfMap.keySet()) {
VirtualNetConf virtualNetConf = mVirtualNetsConfMap.get(pattern);
if (virtualNetConf.imsipattern != null && imsiMatches(virtualNetConf.imsipattern,imsi) == true) {
Log.d(LOG_TAG_Y506,virtualNetConf.onsName == null ?
"getSpnByImsi:no spn in virtual net conf" :("getSpnByImsi from vitural net conf:" + virtualNetConf.onsName));
return virtualNetConf.onsName;
}
}
}
// like add for automatedtesting end
VirtualSpnByImsi vsbi;
for(int i = 0; i < this.CarrierVirtualSpnMapByImsi.size(); i++) {
vsbi = (VirtualSpnByImsi)(this.CarrierVirtualSpnMapByImsi.get(i));
Rlog.w(LOG_TAG, "getSpnByImsi(): imsi = " + imsi + ", pattern = " + vsbi.pattern);
/**************************************************************************************************
Warning: 修改此部分代码请确认不要讲MTK的修改引入,MTK的imsi虚拟网采用的方案为mccmnc+imsi,
当前Y520采用的方案为imsi,故有冲突.
MTK方案:
if (imsiMatches(vsbi.pattern, mccmnc + imsi) == true) {
Date: 2014.11.10
***************************************************************************************************/
if(imsiMatches(vsbi.pattern,imsi) == true) {
return vsbi.name;
}
}
return null;
}
public String getSpnByEfSpn(String mccmnc, String spn) {
if(mccmnc == null || spn == null || mccmnc.isEmpty() || spn.isEmpty())
return null;
// like add for automatedtesting start
if(FeatureOption.CKT_AUTOMATED_TESTING_VIRTUALNET){
VirtualNetConf virtualNetConf = mVirtualNetsConfMap.get(mccmnc + spn);
if (virtualNetConf != null) {
if (virtualNetConf.spn != null && virtualNetConf.spn.equals(spn)) {
String virtualSpn = virtualNetConf.onsName;
//Log.d(LOG_TAG_Y506,virtualSpn == null ? "no spn in virtual net conf" :("get spn from vitural net conf:" + virtualSpn));
return virtualSpn;
}
}
}
// like add for automatedtesting end
return CarrierVirtualSpnMapByEfSpn.get(mccmnc + spn);
}
public String getSpnByEfGid1(String mccmnc, String gid1) {
if(mccmnc == null || gid1 == null || mccmnc.isEmpty() || gid1.isEmpty())
return null;
// like add for automatedtesting start
if(FeatureOption.CKT_AUTOMATED_TESTING_VIRTUALNET){
VirtualNetConf virtualNetConf = getVirtualNetConf(mccmnc + GID1_MATCH_SEPERATOR + gid1,PhoneConstants.MVNO_TYPE_GID);
if (virtualNetConf != null) {
Log.d(LOG_TAG_Y506,virtualNetConf.onsName == null ?
"getSpnByEfGid1:no spn in virtual net conf" :
("getSpnByEfGid1 from vitural net conf:" + virtualNetConf.onsName));
return virtualNetConf.onsName;
}
}
// like add for automatedtesting end
return CarrierVirtualSpnMapByEfPnn.get(mccmnc + gid1);
}
// like add start
public String getSpnByFile(String mccmnc,String iccId,String efSST) {
//Log.d(LOG_TAG_Y506,"getSpnByFile-----------");
if (TextUtils.isEmpty(mccmnc)) {
return null;
}
if(FeatureOption.CKT_AUTOMATED_TESTING_VIRTUALNET) {
String pattern = mccmnc + FILE_MATCH_SEPERATOR + iccId + FILE_MATCH_SEPERATOR + efSST;
VirtualNetConf virtualNetConf = getVirtualNetConf(pattern,PhoneConstants.MVNO_TYPE_FILE);
if (virtualNetConf != null) {
return virtualNetConf.onsName;
}
}
return null;
}