Loading src/java/com/android/internal/telephony/ServiceStateTracker.java +4 −0 Original line number Diff line number Diff line Loading @@ -127,6 +127,10 @@ public class ServiceStateTracker extends Handler { static public final int OTASP_UNKNOWN = 1; static public final int OTASP_NEEDED = 2; static public final int OTASP_NOT_NEEDED = 3; /** * OtaUtil has conflict enum 4: OtaUtils.OTASP_FAILURE_SPC_RETRIES */ static public final int OTASP_SIM_UNPROVISIONED = 5; /** * A unique identifier to track requests associated with a poll Loading src/java/com/android/internal/telephony/SubscriptionController.java +51 −6 Original line number Diff line number Diff line Loading @@ -290,12 +290,16 @@ public class SubscriptionController extends ISub.Stub { // FIXME: consider stick this into database too String countryIso = getSubscriptionCountryIso(id); int simProvisioningStatus = cursor.getInt(cursor.getColumnIndexOrThrow( SubscriptionManager.SIM_PROVISIONING_STATUS)); if (VDBG) { String iccIdToPrint = SubscriptionInfo.givePrintableIccid(iccId); logd("[getSubInfoRecord] id:" + id + " iccid:" + iccIdToPrint + " simSlotIndex:" + simSlotIndex + " displayName:" + displayName + " nameSource:" + nameSource logd("[getSubInfoRecord] id:" + id + " iccid:" + iccIdToPrint + " simSlotIndex:" + simSlotIndex + " displayName:" + displayName + " nameSource:" + nameSource + " iconTint:" + iconTint + " dataRoaming:" + dataRoaming + " mcc:" + mcc + " mnc:" + mnc + " countIso:" + countryIso); + " mcc:" + mcc + " mnc:" + mnc + " countIso:" + countryIso + " simProvisioningStatus:" + simProvisioningStatus); } // If line1number has been set to a different number, use it instead. Loading @@ -304,7 +308,8 @@ public class SubscriptionController extends ISub.Stub { number = line1Number; } return new SubscriptionInfo(id, iccId, simSlotIndex, displayName, carrierName, nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, countryIso); nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, countryIso, simProvisioningStatus); } /** Loading Loading @@ -1094,6 +1099,46 @@ public class SubscriptionController extends ISub.Stub { return result; } /** * Set SimProvisioning Status by subscription ID * @param provisioningStatus with the subscription: * {@See SubscriptionManager#SIM_PROVISIONED} * {@See SubscriptionManager#SIM_UNPROVISIONED_COLD} * {@See SubscriptionManager#SIM_UNPROVISIONED_OUT_OF_CREDIT} * @param subId the unique SubInfoRecord index in database * @return the number of records updated */ @Override public int setSimProvisioningStatus(int provisioningStatus, int subId) { if (DBG) { logd("[setSimProvisioningStatus]+ provisioningStatus:" + provisioningStatus + " subId:" + subId); } enforceModifyPhoneState("setSimProvisioningStatus"); // Now that all security checks passes, perform the operation as ourselves. final long identity = Binder.clearCallingIdentity(); try { validateSubId(subId); if (provisioningStatus < 0 || provisioningStatus > SubscriptionManager.MAX_SIM_PROVISIONING_STATUS) { logd("[setSimProvisioningStatus]- fail with wrong provisioningStatus"); return -1; } ContentValues value = new ContentValues(1); value.put(SubscriptionManager.SIM_PROVISIONING_STATUS, provisioningStatus); int result = mContext.getContentResolver().update(SubscriptionManager.CONTENT_URI, value, SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + Long.toString(subId), null); notifySubscriptionInfoChanged(); return result; } finally { Binder.restoreCallingIdentity(identity); } } @Override public int getSlotId(int subId) { Loading src/java/com/android/internal/telephony/dataconnection/DataConnection.java +13 −0 Original line number Diff line number Diff line Loading @@ -1800,6 +1800,19 @@ public class DataConnection extends StateMachine { mPhone.mCi.pullLceData(DataConnection.this.obtainMessage(EVENT_BW_REFRESH_RESPONSE)); } } @Override protected void networkStatus(int status, String redirectUrl) { if(!TextUtils.isEmpty(redirectUrl)) { log("validation status: " + status + " with redirection URL: " + redirectUrl); /* its possible that we have multiple DataConnection with INTERNET_CAPABILITY all fail the validation with the same redirection url, send CMD back to DCTracker and let DcTracker to make the decision */ Message msg = mDct.obtainMessage(DctConstants.EVENT_REDIRECTION_DETECTED, redirectUrl); msg.sendToTarget(); } } } // ******* "public" interface Loading src/java/com/android/internal/telephony/dataconnection/DcTracker.java +143 −4 Original line number Diff line number Diff line Loading @@ -27,10 +27,12 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.res.Resources; import android.database.ContentObserver; import android.database.Cursor; import android.net.ConnectivityManager; import android.net.ConnectivityManager.NetworkCallback; import android.net.LinkProperties; import android.net.NetworkCapabilities; import android.net.NetworkConfig; Loading @@ -48,6 +50,7 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.os.PersistableBundle; import android.os.RegistrantList; import android.os.ServiceManager; import android.os.SystemClock; Loading @@ -56,8 +59,10 @@ import android.preference.PreferenceManager; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; import android.provider.Telephony; import android.telephony.CarrierConfigManager; import android.telephony.CellLocation; import android.telephony.ServiceState; import android.telephony.SubscriptionInfo; import android.telephony.TelephonyManager; import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; Loading @@ -80,6 +85,8 @@ import com.android.internal.telephony.EventLogTags; import com.android.internal.telephony.ITelephony; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.RILConstants; import com.android.internal.telephony.SubscriptionController; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.uicc.IccRecords; import com.android.internal.telephony.uicc.UiccController; import com.android.internal.util.AsyncChannel; Loading Loading @@ -166,6 +173,10 @@ public class DcTracker extends Handler { private static final String INTENT_DATA_STALL_ALARM = "com.android.internal.telephony.data-stall"; private static final String REDIRECTION_URL_KEY = "redirectionUrl"; private static final String ERROR_CODE_KEY = "errorCode"; private static final String APN_TYPE_KEY = "apnType"; private DcTesterFailBringUpAll mDcTesterFailBringUpAll; private DcController mDcc; Loading Loading @@ -310,6 +321,8 @@ public class DcTracker extends Handler { int subId = mPhone.getSubId(); if (SubscriptionManager.isValidSubscriptionId(subId)) { registerSettingsObserver(); /* check if sim is un-provisioned due to cold sim detection */ applyColdSimDetected(subId); } if (mPreviousSubId.getAndSet(subId) != subId && SubscriptionManager.isValidSubscriptionId(subId)) { Loading Loading @@ -563,6 +576,14 @@ public class DcTracker extends Handler { private int mDisconnectPendingCount = 0; /** mRedirected is set to true when we first got the validation failure with the redirection URL * based on this value we start the Carrier App to check the sim state */ private boolean mRedirected = false; /** mColdSimDetected is set to true when we received SubInfoChanged && * SubscriptionInfo.simProvisioningStatus equals to SIM_UNPROVISIONED_COLD */ private boolean mColdSimDetected = false; /** * Handles changes to the APN db. */ Loading Loading @@ -895,6 +916,22 @@ public class DcTracker extends Handler { return true; } /** * Called when there is any change to any SubscriptionInfo Typically * this method invokes {@link SubscriptionManager#getActiveSubscriptionInfoList} */ private boolean isColdSimDetected(int subId) { final SubscriptionInfo subInfo = mSubscriptionManager.getActiveSubscriptionInfo(subId); if (subInfo != null) { final int simProvisioningStatus = subInfo.getSimProvisioningStatus(); if(simProvisioningStatus == SubscriptionManager.SIM_UNPROVISIONED_COLD) { log("Cold Sim Detected on SubId: " + subId); return true; } } return false; } public int getApnPriority(String name) { ApnContext apnContext = mApnContexts.get(name); if (apnContext == null) { Loading Loading @@ -1471,7 +1508,7 @@ public class DcTracker extends Handler { StringBuilder failureReason = new StringBuilder(); if (apnContext.isConnectable() && (isEmergencyApn || (isDataAllowed(failureReason) && isDataAllowedForApn(apnContext) && getAnyDataEnabled(checkUserDataEnabled) && !isEmergency()))) { getAnyDataEnabled(checkUserDataEnabled) && !isEmergency())) && !mColdSimDetected) { if (apnContext.getState() == DctConstants.State.FAILED) { String str ="trySetupData: make a FAILED ApnContext IDLE so its reusable"; if (DBG) log(str); Loading Loading @@ -1537,6 +1574,9 @@ public class DcTracker extends Handler { if (isEmergency()) { str.append("emergency = true"); } if(mColdSimDetected) { str.append("coldSimDetected = true"); } if (DBG) log(str.toString()); apnContext.requestLog(str.toString()); Loading Loading @@ -2280,6 +2320,24 @@ public class DcTracker extends Handler { setupDataOnConnectableApns(Phone.REASON_SIM_LOADED); } private void applyColdSimDetected(int subId) { if(isColdSimDetected(subId)) { if(!mColdSimDetected) { if(DBG) { log("onColdSimDetected on subId " + subId +": cleanUpAllDataConnections"); } cleanUpAllConnections(null); //send otasp_sim_unprovisioned so that SuW is able to proceed and notify users mPhone.notifyOtaspChanged(ServiceStateTracker.OTASP_SIM_UNPROVISIONED); mColdSimDetected = true; } } else { if (DBG) log("onColdSimDetected on subId: " + + subId + " reset coldSimDetected"); mColdSimDetected = false; mRedirected = false; } } private void onSimNotReady() { if (DBG) log("onSimNotReady"); Loading Loading @@ -2841,6 +2899,12 @@ public class DcTracker extends Handler { mPhone.notifyPreciseDataConnectionFailed(apnContext.getReason(), apnContext.getApnType(), apn != null ? apn.apn : "unknown", cause.toString()); //compose broadcast intent send to the specific carrier apps Intent intent = new Intent(TelephonyIntents.ACTION_REQUEST_NETWORK_FAILED); intent.putExtra(ERROR_CODE_KEY, cause.getErrorCode()); intent.putExtra(APN_TYPE_KEY, apnContext.getApnType()); notifyCarrierAppWithIntent(intent); if (cause.isRestartRadioFail() || apnContext.restartOnError(cause.getErrorCode())) { if (DBG) log("Modem restarted."); sendRestartRadio(); Loading Loading @@ -2924,6 +2988,45 @@ public class DcTracker extends Handler { } } /** * Read Carrier App name from CarrierConfig * @return String[0] Package name, String[1] Activity name */ private String[] getActivationAppName() { CarrierConfigManager configManager = (CarrierConfigManager) mPhone.getContext() .getSystemService(Context.CARRIER_CONFIG_SERVICE); PersistableBundle b = null; String[] activationApp; if (configManager != null) { b = configManager.getConfig(); } if (b != null) { activationApp = b.getStringArray(CarrierConfigManager .KEY_SIM_PROVISIONING_STATUS_DETECTION_CARRIER_APP_STRING_ARRAY); } else { // Return static default defined in CarrierConfigManager. activationApp = CarrierConfigManager.getDefaultConfig().getStringArray (CarrierConfigManager .KEY_SIM_PROVISIONING_STATUS_DETECTION_CARRIER_APP_STRING_ARRAY); } return activationApp; } /** * Called when EVENT_REDIRECTION_DETECTED is received. */ private void onDataConnectionRedirected(String redirectUrl) { if (!TextUtils.isEmpty(redirectUrl)) { mRedirected = true; Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_REDIRECTED); intent.putExtra(REDIRECTION_URL_KEY, redirectUrl); if(notifyCarrierAppWithIntent(intent)) { log("Starting Activation Carrier app with redirectUrl : " + redirectUrl); } } } /** * Called when EVENT_DISCONNECT_DONE is received. */ Loading Loading @@ -2958,7 +3061,6 @@ public class DcTracker extends Handler { return; } } // If APN is still enabled, try to bring it back up automatically if (mAttached.get() && apnContext.isReady() && retryAfterDisconnected(apnContext)) { try { Loading Loading @@ -3617,6 +3719,10 @@ public class DcTracker extends Handler { onDeviceProvisionedChange(); break; case DctConstants.EVENT_REDIRECTION_DETECTED: log("dataConnectionTracker.handleMessage: EVENT_REDIRECTION_DETECTED=" + msg); onDataConnectionRedirected((String) msg.obj); case DctConstants.EVENT_RADIO_AVAILABLE: onRadioAvailable(); break; Loading @@ -3632,6 +3738,7 @@ public class DcTracker extends Handler { case DctConstants.EVENT_DATA_SETUP_COMPLETE_ERROR: onDataSetupCompleteError((AsyncResult) msg.obj); break; case DctConstants.EVENT_DISCONNECT_DONE: log("DataConnectionTracker.handleMessage: EVENT_DISCONNECT_DONE msg=" + msg); onDisconnectDone((AsyncResult) msg.obj); Loading Loading @@ -3866,6 +3973,8 @@ public class DcTracker extends Handler { mIccRecords.set(newIccRecords); newIccRecords.registerForRecordsLoaded( this, DctConstants.EVENT_RECORDS_LOADED, null); SubscriptionController.getInstance().setSimProvisioningStatus( SubscriptionManager.SIM_PROVISIONED, mPhone.getSubId()); } } else { onSimNotReady(); Loading Loading @@ -3902,6 +4011,36 @@ public class DcTracker extends Handler { sendMessage(msg); } private boolean notifyCarrierAppWithIntent(Intent intent) { //read from carrier config manager String[] activationApp = getActivationAppName(); if(activationApp == null || activationApp.length != 2) { return false; } intent.setClassName(activationApp[0], activationApp[1]); intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, mPhone.getSubId()); //check if Activation App is available */ final PackageManager packageManager = mPhone.getContext().getPackageManager(); if (packageManager.queryBroadcastReceivers(intent, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { loge("Activation Carrier app is configured, but not available: " + activationApp[0] + "." + activationApp[1]); return false; } try { mPhone.getContext().sendBroadcast(intent); } catch (ActivityNotFoundException e) { loge("sendBroadcast failed: " + e); return false; } if (DBG) log("send Intent to : " + activationApp[0] + "." + activationApp[1] + " with action: " + intent.getAction()); return true; } private void notifyDataDisconnectComplete() { log("notifyDataDisconnectComplete"); for (Message m: mDisconnectAllCompleteMsgList) { Loading tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoTest.java +3 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ package com.android.internal.telephony; import android.telephony.SubscriptionManager; import android.test.suitebuilder.annotation.SmallTest; import static org.junit.Assert.*; import org.junit.After; Loading @@ -34,7 +35,8 @@ public class SubscriptionInfoTest { @Before public void setUp() throws Exception { mSubscriptionInfoUT = new SubscriptionInfo(1, "890126042XXXXXXXXXXX", 0, "T-mobile", "T-mobile", 0, 255, "12345", 0, null, 310, 260, "156"); "T-mobile", 0, 255, "12345", 0, null, 310, 260, "156", SubscriptionManager.SIM_PROVISIONED); } @Test Loading Loading
src/java/com/android/internal/telephony/ServiceStateTracker.java +4 −0 Original line number Diff line number Diff line Loading @@ -127,6 +127,10 @@ public class ServiceStateTracker extends Handler { static public final int OTASP_UNKNOWN = 1; static public final int OTASP_NEEDED = 2; static public final int OTASP_NOT_NEEDED = 3; /** * OtaUtil has conflict enum 4: OtaUtils.OTASP_FAILURE_SPC_RETRIES */ static public final int OTASP_SIM_UNPROVISIONED = 5; /** * A unique identifier to track requests associated with a poll Loading
src/java/com/android/internal/telephony/SubscriptionController.java +51 −6 Original line number Diff line number Diff line Loading @@ -290,12 +290,16 @@ public class SubscriptionController extends ISub.Stub { // FIXME: consider stick this into database too String countryIso = getSubscriptionCountryIso(id); int simProvisioningStatus = cursor.getInt(cursor.getColumnIndexOrThrow( SubscriptionManager.SIM_PROVISIONING_STATUS)); if (VDBG) { String iccIdToPrint = SubscriptionInfo.givePrintableIccid(iccId); logd("[getSubInfoRecord] id:" + id + " iccid:" + iccIdToPrint + " simSlotIndex:" + simSlotIndex + " displayName:" + displayName + " nameSource:" + nameSource logd("[getSubInfoRecord] id:" + id + " iccid:" + iccIdToPrint + " simSlotIndex:" + simSlotIndex + " displayName:" + displayName + " nameSource:" + nameSource + " iconTint:" + iconTint + " dataRoaming:" + dataRoaming + " mcc:" + mcc + " mnc:" + mnc + " countIso:" + countryIso); + " mcc:" + mcc + " mnc:" + mnc + " countIso:" + countryIso + " simProvisioningStatus:" + simProvisioningStatus); } // If line1number has been set to a different number, use it instead. Loading @@ -304,7 +308,8 @@ public class SubscriptionController extends ISub.Stub { number = line1Number; } return new SubscriptionInfo(id, iccId, simSlotIndex, displayName, carrierName, nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, countryIso); nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, countryIso, simProvisioningStatus); } /** Loading Loading @@ -1094,6 +1099,46 @@ public class SubscriptionController extends ISub.Stub { return result; } /** * Set SimProvisioning Status by subscription ID * @param provisioningStatus with the subscription: * {@See SubscriptionManager#SIM_PROVISIONED} * {@See SubscriptionManager#SIM_UNPROVISIONED_COLD} * {@See SubscriptionManager#SIM_UNPROVISIONED_OUT_OF_CREDIT} * @param subId the unique SubInfoRecord index in database * @return the number of records updated */ @Override public int setSimProvisioningStatus(int provisioningStatus, int subId) { if (DBG) { logd("[setSimProvisioningStatus]+ provisioningStatus:" + provisioningStatus + " subId:" + subId); } enforceModifyPhoneState("setSimProvisioningStatus"); // Now that all security checks passes, perform the operation as ourselves. final long identity = Binder.clearCallingIdentity(); try { validateSubId(subId); if (provisioningStatus < 0 || provisioningStatus > SubscriptionManager.MAX_SIM_PROVISIONING_STATUS) { logd("[setSimProvisioningStatus]- fail with wrong provisioningStatus"); return -1; } ContentValues value = new ContentValues(1); value.put(SubscriptionManager.SIM_PROVISIONING_STATUS, provisioningStatus); int result = mContext.getContentResolver().update(SubscriptionManager.CONTENT_URI, value, SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + Long.toString(subId), null); notifySubscriptionInfoChanged(); return result; } finally { Binder.restoreCallingIdentity(identity); } } @Override public int getSlotId(int subId) { Loading
src/java/com/android/internal/telephony/dataconnection/DataConnection.java +13 −0 Original line number Diff line number Diff line Loading @@ -1800,6 +1800,19 @@ public class DataConnection extends StateMachine { mPhone.mCi.pullLceData(DataConnection.this.obtainMessage(EVENT_BW_REFRESH_RESPONSE)); } } @Override protected void networkStatus(int status, String redirectUrl) { if(!TextUtils.isEmpty(redirectUrl)) { log("validation status: " + status + " with redirection URL: " + redirectUrl); /* its possible that we have multiple DataConnection with INTERNET_CAPABILITY all fail the validation with the same redirection url, send CMD back to DCTracker and let DcTracker to make the decision */ Message msg = mDct.obtainMessage(DctConstants.EVENT_REDIRECTION_DETECTED, redirectUrl); msg.sendToTarget(); } } } // ******* "public" interface Loading
src/java/com/android/internal/telephony/dataconnection/DcTracker.java +143 −4 Original line number Diff line number Diff line Loading @@ -27,10 +27,12 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.res.Resources; import android.database.ContentObserver; import android.database.Cursor; import android.net.ConnectivityManager; import android.net.ConnectivityManager.NetworkCallback; import android.net.LinkProperties; import android.net.NetworkCapabilities; import android.net.NetworkConfig; Loading @@ -48,6 +50,7 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.os.PersistableBundle; import android.os.RegistrantList; import android.os.ServiceManager; import android.os.SystemClock; Loading @@ -56,8 +59,10 @@ import android.preference.PreferenceManager; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; import android.provider.Telephony; import android.telephony.CarrierConfigManager; import android.telephony.CellLocation; import android.telephony.ServiceState; import android.telephony.SubscriptionInfo; import android.telephony.TelephonyManager; import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; Loading @@ -80,6 +85,8 @@ import com.android.internal.telephony.EventLogTags; import com.android.internal.telephony.ITelephony; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.RILConstants; import com.android.internal.telephony.SubscriptionController; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.uicc.IccRecords; import com.android.internal.telephony.uicc.UiccController; import com.android.internal.util.AsyncChannel; Loading Loading @@ -166,6 +173,10 @@ public class DcTracker extends Handler { private static final String INTENT_DATA_STALL_ALARM = "com.android.internal.telephony.data-stall"; private static final String REDIRECTION_URL_KEY = "redirectionUrl"; private static final String ERROR_CODE_KEY = "errorCode"; private static final String APN_TYPE_KEY = "apnType"; private DcTesterFailBringUpAll mDcTesterFailBringUpAll; private DcController mDcc; Loading Loading @@ -310,6 +321,8 @@ public class DcTracker extends Handler { int subId = mPhone.getSubId(); if (SubscriptionManager.isValidSubscriptionId(subId)) { registerSettingsObserver(); /* check if sim is un-provisioned due to cold sim detection */ applyColdSimDetected(subId); } if (mPreviousSubId.getAndSet(subId) != subId && SubscriptionManager.isValidSubscriptionId(subId)) { Loading Loading @@ -563,6 +576,14 @@ public class DcTracker extends Handler { private int mDisconnectPendingCount = 0; /** mRedirected is set to true when we first got the validation failure with the redirection URL * based on this value we start the Carrier App to check the sim state */ private boolean mRedirected = false; /** mColdSimDetected is set to true when we received SubInfoChanged && * SubscriptionInfo.simProvisioningStatus equals to SIM_UNPROVISIONED_COLD */ private boolean mColdSimDetected = false; /** * Handles changes to the APN db. */ Loading Loading @@ -895,6 +916,22 @@ public class DcTracker extends Handler { return true; } /** * Called when there is any change to any SubscriptionInfo Typically * this method invokes {@link SubscriptionManager#getActiveSubscriptionInfoList} */ private boolean isColdSimDetected(int subId) { final SubscriptionInfo subInfo = mSubscriptionManager.getActiveSubscriptionInfo(subId); if (subInfo != null) { final int simProvisioningStatus = subInfo.getSimProvisioningStatus(); if(simProvisioningStatus == SubscriptionManager.SIM_UNPROVISIONED_COLD) { log("Cold Sim Detected on SubId: " + subId); return true; } } return false; } public int getApnPriority(String name) { ApnContext apnContext = mApnContexts.get(name); if (apnContext == null) { Loading Loading @@ -1471,7 +1508,7 @@ public class DcTracker extends Handler { StringBuilder failureReason = new StringBuilder(); if (apnContext.isConnectable() && (isEmergencyApn || (isDataAllowed(failureReason) && isDataAllowedForApn(apnContext) && getAnyDataEnabled(checkUserDataEnabled) && !isEmergency()))) { getAnyDataEnabled(checkUserDataEnabled) && !isEmergency())) && !mColdSimDetected) { if (apnContext.getState() == DctConstants.State.FAILED) { String str ="trySetupData: make a FAILED ApnContext IDLE so its reusable"; if (DBG) log(str); Loading Loading @@ -1537,6 +1574,9 @@ public class DcTracker extends Handler { if (isEmergency()) { str.append("emergency = true"); } if(mColdSimDetected) { str.append("coldSimDetected = true"); } if (DBG) log(str.toString()); apnContext.requestLog(str.toString()); Loading Loading @@ -2280,6 +2320,24 @@ public class DcTracker extends Handler { setupDataOnConnectableApns(Phone.REASON_SIM_LOADED); } private void applyColdSimDetected(int subId) { if(isColdSimDetected(subId)) { if(!mColdSimDetected) { if(DBG) { log("onColdSimDetected on subId " + subId +": cleanUpAllDataConnections"); } cleanUpAllConnections(null); //send otasp_sim_unprovisioned so that SuW is able to proceed and notify users mPhone.notifyOtaspChanged(ServiceStateTracker.OTASP_SIM_UNPROVISIONED); mColdSimDetected = true; } } else { if (DBG) log("onColdSimDetected on subId: " + + subId + " reset coldSimDetected"); mColdSimDetected = false; mRedirected = false; } } private void onSimNotReady() { if (DBG) log("onSimNotReady"); Loading Loading @@ -2841,6 +2899,12 @@ public class DcTracker extends Handler { mPhone.notifyPreciseDataConnectionFailed(apnContext.getReason(), apnContext.getApnType(), apn != null ? apn.apn : "unknown", cause.toString()); //compose broadcast intent send to the specific carrier apps Intent intent = new Intent(TelephonyIntents.ACTION_REQUEST_NETWORK_FAILED); intent.putExtra(ERROR_CODE_KEY, cause.getErrorCode()); intent.putExtra(APN_TYPE_KEY, apnContext.getApnType()); notifyCarrierAppWithIntent(intent); if (cause.isRestartRadioFail() || apnContext.restartOnError(cause.getErrorCode())) { if (DBG) log("Modem restarted."); sendRestartRadio(); Loading Loading @@ -2924,6 +2988,45 @@ public class DcTracker extends Handler { } } /** * Read Carrier App name from CarrierConfig * @return String[0] Package name, String[1] Activity name */ private String[] getActivationAppName() { CarrierConfigManager configManager = (CarrierConfigManager) mPhone.getContext() .getSystemService(Context.CARRIER_CONFIG_SERVICE); PersistableBundle b = null; String[] activationApp; if (configManager != null) { b = configManager.getConfig(); } if (b != null) { activationApp = b.getStringArray(CarrierConfigManager .KEY_SIM_PROVISIONING_STATUS_DETECTION_CARRIER_APP_STRING_ARRAY); } else { // Return static default defined in CarrierConfigManager. activationApp = CarrierConfigManager.getDefaultConfig().getStringArray (CarrierConfigManager .KEY_SIM_PROVISIONING_STATUS_DETECTION_CARRIER_APP_STRING_ARRAY); } return activationApp; } /** * Called when EVENT_REDIRECTION_DETECTED is received. */ private void onDataConnectionRedirected(String redirectUrl) { if (!TextUtils.isEmpty(redirectUrl)) { mRedirected = true; Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_REDIRECTED); intent.putExtra(REDIRECTION_URL_KEY, redirectUrl); if(notifyCarrierAppWithIntent(intent)) { log("Starting Activation Carrier app with redirectUrl : " + redirectUrl); } } } /** * Called when EVENT_DISCONNECT_DONE is received. */ Loading Loading @@ -2958,7 +3061,6 @@ public class DcTracker extends Handler { return; } } // If APN is still enabled, try to bring it back up automatically if (mAttached.get() && apnContext.isReady() && retryAfterDisconnected(apnContext)) { try { Loading Loading @@ -3617,6 +3719,10 @@ public class DcTracker extends Handler { onDeviceProvisionedChange(); break; case DctConstants.EVENT_REDIRECTION_DETECTED: log("dataConnectionTracker.handleMessage: EVENT_REDIRECTION_DETECTED=" + msg); onDataConnectionRedirected((String) msg.obj); case DctConstants.EVENT_RADIO_AVAILABLE: onRadioAvailable(); break; Loading @@ -3632,6 +3738,7 @@ public class DcTracker extends Handler { case DctConstants.EVENT_DATA_SETUP_COMPLETE_ERROR: onDataSetupCompleteError((AsyncResult) msg.obj); break; case DctConstants.EVENT_DISCONNECT_DONE: log("DataConnectionTracker.handleMessage: EVENT_DISCONNECT_DONE msg=" + msg); onDisconnectDone((AsyncResult) msg.obj); Loading Loading @@ -3866,6 +3973,8 @@ public class DcTracker extends Handler { mIccRecords.set(newIccRecords); newIccRecords.registerForRecordsLoaded( this, DctConstants.EVENT_RECORDS_LOADED, null); SubscriptionController.getInstance().setSimProvisioningStatus( SubscriptionManager.SIM_PROVISIONED, mPhone.getSubId()); } } else { onSimNotReady(); Loading Loading @@ -3902,6 +4011,36 @@ public class DcTracker extends Handler { sendMessage(msg); } private boolean notifyCarrierAppWithIntent(Intent intent) { //read from carrier config manager String[] activationApp = getActivationAppName(); if(activationApp == null || activationApp.length != 2) { return false; } intent.setClassName(activationApp[0], activationApp[1]); intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, mPhone.getSubId()); //check if Activation App is available */ final PackageManager packageManager = mPhone.getContext().getPackageManager(); if (packageManager.queryBroadcastReceivers(intent, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { loge("Activation Carrier app is configured, but not available: " + activationApp[0] + "." + activationApp[1]); return false; } try { mPhone.getContext().sendBroadcast(intent); } catch (ActivityNotFoundException e) { loge("sendBroadcast failed: " + e); return false; } if (DBG) log("send Intent to : " + activationApp[0] + "." + activationApp[1] + " with action: " + intent.getAction()); return true; } private void notifyDataDisconnectComplete() { log("notifyDataDisconnectComplete"); for (Message m: mDisconnectAllCompleteMsgList) { Loading
tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoTest.java +3 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ package com.android.internal.telephony; import android.telephony.SubscriptionManager; import android.test.suitebuilder.annotation.SmallTest; import static org.junit.Assert.*; import org.junit.After; Loading @@ -34,7 +35,8 @@ public class SubscriptionInfoTest { @Before public void setUp() throws Exception { mSubscriptionInfoUT = new SubscriptionInfo(1, "890126042XXXXXXXXXXX", 0, "T-mobile", "T-mobile", 0, 255, "12345", 0, null, 310, 260, "156"); "T-mobile", 0, 255, "12345", 0, null, 310, 260, "156", SubscriptionManager.SIM_PROVISIONED); } @Test Loading