protected void updatePhoneObject() { if (mPhoneBase .getContext() .getResources() .getBoolean(com.android.internal.R.bool.config_switch_phone_on_voice_reg_state_change)) { // If the phone is not registered on a network, no need to update. boolean isRegistered = mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE || mSS.getVoiceRegState() == ServiceState.STATE_EMERGENCY_ONLY; if (!isRegistered) { Rlog.d(LOG_TAG, "updatePhoneObject: Ignore update"); return; } mPhoneBase.updatePhoneObject(mSS.getRilVoiceRadioTechnology()); } }
private int updateEfForIccType(int efid) { // Check if we are trying to read ADN records if (efid == IccConstants.EF_ADN) { if (phone.getIccCard().isApplicationOnIcc(IccCardApplication.AppType.APPTYPE_USIM)) { return IccConstants.EF_PBR; } } return efid; }
/** * Notify all mDataConnectionRatChangeRegistrants using an AsyncResult in msg.obj where * AsyncResult#result contains the new RAT as an Integer Object. */ protected void notifyDataRegStateRilRadioTechnologyChanged() { int rat = mSS.getRilDataRadioTechnology(); int drs = mSS.getDataRegState(); if (DBG) log("notifyDataRegStateRilRadioTechnologyChanged: drs=" + drs + " rat=" + rat); mPhoneBase.setSystemProperty( TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE, ServiceState.rilRadioTechnologyToString(rat)); mDataRegStateOrRatChangedRegistrants.notifyResult(new Pair<Integer, Integer>(drs, rat)); }
public DisconnectCause disconnectCauseFromCode(int causeCode, PhoneBase phone) { /** See 22.001 Annex F.4 for mapping of cause codes to local tones */ switch (causeCode) { case CallFailCause.NO_CIRCUIT_AVAIL: case CallFailCause.TEMPORARY_FAILURE: case CallFailCause.SWITCHING_CONGESTION: case CallFailCause.CHANNEL_NOT_AVAIL: case CallFailCause.QOS_NOT_AVAIL: case CallFailCause.BEARER_NOT_AVAIL: return DisconnectCause.CONGESTION; case CallFailCause.ACM_LIMIT_EXCEEDED: return DisconnectCause.LIMIT_EXCEEDED; case CallFailCause.CALL_BARRED: return DisconnectCause.CALL_BARRED; case CallFailCause.FDN_BLOCKED: return DisconnectCause.FDN_BLOCKED; case CallFailCause.UNOBTAINABLE_NUMBER: return DisconnectCause.UNOBTAINABLE_NUMBER; case CallFailCause.DIAL_MODIFIED_TO_USSD: return DisconnectCause.DIAL_MODIFIED_TO_USSD; case CallFailCause.DIAL_MODIFIED_TO_SS: return DisconnectCause.DIAL_MODIFIED_TO_SS; case CallFailCause.DIAL_MODIFIED_TO_DIAL: return DisconnectCause.DIAL_MODIFIED_TO_DIAL; case CallFailCause.USER_BUSY: return DisconnectCause.BUSY; case CallFailCause.CDMA_LOCKED_UNTIL_POWER_CYCLE: return DisconnectCause.CDMA_LOCKED_UNTIL_POWER_CYCLE; case CallFailCause.CDMA_DROP: return DisconnectCause.CDMA_DROP; case CallFailCause.CDMA_INTERCEPT: return DisconnectCause.CDMA_INTERCEPT; case CallFailCause.CDMA_REORDER: return DisconnectCause.CDMA_REORDER; case CallFailCause.CDMA_SO_REJECT: return DisconnectCause.CDMA_SO_REJECT; case CallFailCause.CDMA_RETRY_ORDER: return DisconnectCause.CDMA_RETRY_ORDER; case CallFailCause.CDMA_ACCESS_FAILURE: return DisconnectCause.CDMA_ACCESS_FAILURE; case CallFailCause.CDMA_PREEMPTED: return DisconnectCause.CDMA_PREEMPTED; case CallFailCause.CDMA_NOT_EMERGENCY: return DisconnectCause.CDMA_NOT_EMERGENCY; case CallFailCause.CDMA_ACCESS_BLOCKED: return DisconnectCause.CDMA_ACCESS_BLOCKED; case CallFailCause.ERROR_UNSPECIFIED: case CallFailCause.NORMAL_CLEARING: default: { return phone.disconnectCauseFromCode(causeCode); } } }
protected ServiceStateTracker(PhoneBase phoneBase, CommandsInterface ci, CellInfo cellInfo) { mPhoneBase = phoneBase; mCellInfo = cellInfo; mCi = ci; mVoiceCapable = mPhoneBase .getContext() .getResources() .getBoolean(com.android.internal.R.bool.config_voice_capable); mUiccController = UiccController.getInstance(); mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null); mCi.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null); mCi.registerForCellInfoList(this, EVENT_UNSOL_CELL_INFO_LIST, null); mSubscriptionController = SubscriptionController.getInstance(); mSubscriptionManager = SubscriptionManager.from(phoneBase.getContext()); mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener); mPhoneBase.setSystemProperty( TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE, ServiceState.rilRadioTechnologyToString(ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN)); mCi.registerForImsNetworkStateChanged(this, EVENT_IMS_STATE_CHANGED, null); }
/** * Replace oldAdn with newAdn in ADN-like record in EF * * <p>getAdnRecordsInEf must be called at least once before this function, otherwise an error will * be returned. Currently the email field if set in the ADN record is ignored. throws * SecurityException if no WRITE_CONTACTS permission * * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN * @param oldTag adn tag to be replaced * @param oldPhoneNumber adn number to be replaced Set both oldTag and oldPhoneNubmer to "" means * to replace an empty record, aka, insert new record * @param newTag adn tag to be stored * @param newPhoneNumber adn number ot be stored Set both newTag and newPhoneNubmer to "" means to * replace the old record with empty one, aka, delete old record * @param pin2 required to update EF_FDN, otherwise must be null * @return true for success */ public boolean updateAdnRecordsInEfBySearch( int efid, String oldTag, String oldPhoneNumber, String newTag, String newPhoneNumber, String pin2) { if (phone.getContext().checkCallingOrSelfPermission(android.Manifest.permission.WRITE_CONTACTS) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires android.permission.WRITE_CONTACTS permission"); } if (DBG) logd( "updateAdnRecordsInEfBySearch: efid=" + efid + " (" + oldTag + "," + oldPhoneNumber + ")" + "==>" + " (" + newTag + "," + newPhoneNumber + ")" + " pin2=" + pin2); efid = updateEfForIccType(efid); synchronized (mLock) { checkThread(); success = false; Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE); AdnRecord oldAdn = new AdnRecord(oldTag, oldPhoneNumber); AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber); adnCache.updateAdnBySearch(efid, oldAdn, newAdn, pin2, response); try { mLock.wait(); } catch (InterruptedException e) { logd("interrupted while trying to update by search"); } } return success; }
protected boolean notifySignalStrength() { boolean notified = false; synchronized (mCellInfo) { if (!mSignalStrength.equals(mLastSignalStrength)) { try { mPhoneBase.notifySignalStrength(); notified = true; } catch (NullPointerException ex) { loge( "updateSignalStrength() Phone already destroyed: " + ex + "SignalStrength not notified"); } } } return notified; }
/** * Clean up existing voice and data connection then turn off radio power. * * <p>Hang up the existing voice calls to decrease call drop rate. */ public void powerOffRadioSafely(DcTrackerBase dcTracker) { synchronized (this) { if (!mPendingRadioPowerOffAfterDataOff) { // In some network, deactivate PDP connection cause releasing of RRC connection, // which MM/IMSI detaching request needs. Without this detaching, network can // not release the network resources previously attached. // So we are avoiding data detaching on these networks. String[] networkNotClearData = mPhoneBase .getContext() .getResources() .getStringArray(com.android.internal.R.array.networks_not_clear_data); String currentNetwork = mSS.getOperatorNumeric(); if ((networkNotClearData != null) && (currentNetwork != null)) { for (int i = 0; i < networkNotClearData.length; i++) { if (currentNetwork.equals(networkNotClearData[i])) { // Don't clear data connection for this carrier if (DBG) log("Not disconnecting data for " + currentNetwork); hangupAndPowerOff(); return; } } } // To minimize race conditions we call cleanUpAllConnections on // both if else paths instead of before this isDisconnected test. if (dcTracker.isDisconnected()) { // To minimize race conditions we do this after isDisconnected dcTracker.cleanUpAllConnections(Phone.REASON_RADIO_TURNED_OFF); if (DBG) log("Data disconnected, turn off radio right away."); hangupAndPowerOff(); } else { dcTracker.cleanUpAllConnections(Phone.REASON_RADIO_TURNED_OFF); Message msg = Message.obtain(this); msg.what = EVENT_SET_RADIO_POWER_OFF; msg.arg1 = ++mPendingRadioPowerOffAfterDataOffTag; if (sendMessageDelayed(msg, 30000)) { if (DBG) log("Wait upto 30s for data to disconnect, then turn off radio."); mPendingRadioPowerOffAfterDataOff = true; } else { log("Cannot send delayed Msg, turn off radio right away."); hangupAndPowerOff(); } } } } }
/** * Loads the AdnRecords in efid and returns them as a List of AdnRecords * * <p>throws SecurityException if no READ_CONTACTS permission * * @param efid the EF id of a ADN-like ICC * @return List of AdnRecord */ public List<AdnRecord> getAdnRecordsInEf(int efid) { if (phone.getContext().checkCallingOrSelfPermission(android.Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires android.permission.READ_CONTACTS permission"); } efid = updateEfForIccType(efid); if (DBG) logd("getAdnRecordsInEF: efid=" + efid); synchronized (mLock) { checkThread(); Message response = mBaseHandler.obtainMessage(EVENT_LOAD_DONE); adnCache.requestLoadAllAdnLike(efid, adnCache.extensionEfForEf(efid), response); try { mLock.wait(); } catch (InterruptedException e) { logd("interrupted while trying to load from the SIM"); } } return records; }
public static void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("PhoneFactory:"); PhoneProxy[] phones = (PhoneProxy[]) PhoneFactory.getPhones(); int i = -1; for (PhoneProxy phoneProxy : phones) { PhoneBase phoneBase; i += 1; try { phoneBase = (PhoneBase) phoneProxy.getActivePhone(); phoneBase.dump(fd, pw, args); } catch (Exception e) { pw.println("Telephony DebugService: Could not get Phone[" + i + "] e=" + e); continue; } pw.flush(); pw.println("++++++++++++++++++++++++++++++++"); try { ((IccCardProxy) phoneProxy.getIccCard()).dump(fd, pw, args); } catch (Exception e) { e.printStackTrace(); } pw.flush(); pw.println("++++++++++++++++++++++++++++++++"); } try { DctController.getInstance().dump(fd, pw, args); } catch (Exception e) { e.printStackTrace(); } try { mUiccController.dump(fd, pw, args); } catch (Exception e) { e.printStackTrace(); } pw.flush(); pw.println("++++++++++++++++++++++++++++++++"); try { SubscriptionController.getInstance().dump(fd, pw, args); } catch (Exception e) { e.printStackTrace(); } pw.flush(); pw.println("++++++++++++++++++++++++++++++++"); try { sSubInfoRecordUpdater.dump(fd, pw, args); } catch (Exception e) { e.printStackTrace(); } pw.flush(); pw.println("++++++++++++++++++++++++++++++++"); synchronized (sLocalLogs) { final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); for (String key : sLocalLogs.keySet()) { ipw.println(key); ipw.increaseIndent(); sLocalLogs.get(key).dump(fd, ipw, args); ipw.decreaseIndent(); } ipw.flush(); } }
public String getSystemProperty(String property, String defValue) { return TelephonyManager.getTelephonyProperty(mPhoneBase.getPhoneId(), property, defValue); }
@Override public void handleMessage(Message msg) { switch (msg.what) { case EVENT_SET_RADIO_POWER_OFF: synchronized (this) { if (mPendingRadioPowerOffAfterDataOff && (msg.arg1 == mPendingRadioPowerOffAfterDataOffTag)) { if (DBG) log("EVENT_SET_RADIO_OFF, turn radio off now."); hangupAndPowerOff(); mPendingRadioPowerOffAfterDataOffTag += 1; mPendingRadioPowerOffAfterDataOff = false; } else { log( "EVENT_SET_RADIO_OFF is stale arg1=" + msg.arg1 + "!= tag=" + mPendingRadioPowerOffAfterDataOffTag); } } break; case EVENT_ICC_CHANGED: onUpdateIccAvailability(); break; case EVENT_GET_CELL_INFO_LIST: { AsyncResult ar = (AsyncResult) msg.obj; CellInfoResult result = (CellInfoResult) ar.userObj; synchronized (result.lockObj) { if (ar.exception != null) { log("EVENT_GET_CELL_INFO_LIST: error ret null, e=" + ar.exception); result.list = null; } else { result.list = (List<CellInfo>) ar.result; if (VDBG) { log( "EVENT_GET_CELL_INFO_LIST: size=" + result.list.size() + " list=" + result.list); } } mLastCellInfoListTime = SystemClock.elapsedRealtime(); mLastCellInfoList = result.list; result.lockObj.notify(); } break; } case EVENT_UNSOL_CELL_INFO_LIST: { AsyncResult ar = (AsyncResult) msg.obj; if (ar.exception != null) { log("EVENT_UNSOL_CELL_INFO_LIST: error ignoring, e=" + ar.exception); } else { List<CellInfo> list = (List<CellInfo>) ar.result; if (DBG) { log("EVENT_UNSOL_CELL_INFO_LIST: size=" + list.size() + " list=" + list); } mLastCellInfoListTime = SystemClock.elapsedRealtime(); mLastCellInfoList = list; mPhoneBase.notifyCellInfo(list); } break; } case EVENT_IMS_STATE_CHANGED: // received unsol mCi.getImsRegistrationState(this.obtainMessage(EVENT_IMS_STATE_DONE)); break; case EVENT_IMS_STATE_DONE: AsyncResult ar = (AsyncResult) msg.obj; if (ar.exception == null) { int[] responseArray = (int[]) ar.result; mImsRegistered = (responseArray[0] == 1) ? true : false; } break; default: log("Unhandled message with number: " + msg.what); break; } }
protected int getPhoneId() { return mPhoneBase.getPhoneId(); }
protected String getHomeOperatorNumeric() { return ((TelephonyManager) mPhoneBase.getContext().getSystemService(Context.TELEPHONY_SERVICE)) .getSimOperatorNumericForPhone(mPhoneBase.getPhoneId()); }
// TBD move this to phone & implement in cdma & gsmphone DisconnectCause disconnectCauseFromCode(PhoneBase phone, int causeCode) { /** See 22.001 Annex F.4 for mapping of cause codes to local tones */ switch (causeCode) { case CallFailCause.USER_BUSY: return DisconnectCause.BUSY; case CallFailCause.NO_CIRCUIT_AVAIL: case CallFailCause.TEMPORARY_FAILURE: case CallFailCause.SWITCHING_CONGESTION: case CallFailCause.CHANNEL_NOT_AVAIL: case CallFailCause.QOS_NOT_AVAIL: case CallFailCause.BEARER_NOT_AVAIL: return DisconnectCause.CONGESTION; case CallFailCause.ACM_LIMIT_EXCEEDED: return DisconnectCause.LIMIT_EXCEEDED; case CallFailCause.CALL_BARRED: return DisconnectCause.CALL_BARRED; case CallFailCause.FDN_BLOCKED: return DisconnectCause.FDN_BLOCKED; case CallFailCause.UNOBTAINABLE_NUMBER: return DisconnectCause.UNOBTAINABLE_NUMBER; case CallFailCause.DIAL_MODIFIED_TO_USSD: return DisconnectCause.DIAL_MODIFIED_TO_USSD; case CallFailCause.DIAL_MODIFIED_TO_SS: return DisconnectCause.DIAL_MODIFIED_TO_SS; case CallFailCause.DIAL_MODIFIED_TO_DIAL: return DisconnectCause.DIAL_MODIFIED_TO_DIAL; case CallFailCause.CDMA_LOCKED_UNTIL_POWER_CYCLE: return DisconnectCause.CDMA_LOCKED_UNTIL_POWER_CYCLE; case CallFailCause.CDMA_DROP: return DisconnectCause.CDMA_DROP; case CallFailCause.CDMA_INTERCEPT: return DisconnectCause.CDMA_INTERCEPT; case CallFailCause.CDMA_REORDER: return DisconnectCause.CDMA_REORDER; case CallFailCause.CDMA_SO_REJECT: return DisconnectCause.CDMA_SO_REJECT; case CallFailCause.CDMA_RETRY_ORDER: return DisconnectCause.CDMA_RETRY_ORDER; case CallFailCause.CDMA_ACCESS_FAILURE: return DisconnectCause.CDMA_ACCESS_FAILURE; case CallFailCause.CDMA_PREEMPTED: return DisconnectCause.CDMA_PREEMPTED; case CallFailCause.CDMA_NOT_EMERGENCY: return DisconnectCause.CDMA_NOT_EMERGENCY; case CallFailCause.CDMA_ACCESS_BLOCKED: return DisconnectCause.CDMA_ACCESS_BLOCKED; case CallFailCause.ERROR_UNSPECIFIED: case CallFailCause.NORMAL_CLEARING: default: int serviceState = phone.getServiceState().getState(); if (serviceState == ServiceState.STATE_POWER_OFF) { return DisconnectCause.POWER_OFF; } else if (serviceState == ServiceState.STATE_OUT_OF_SERVICE || serviceState == ServiceState.STATE_EMERGENCY_ONLY) { return DisconnectCause.OUT_OF_SERVICE; } else if (causeCode == CallFailCause.NORMAL_CLEARING) { return DisconnectCause.NORMAL; } else { return DisconnectCause.ERROR_UNSPECIFIED; } } }