Merge "Use CSIM to get provision information" into honeycomb-LTE
This commit is contained in:
@@ -63,6 +63,10 @@ public interface IccConstants {
|
||||
// 3GPP2 C.S0065
|
||||
static final int EF_CSIM_LI = 0x6F3A;
|
||||
static final int EF_CSIM_SPN =0x6F41;
|
||||
static final int EF_CSIM_MDN = 0x6F44;
|
||||
static final int EF_CSIM_IMSIM = 0x6F22;
|
||||
static final int EF_CSIM_CDMAHOME = 0x6F28;
|
||||
static final int EF_CSIM_EPRL = 0x6F5A;
|
||||
|
||||
//ISIM access
|
||||
static final int EF_IMPU = 0x6f04;
|
||||
|
||||
@@ -287,6 +287,16 @@ public abstract class IccRecords extends Handler implements IccConstants {
|
||||
public void setVoiceCallForwardingFlag(int line, boolean enable) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates wether SIM is in provisioned state or not.
|
||||
* Overridden only if SIM can be dynamically provisioned via OTA.
|
||||
*
|
||||
* @return true if provisioned
|
||||
*/
|
||||
public boolean isProvisioned () {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write string to log file
|
||||
*
|
||||
|
||||
@@ -63,6 +63,29 @@ public class IccUtils {
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode cdma byte into String.
|
||||
*/
|
||||
public static String
|
||||
cdmaBcdToString(byte[] data, int offset, int length) {
|
||||
StringBuilder ret = new StringBuilder(length);
|
||||
|
||||
int count = 0;
|
||||
for (int i = offset; count < length; i++) {
|
||||
int v;
|
||||
v = data[i] & 0xf;
|
||||
if (v > 9) v = 0;
|
||||
ret.append((char)('0' + v));
|
||||
|
||||
if (++count == length) break;
|
||||
|
||||
v = (data[i] >> 4) & 0xf;
|
||||
if (v > 9) v = 0;
|
||||
ret.append((char)('0' + v));
|
||||
++count;
|
||||
}
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a GSM-style BCD byte, returning an int ranging from 0-99.
|
||||
|
||||
@@ -67,11 +67,24 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
|
||||
case EVENT_SIM_READY:
|
||||
if (DBG) log("handleMessage EVENT_SIM_READY");
|
||||
isSubscriptionFromRuim = false;
|
||||
cm.getCDMASubscription( obtainMessage(EVENT_POLL_STATE_CDMA_SUBSCRIPTION));
|
||||
// Register SIM_RECORDS_LOADED dynamically.
|
||||
// This is to avoid confilct with RUIM_READY scenario)
|
||||
phone.mIccRecords.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null);
|
||||
pollState();
|
||||
// Signal strength polling stops when radio is off.
|
||||
queueNextSignalStrengthPoll();
|
||||
break;
|
||||
case EVENT_SIM_RECORDS_LOADED:
|
||||
CdmaLteUiccRecords sim = (CdmaLteUiccRecords)phone.mIccRecords;
|
||||
if ((sim != null) && sim.isProvisioned()) {
|
||||
mMdn = sim.getMdn();
|
||||
mMin = sim.getMin();
|
||||
parseSidNid(sim.getSid(), sim.getNid());
|
||||
mPrlVersion = sim.getPrlVersion();;
|
||||
mIsMinInfoReady = true;
|
||||
updateOtaspState();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
super.handleMessage(msg);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.internal.telephony.cdma;
|
||||
import android.util.Log;
|
||||
import com.android.internal.telephony.IccConstants;
|
||||
import com.android.internal.telephony.IccFileHandler;
|
||||
import android.os.Message;
|
||||
|
||||
/**
|
||||
* {@hide}
|
||||
@@ -34,6 +35,10 @@ public final class CdmaLteUiccFileHandler extends IccFileHandler {
|
||||
switch(efid) {
|
||||
case EF_CSIM_SPN:
|
||||
case EF_CSIM_LI:
|
||||
case EF_CSIM_MDN:
|
||||
case EF_CSIM_IMSIM:
|
||||
case EF_CSIM_CDMAHOME:
|
||||
case EF_CSIM_EPRL:
|
||||
return MF_SIM + DF_CDMA;
|
||||
case EF_AD:
|
||||
return MF_SIM + DF_GSM;
|
||||
@@ -41,6 +46,21 @@ public final class CdmaLteUiccFileHandler extends IccFileHandler {
|
||||
return getCommonIccEFPath(efid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadEFTransparent(int fileid, Message onLoaded) {
|
||||
if (fileid == EF_CSIM_EPRL) {
|
||||
// Entire PRL could be huge. We are only interested in
|
||||
// the first 4 bytes of the record.
|
||||
phone.mCM.iccIO(COMMAND_READ_BINARY, fileid, getEFPath(fileid),
|
||||
0, 0, 4, null, null,
|
||||
obtainMessage(EVENT_READ_BINARY_DONE,
|
||||
fileid, 0, onLoaded));
|
||||
} else {
|
||||
super.loadEFTransparent(fileid, onLoaded);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void logd(String msg) {
|
||||
Log.d(LOG_TAG, "[CdmaLteUiccFileHandler] " + msg);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,8 @@ import android.os.AsyncResult;
|
||||
import android.os.Message;
|
||||
import android.os.SystemProperties;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* {@hide}
|
||||
@@ -36,10 +37,19 @@ public final class CdmaLteUiccRecords extends SIMRecords {
|
||||
private byte[] mEFpl = null;
|
||||
private byte[] mEFli = null;
|
||||
boolean csimSpnDisplayCondition = false;
|
||||
private String mMdn;
|
||||
private String mMin;
|
||||
private String mPrlVersion;
|
||||
private String mHomeSystemId;
|
||||
private String mHomeNetworkId;
|
||||
|
||||
private static final int EVENT_GET_PL_DONE = CSIM_EVENT_BASE;
|
||||
private static final int EVENT_GET_CSIM_LI_DONE = CSIM_EVENT_BASE + 1;
|
||||
private static final int EVENT_GET_CSIM_SPN_DONE = CSIM_EVENT_BASE + 2;
|
||||
private static final int EVENT_GET_CSIM_MDN_DONE = CSIM_EVENT_BASE + 3;
|
||||
private static final int EVENT_GET_CSIM_IMSIM_DONE = CSIM_EVENT_BASE + 4;
|
||||
private static final int EVENT_GET_CSIM_CDMAHOME_DONE = CSIM_EVENT_BASE + 5;
|
||||
private static final int EVENT_GET_CSIM_EPRL_DONE = CSIM_EVENT_BASE + 6;
|
||||
|
||||
public CdmaLteUiccRecords(PhoneBase p) {
|
||||
super(p);
|
||||
@@ -109,6 +119,46 @@ public final class CdmaLteUiccRecords extends SIMRecords {
|
||||
}
|
||||
onGetCSimSpnDone(ar);
|
||||
break;
|
||||
case EVENT_GET_CSIM_MDN_DONE:
|
||||
if (DBG) log("EVENT_GET_CSIM_MDN_DONE");
|
||||
isCsimRecordLoadResponse = true;
|
||||
ar = (AsyncResult) msg.obj;
|
||||
if (ar.exception != null) {
|
||||
Log.e(LOG_TAG, "ar.exception=" + ar.exception);
|
||||
break;
|
||||
}
|
||||
onGetCSimMdnDone(ar);
|
||||
break;
|
||||
case EVENT_GET_CSIM_IMSIM_DONE:
|
||||
if (DBG) log("EVENT_GET_CSIM_IMSIM_DONE");
|
||||
isCsimRecordLoadResponse = true;
|
||||
ar = (AsyncResult) msg.obj;
|
||||
if (ar.exception != null) {
|
||||
Log.e(LOG_TAG, "ar.exception=" + ar.exception);
|
||||
break;
|
||||
}
|
||||
onGetCSimImsimDone(ar);
|
||||
break;
|
||||
case EVENT_GET_CSIM_CDMAHOME_DONE:
|
||||
if (DBG) log("EVENT_GET_CSIM_CDMAHOME_DONE");
|
||||
isCsimRecordLoadResponse = true;
|
||||
ar = (AsyncResult) msg.obj;
|
||||
if (ar.exception != null) {
|
||||
Log.e(LOG_TAG, "ar.exception=" + ar.exception);
|
||||
break;
|
||||
}
|
||||
onGetCSimCdmaHomeDone(ar);
|
||||
break;
|
||||
case EVENT_GET_CSIM_EPRL_DONE:
|
||||
if (DBG) log("EVENT_GET_CSIM_EPRL_DONE");
|
||||
isCsimRecordLoadResponse = true;
|
||||
ar = (AsyncResult) msg.obj;
|
||||
if (ar.exception != null) {
|
||||
Log.e(LOG_TAG, "ar.exception=" + ar.exception);
|
||||
break;
|
||||
}
|
||||
onGetCSimEprlDone(ar);
|
||||
break;
|
||||
default:
|
||||
super.handleMessage(msg);
|
||||
}}catch (RuntimeException exc) {
|
||||
@@ -156,6 +206,19 @@ public final class CdmaLteUiccRecords extends SIMRecords {
|
||||
|
||||
iccFh.loadEFTransparent(EF_CSIM_SPN, obtainMessage(EVENT_GET_CSIM_SPN_DONE));
|
||||
recordsToLoad++;
|
||||
|
||||
iccFh.loadEFLinearFixed(EF_CSIM_MDN, 1, obtainMessage(EVENT_GET_CSIM_MDN_DONE));
|
||||
recordsToLoad++;
|
||||
|
||||
iccFh.loadEFTransparent(EF_CSIM_IMSIM, obtainMessage(EVENT_GET_CSIM_IMSIM_DONE));
|
||||
recordsToLoad++;
|
||||
|
||||
iccFh.loadEFLinearFixedAll(EF_CSIM_CDMAHOME,
|
||||
obtainMessage(EVENT_GET_CSIM_CDMAHOME_DONE));
|
||||
recordsToLoad++;
|
||||
|
||||
iccFh.loadEFTransparent(EF_CSIM_EPRL, obtainMessage(EVENT_GET_CSIM_EPRL_DONE));
|
||||
recordsToLoad++;
|
||||
}
|
||||
|
||||
private void onGetCSimSpnDone(AsyncResult ar) {
|
||||
@@ -205,6 +268,93 @@ public final class CdmaLteUiccRecords extends SIMRecords {
|
||||
phone.setSystemProperty(PROPERTY_ICC_OPERATOR_ALPHA, spn);
|
||||
}
|
||||
|
||||
private void onGetCSimMdnDone(AsyncResult ar) {
|
||||
byte[] data = (byte[]) ar.result;
|
||||
if (DBG) log("CSIM_MDN=" + IccUtils.bytesToHexString(data));
|
||||
int mdnDigitsNum = 0x0F & data[0];
|
||||
mMdn = IccUtils.cdmaBcdToString(data, 1, mdnDigitsNum);
|
||||
if (DBG) log("CSIM MDN=" + mMdn);
|
||||
}
|
||||
|
||||
private void onGetCSimImsimDone(AsyncResult ar) {
|
||||
byte[] data = (byte[]) ar.result;
|
||||
if (DBG) log("CSIM_IMSIM=" + IccUtils.bytesToHexString(data));
|
||||
// C.S0065 section 5.2.2 for IMSI_M encoding
|
||||
// C.S0005 section 2.3.1 for MIN encoding in IMSI_M.
|
||||
boolean provisioned = ((data[7] & 0x80) == 0x80);
|
||||
|
||||
if (provisioned) {
|
||||
int first3digits = ((0x03 & data[2]) << 8) + (0xFF & data[1]);
|
||||
int second3digits = (((0xFF & data[5]) << 8) | (0xFF & data[4])) >> 6;
|
||||
int digit7 = 0x0F & (data[4] >> 2);
|
||||
if (digit7 > 0x09) digit7 = 0;
|
||||
int last3digits = ((0x03 & data[4]) << 8) | (0xFF & data[3]);
|
||||
first3digits = adjstMinDigits(first3digits);
|
||||
second3digits = adjstMinDigits(second3digits);
|
||||
last3digits = adjstMinDigits(last3digits);
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(String.format(Locale.US, "%03d", first3digits));
|
||||
builder.append(String.format(Locale.US, "%03d", second3digits));
|
||||
builder.append(String.format(Locale.US, "%d", digit7));
|
||||
builder.append(String.format(Locale.US, "%03d", last3digits));
|
||||
if (DBG) log("min present=" + builder.toString());
|
||||
|
||||
mMin = builder.toString();
|
||||
} else {
|
||||
if (DBG) log("min not present");
|
||||
}
|
||||
}
|
||||
|
||||
private int adjstMinDigits (int digits) {
|
||||
// Per C.S0005 section 2.3.1.
|
||||
digits += 111;
|
||||
digits = (digits % 10 == 0)?(digits - 10):digits;
|
||||
digits = ((digits / 10) % 10 == 0)?(digits - 100):digits;
|
||||
digits = ((digits / 100) % 10 == 0)?(digits - 1000):digits;
|
||||
return digits;
|
||||
}
|
||||
|
||||
private void onGetCSimCdmaHomeDone(AsyncResult ar) {
|
||||
// Per C.S0065 section 5.2.8
|
||||
ArrayList<byte[]> dataList = (ArrayList<byte[]>) ar.result;
|
||||
if (DBG) log("CSIM_CDMAHOME data size=" + dataList.size());
|
||||
if (dataList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
StringBuilder sidBuf = new StringBuilder();
|
||||
StringBuilder nidBuf = new StringBuilder();
|
||||
|
||||
for (byte[] data : dataList) {
|
||||
if (data.length == 5) {
|
||||
int sid = ((data[1] & 0xFF) << 8) | (data[0] & 0xFF);
|
||||
int nid = ((data[3] & 0xFF) << 8) | (data[2] & 0xFF);
|
||||
sidBuf.append(sid).append(",");
|
||||
nidBuf.append(nid).append(",");
|
||||
}
|
||||
}
|
||||
// remove trailing ","
|
||||
sidBuf.setLength(sidBuf.length()-1);
|
||||
nidBuf.setLength(nidBuf.length()-1);
|
||||
|
||||
mHomeSystemId = sidBuf.toString();
|
||||
mHomeNetworkId = nidBuf.toString();
|
||||
}
|
||||
|
||||
private void onGetCSimEprlDone(AsyncResult ar) {
|
||||
// C.S0065 section 5.2.57 for EFeprl encoding
|
||||
// C.S0016 section 3.5.5 for PRL format.
|
||||
byte[] data = (byte[]) ar.result;
|
||||
if (DBG) log("CSIM_EPRL=" + IccUtils.bytesToHexString(data));
|
||||
|
||||
// Only need the first 4 bytes of record
|
||||
if (data.length > 3) {
|
||||
int prlId = ((data[2] & 0xFF) << 8) | (data[3] & 0xFF);
|
||||
mPrlVersion = Integer.toString(prlId);
|
||||
}
|
||||
if (DBG) log("CSIM PRL version=" + mPrlVersion);
|
||||
}
|
||||
|
||||
public byte[] getPreferredLanguage() {
|
||||
return mEFpl;
|
||||
}
|
||||
@@ -212,4 +362,32 @@ public final class CdmaLteUiccRecords extends SIMRecords {
|
||||
public byte[] getLanguageIndication() {
|
||||
return mEFli;
|
||||
}
|
||||
|
||||
public String getMdn() {
|
||||
return mMdn;
|
||||
}
|
||||
|
||||
public String getMin() {
|
||||
return mMin;
|
||||
}
|
||||
|
||||
public String getSid() {
|
||||
return mHomeSystemId;
|
||||
}
|
||||
|
||||
public String getNid() {
|
||||
return mHomeNetworkId;
|
||||
}
|
||||
|
||||
public String getPrlVersion() {
|
||||
return mPrlVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProvisioned() {
|
||||
// Look for MDN and MIN field to determine if the SIM is provisioned.
|
||||
if ((mMdn != null) && (mMin != null)) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,12 +129,12 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
|
||||
/** Contains the name of the registered network in CDMA (either ONS or ERI text). */
|
||||
private String curPlmn = null;
|
||||
|
||||
private String mMdn;
|
||||
protected String mMdn;
|
||||
private int mHomeSystemId[] = null;
|
||||
private int mHomeNetworkId[] = null;
|
||||
private String mMin;
|
||||
private String mPrlVersion;
|
||||
private boolean mIsMinInfoReady = false;
|
||||
protected String mMin;
|
||||
protected String mPrlVersion;
|
||||
protected boolean mIsMinInfoReady = false;
|
||||
|
||||
private boolean isEriTextLoaded = false;
|
||||
protected boolean isSubscriptionFromRuim = false;
|
||||
@@ -373,53 +373,15 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
|
||||
String cdmaSubscription[] = (String[])ar.result;
|
||||
if (cdmaSubscription != null && cdmaSubscription.length >= 5) {
|
||||
mMdn = cdmaSubscription[0];
|
||||
if (cdmaSubscription[1] != null) {
|
||||
String[] sid = cdmaSubscription[1].split(",");
|
||||
mHomeSystemId = new int[sid.length];
|
||||
for (int i = 0; i < sid.length; i++) {
|
||||
try {
|
||||
mHomeSystemId[i] = Integer.parseInt(sid[i]);
|
||||
} catch (NumberFormatException ex) {
|
||||
loge("error parsing system id: " + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (DBG) log("GET_CDMA_SUBSCRIPTION: SID=" + cdmaSubscription[1] );
|
||||
parseSidNid(cdmaSubscription[1], cdmaSubscription[2]);
|
||||
|
||||
if (cdmaSubscription[2] != null) {
|
||||
String[] nid = cdmaSubscription[2].split(",");
|
||||
mHomeNetworkId = new int[nid.length];
|
||||
for (int i = 0; i < nid.length; i++) {
|
||||
try {
|
||||
mHomeNetworkId[i] = Integer.parseInt(nid[i]);
|
||||
} catch (NumberFormatException ex) {
|
||||
loge("GET_CDMA_SUBSCRIPTION: error parsing network id: " + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (DBG) log("GET_CDMA_SUBSCRIPTION: NID=" + cdmaSubscription[2]);
|
||||
mMin = cdmaSubscription[3];
|
||||
mPrlVersion = cdmaSubscription[4];
|
||||
if (DBG) log("GET_CDMA_SUBSCRIPTION: MDN=" + mMdn);
|
||||
|
||||
mIsMinInfoReady = true;
|
||||
|
||||
int otaspMode = getOtasp();
|
||||
int oldOtaspMode = mCurrentOtaspMode;
|
||||
mCurrentOtaspMode = otaspMode;
|
||||
|
||||
// Notify apps subscription info is ready
|
||||
if (cdmaForSubscriptionInfoReadyRegistrants != null) {
|
||||
if (DBG) log("GET_CDMA_SUBSCRIPTION: call notifyRegistrants()");
|
||||
cdmaForSubscriptionInfoReadyRegistrants.notifyRegistrants();
|
||||
}
|
||||
if (oldOtaspMode != mCurrentOtaspMode) {
|
||||
if (DBG) {
|
||||
log("GET_CDMA_SUBSCRIPTION: call notifyOtaspChanged old otaspMode=" +
|
||||
oldOtaspMode + " new otaspMode=" + mCurrentOtaspMode);
|
||||
}
|
||||
phone.notifyOtaspChanged(mCurrentOtaspMode);
|
||||
}
|
||||
updateOtaspState();
|
||||
phone.getIccCard().broadcastIccStateChangedIntent(IccCard.INTENT_VALUE_ICC_IMSI,
|
||||
null);
|
||||
} else {
|
||||
@@ -1622,6 +1584,53 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
|
||||
cm.setRadioPower(false, null);
|
||||
}
|
||||
|
||||
protected void parseSidNid (String sidStr, String nidStr) {
|
||||
if (sidStr != null) {
|
||||
String[] sid = sidStr.split(",");
|
||||
mHomeSystemId = new int[sid.length];
|
||||
for (int i = 0; i < sid.length; i++) {
|
||||
try {
|
||||
mHomeSystemId[i] = Integer.parseInt(sid[i]);
|
||||
} catch (NumberFormatException ex) {
|
||||
loge("error parsing system id: " + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (DBG) log("CDMA_SUBSCRIPTION: SID=" + sidStr);
|
||||
|
||||
if (nidStr != null) {
|
||||
String[] nid = nidStr.split(",");
|
||||
mHomeNetworkId = new int[nid.length];
|
||||
for (int i = 0; i < nid.length; i++) {
|
||||
try {
|
||||
mHomeNetworkId[i] = Integer.parseInt(nid[i]);
|
||||
} catch (NumberFormatException ex) {
|
||||
loge("CDMA_SUBSCRIPTION: error parsing network id: " + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (DBG) log("CDMA_SUBSCRIPTION: NID=" + nidStr);
|
||||
}
|
||||
|
||||
protected void updateOtaspState() {
|
||||
int otaspMode = getOtasp();
|
||||
int oldOtaspMode = mCurrentOtaspMode;
|
||||
mCurrentOtaspMode = otaspMode;
|
||||
|
||||
// Notify apps subscription info is ready
|
||||
if (cdmaForSubscriptionInfoReadyRegistrants != null) {
|
||||
if (DBG) log("CDMA_SUBSCRIPTION: call notifyRegistrants()");
|
||||
cdmaForSubscriptionInfoReadyRegistrants.notifyRegistrants();
|
||||
}
|
||||
if (oldOtaspMode != mCurrentOtaspMode) {
|
||||
if (DBG) {
|
||||
log("CDMA_SUBSCRIPTION: call notifyOtaspChanged old otaspMode=" +
|
||||
oldOtaspMode + " new otaspMode=" + mCurrentOtaspMode);
|
||||
}
|
||||
phone.notifyOtaspChanged(mCurrentOtaspMode);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void log(String s) {
|
||||
Log.d(LOG_TAG, "[CdmaSST] " + s);
|
||||
|
||||
@@ -561,6 +561,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
boolean allowed =
|
||||
(gprsState == ServiceState.STATE_IN_SERVICE || mAutoAttachOnCreation) &&
|
||||
mPhone.mIccRecords.getRecordsLoaded() &&
|
||||
mPhone.mIccRecords.isProvisioned() &&
|
||||
mPhone.getState() == Phone.State.IDLE &&
|
||||
mInternalDataEnabled &&
|
||||
(!mPhone.getServiceState().getRoaming() || getDataOnRoamingEnabled()) &&
|
||||
@@ -572,6 +573,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
reason += " - gprs= " + gprsState;
|
||||
}
|
||||
if (!mPhone.mIccRecords.getRecordsLoaded()) reason += " - SIM not loaded";
|
||||
if (!mPhone.mIccRecords.isProvisioned()) reason += " - SIM not provisioned";
|
||||
if (mPhone.getState() != Phone.State.IDLE) {
|
||||
reason += " - PhoneState= " + mPhone.getState();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user