10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/*
20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2006 The Android Open Source Project
30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License");
50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License.
60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at
70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *      http://www.apache.org/licenses/LICENSE-2.0
90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software
110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS,
120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and
140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License.
150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage com.android.internal.telephony.gsm;
180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.app.AlarmManager;
200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.app.PendingIntent;
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.ContentResolver;
220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.ContentValues;
230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Context;
240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Intent;
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.IntentFilter;
26175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddinimport android.content.res.Resources;
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.database.ContentObserver;
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.database.Cursor;
290825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.net.ConnectivityManager;
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.net.LinkAddress;
310825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.net.LinkCapabilities;
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.net.LinkProperties;
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.net.LinkProperties.CompareResult;
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.net.NetworkConfig;
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.net.NetworkUtils;
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.net.ProxyProperties;
370825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.net.TrafficStats;
380825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.net.Uri;
390825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult;
400825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message;
410825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.SystemClock;
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.SystemProperties;
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.provider.Settings;
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.provider.Telephony;
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.CellLocation;
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.ServiceState;
470825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.TelephonyManager;
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.cdma.CdmaCellLocation;
490825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.gsm.GsmCellLocation;
500825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.text.TextUtils;
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.EventLog;
520825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.Log;
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
540825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.ApnContext;
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.ApnSetting;
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.DataCallState;
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.DataConnection;
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.DataConnection.FailCause;
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.DataConnection.UpdateLinkPropertyResult;
600825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.DataConnectionAc;
610825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.DataConnectionTracker;
620825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.DctConstants;
630825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.EventLogTags;
64e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenkaimport com.android.internal.telephony.IccCard;
65e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenkaimport com.android.internal.telephony.IccRecords;
660825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.Phone;
670825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.PhoneBase;
680825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.PhoneConstants;
690825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.RILConstants;
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.RetryManager;
71e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.UiccCard;
72e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.uicc.UiccController;
730825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.util.AsyncChannel;
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.FileDescriptor;
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.PrintWriter;
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.ArrayList;
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Collection;
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.HashMap;
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.List;
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.concurrent.ConcurrentHashMap;
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
860825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic final class GsmDataConnectionTracker extends DataConnectionTracker {
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected final String LOG_TAG = "GSM";
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Handles changes to the APN db.
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private class ApnChangeObserver extends ContentObserver {
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        public ApnChangeObserver () {
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            super(mDataConnectionTracker);
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        @Override
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        public void onChange(boolean selfChange) {
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            sendMessage(obtainMessage(DctConstants.EVENT_APN_CHANGED));
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Instance Variables
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mReregisterOnReconnectFailure = false;
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Constants
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int POLL_PDP_MILLIS = 5 * 1000;
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final String INTENT_RECONNECT_ALARM =
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "com.android.internal.telephony.gprs-reconnect";
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final String INTENT_RECONNECT_ALARM_EXTRA_TYPE = "reconnect_alarm_extra_type";
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final String INTENT_RECONNECT_ALARM_EXTRA_RETRY_COUNT =
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "reconnect_alaram_extra_retry_count";
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final String INTENT_DATA_STALL_ALARM =
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "com.android.internal.telephony.gprs-data-stall";
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final Uri PREFERAPN_NO_UPDATE_URI =
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        Uri.parse("content://telephony/carriers/preferapn_no_update");
1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final String APN_ID = "apn_id";
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean canSetPreferApn = false;
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final boolean DATA_STALL_SUSPECTED = true;
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final boolean DATA_STALL_NOT_SUSPECTED = false;
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onActionIntentReconnectAlarm(Intent intent) {
1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON);
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int connectionId = intent.getIntExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, -1);
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int retryCount = intent.getIntExtra(INTENT_RECONNECT_ALARM_EXTRA_RETRY_COUNT, 0);
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        DataConnectionAc dcac= mDataConnectionAsyncChannels.get(connectionId);
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("onActionIntentReconnectAlarm: mState=" + mState + " reason=" + reason +
13927814a2e735c0221935d46654fb00ff3ec2c45eaWink Saville                    " connectionId=" + connectionId + " retryCount=" + retryCount + " dcac=" + dcac
14027814a2e735c0221935d46654fb00ff3ec2c45eaWink Saville                    + " mDataConnectionAsyncChannels=" + mDataConnectionAsyncChannels);
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (dcac != null) {
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (ApnContext apnContext : dcac.getApnListSync()) {
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext.setReason(reason);
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext.setRetryCount(retryCount);
14727814a2e735c0221935d46654fb00ff3ec2c45eaWink Saville                DctConstants.State apnContextState = apnContext.getState();
14827814a2e735c0221935d46654fb00ff3ec2c45eaWink Saville                if (DBG) {
14927814a2e735c0221935d46654fb00ff3ec2c45eaWink Saville                    log("onActionIntentReconnectAlarm: apnContext state=" + apnContextState);
15027814a2e735c0221935d46654fb00ff3ec2c45eaWink Saville                }
15127814a2e735c0221935d46654fb00ff3ec2c45eaWink Saville                if ((apnContextState == DctConstants.State.FAILED)
15227814a2e735c0221935d46654fb00ff3ec2c45eaWink Saville                        || (apnContextState == DctConstants.State.IDLE)) {
15327814a2e735c0221935d46654fb00ff3ec2c45eaWink Saville                    if (DBG) {
15427814a2e735c0221935d46654fb00ff3ec2c45eaWink Saville                        log("onActionIntentReconnectAlarm: state is FAILED|IDLE, disassociate");
15527814a2e735c0221935d46654fb00ff3ec2c45eaWink Saville                    }
15627814a2e735c0221935d46654fb00ff3ec2c45eaWink Saville                    apnContext.setDataConnectionAc(null);
15727814a2e735c0221935d46654fb00ff3ec2c45eaWink Saville                    apnContext.setDataConnection(null);
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.setState(DctConstants.State.IDLE);
15927814a2e735c0221935d46654fb00ff3ec2c45eaWink Saville                } else {
16027814a2e735c0221935d46654fb00ff3ec2c45eaWink Saville                    if (DBG) {
16127814a2e735c0221935d46654fb00ff3ec2c45eaWink Saville                        log("onActionIntentReconnectAlarm: keep associated");
16227814a2e735c0221935d46654fb00ff3ec2c45eaWink Saville                    }
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                sendMessage(obtainMessage(DctConstants.EVENT_TRY_SETUP_DATA, apnContext));
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Alram had expired. Clear pending intent recorded on the DataConnection.
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            dcac.setReconnectIntentSync(null);
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Watches for changes to the APN db. */
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private ApnChangeObserver mApnObserver;
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Constructor
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public GsmDataConnectionTracker(PhoneBase p) {
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        super(p);
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("GsmDCT.constructor");
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.mCM.registerForAvailable (this, DctConstants.EVENT_RADIO_AVAILABLE, null);
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.mCM.registerForOffOrNotAvailable(this, DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE,
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                null);
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.mCM.registerForDataNetworkStateChanged (this, DctConstants.EVENT_DATA_STATE_CHANGED,
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                null);
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.getCallTracker().registerForVoiceCallEnded (this, DctConstants.EVENT_VOICE_CALL_ENDED,
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                null);
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.getCallTracker().registerForVoiceCallStarted (this, DctConstants.EVENT_VOICE_CALL_STARTED,
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                null);
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.getServiceStateTracker().registerForDataConnectionAttached(this,
1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null);
1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.getServiceStateTracker().registerForDataConnectionDetached(this,
1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                DctConstants.EVENT_DATA_CONNECTION_DETACHED, null);
1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.getServiceStateTracker().registerForRoamingOn(this, DctConstants.EVENT_ROAMING_ON, null);
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.getServiceStateTracker().registerForRoamingOff(this, DctConstants.EVENT_ROAMING_OFF,
1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                null);
1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.getServiceStateTracker().registerForPsRestrictedEnabled(this,
1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                DctConstants.EVENT_PS_RESTRICT_ENABLED, null);
1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.getServiceStateTracker().registerForPsRestrictedDisabled(this,
1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                DctConstants.EVENT_PS_RESTRICT_DISABLED, null);
1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDataConnectionTracker = this;
2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mApnObserver = new ApnChangeObserver();
2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.getContext().getContentResolver().registerContentObserver(
2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Telephony.Carriers.CONTENT_URI, true, mApnObserver);
2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        initApnContextsAndDataConnection();
2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        broadcastMessenger();
2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dispose() {
2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("GsmDCT.dispose");
213c62df086696fc7cb42c51e086ea2aab076cff24bAjay Nambi        cleanUpAllConnections(true, null);
2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        super.dispose();
2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //Unregister for all events
2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.mCM.unregisterForAvailable(this);
2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.mCM.unregisterForOffOrNotAvailable(this);
220e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        IccRecords r = mIccRecords.get();
221e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        if (r != null) { r.unregisterForRecordsLoaded(this);}
2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.mCM.unregisterForDataNetworkStateChanged(this);
2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.getCallTracker().unregisterForVoiceCallEnded(this);
2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.getCallTracker().unregisterForVoiceCallStarted(this);
2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.getServiceStateTracker().unregisterForDataConnectionAttached(this);
2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.getServiceStateTracker().unregisterForDataConnectionDetached(this);
2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.getServiceStateTracker().unregisterForRoamingOn(this);
2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.getServiceStateTracker().unregisterForRoamingOff(this);
2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.getServiceStateTracker().unregisterForPsRestrictedEnabled(this);
2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.getServiceStateTracker().unregisterForPsRestrictedDisabled(this);
2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.getContext().getContentResolver().unregisterContentObserver(this.mApnObserver);
2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mApnContexts.clear();
2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        destroyDataConnections();
2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean isApnTypeActive(String type) {
2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnContext apnContext = mApnContexts.get(type);
2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext == null) return false;
2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return (apnContext.getDataConnection() != null);
2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected boolean isDataPossible(String apnType) {
2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnContext apnContext = mApnContexts.get(apnType);
2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext == null) {
2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean apnContextIsEnabled = apnContext.isEnabled();
2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        DctConstants.State apnContextState = apnContext.getState();
2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean apnTypePossible = !(apnContextIsEnabled &&
2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                (apnContextState == DctConstants.State.FAILED));
2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean dataAllowed = isDataAllowed();
2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean possible = dataAllowed && apnTypePossible;
2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log(String.format("isDataPossible(%s): possible=%b isDataAllowed=%b " +
2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    "apnTypePossible=%b apnContextisEnabled=%b apnContextState()=%s",
2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnType, possible, dataAllowed, apnTypePossible,
2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContextIsEnabled, apnContextState));
2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return possible;
2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void finalize() {
2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if(DBG) log("finalize");
2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected String getActionIntentReconnectAlarm() {
2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return INTENT_RECONNECT_ALARM;
2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected String getActionIntentDataStallAlarm() {
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return INTENT_DATA_STALL_ALARM;
2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private ApnContext addApnContext(String type) {
2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnContext apnContext = new ApnContext(type, LOG_TAG);
2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        apnContext.setDependencyMet(false);
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mApnContexts.put(type, apnContext);
2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return apnContext;
2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void initApnContextsAndDataConnection() {
2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean defaultEnabled = SystemProperties.getBoolean(DEFALUT_DATA_ON_BOOT_PROP, true);
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Load device network attributes from resources
2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String[] networkConfigStrings = mPhone.getContext().getResources().getStringArray(
2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                com.android.internal.R.array.networkAttributes);
2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (String networkConfigString : networkConfigStrings) {
2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            NetworkConfig networkConfig = new NetworkConfig(networkConfigString);
2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ApnContext apnContext = null;
2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            switch (networkConfig.type) {
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case ConnectivityManager.TYPE_MOBILE:
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext = addApnContext(PhoneConstants.APN_TYPE_DEFAULT);
3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext.setEnabled(defaultEnabled);
3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case ConnectivityManager.TYPE_MOBILE_MMS:
3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext = addApnContext(PhoneConstants.APN_TYPE_MMS);
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case ConnectivityManager.TYPE_MOBILE_SUPL:
3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext = addApnContext(PhoneConstants.APN_TYPE_SUPL);
3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case ConnectivityManager.TYPE_MOBILE_DUN:
3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext = addApnContext(PhoneConstants.APN_TYPE_DUN);
3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case ConnectivityManager.TYPE_MOBILE_HIPRI:
3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext = addApnContext(PhoneConstants.APN_TYPE_HIPRI);
3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ApnContext defaultContext = mApnContexts.get(PhoneConstants.APN_TYPE_DEFAULT);
3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (defaultContext != null) {
3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    applyNewState(apnContext, apnContext.isEnabled(),
3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            defaultContext.getDependencyMet());
3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // the default will set the hipri dep-met when it is created
3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                continue;
3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case ConnectivityManager.TYPE_MOBILE_FOTA:
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext = addApnContext(PhoneConstants.APN_TYPE_FOTA);
3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case ConnectivityManager.TYPE_MOBILE_IMS:
3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext = addApnContext(PhoneConstants.APN_TYPE_IMS);
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case ConnectivityManager.TYPE_MOBILE_CBS:
3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext = addApnContext(PhoneConstants.APN_TYPE_CBS);
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // skip unknown types
3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                continue;
3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (apnContext != null) {
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // set the prop, but also apply the newly set enabled and dependency values
3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                onSetDependencyMet(apnContext.getApnType(), networkConfig.dependencyMet);
3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected LinkProperties getLinkProperties(String apnType) {
3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnContext apnContext = mApnContexts.get(apnType);
3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext != null) {
3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            DataConnectionAc dcac = apnContext.getDataConnectionAc();
3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dcac != null) {
3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("return link properites for " + apnType);
3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return dcac.getLinkPropertiesSync();
3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("return new LinkProperties");
3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return new LinkProperties();
3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected LinkCapabilities getLinkCapabilities(String apnType) {
3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnContext apnContext = mApnContexts.get(apnType);
3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext!=null) {
3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            DataConnectionAc dataConnectionAc = apnContext.getDataConnectionAc();
3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dataConnectionAc != null) {
3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("get active pdp is not null, return link Capabilities for " + apnType);
3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return dataConnectionAc.getLinkCapabilitiesSync();
3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("return new LinkCapabilities");
3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return new LinkCapabilities();
3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Return all active apn types
3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public String[] getActiveApnTypes() {
3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("get all active apn types");
3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ArrayList<String> result = new ArrayList<String>();
3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (ApnContext apnContext : mApnContexts.values()) {
3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (apnContext.isReady()) {
3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                result.add(apnContext.getApnType());
3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return (String[])result.toArray(new String[0]);
3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Return active apn of specific apn type
3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public String getActiveApnString(String apnType) {
3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log( "get active apn string for type:" + apnType);
3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnContext apnContext = mApnContexts.get(apnType);
3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext != null) {
3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ApnSetting apnSetting = apnContext.getApnSetting();
3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (apnSetting != null) {
3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return apnSetting.apn;
3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return null;
3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean isApnTypeEnabled(String apnType) {
4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnContext apnContext = mApnContexts.get(apnType);
4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext == null) {
4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return apnContext.isEnabled();
4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void setState(DctConstants.State s) {
4110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("setState should not be used in GSM" + s);
4120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Return state of specific apn type
4150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public DctConstants.State getState(String apnType) {
4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnContext apnContext = mApnContexts.get(apnType);
4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext != null) {
4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return apnContext.getState();
4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return DctConstants.State.FAILED;
4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Return state of overall
4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public DctConstants.State getOverallState() {
4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean isConnecting = false;
4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean isFailed = true; // All enabled Apns should be FAILED.
4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean isAnyEnabled = false;
4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (ApnContext apnContext : mApnContexts.values()) {
4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (apnContext.isEnabled()) {
4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                isAnyEnabled = true;
4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                switch (apnContext.getState()) {
4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case CONNECTED:
4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case DISCONNECTING:
4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) log("overall state is CONNECTED");
4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return DctConstants.State.CONNECTED;
4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case CONNECTING:
4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case INITING:
4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    isConnecting = true;
4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    isFailed = false;
4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case IDLE:
4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case SCANNING:
4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    isFailed = false;
4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!isAnyEnabled) { // Nothing enabled. return IDLE.
4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log( "overall state is IDLE");
4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return DctConstants.State.IDLE;
4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (isConnecting) {
4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log( "overall state is CONNECTING");
4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return DctConstants.State.CONNECTING;
4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (!isFailed) {
4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log( "overall state is IDLE");
4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return DctConstants.State.IDLE;
4620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log( "overall state is FAILED");
4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return DctConstants.State.FAILED;
4650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
4690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Ensure that we are connected to an APN of the specified type.
4700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param type the APN type
4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return Success is indicated by {@code PhoneConstants.APN_ALREADY_ACTIVE} or
4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *         {@code PhoneConstants.APN_REQUEST_STARTED}. In the latter case, a
4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *         broadcast will be sent by the ConnectivityManager when a
4750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *         connection to the APN has been established.
4760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
4770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public synchronized int enableApnType(String apnType) {
4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnContext apnContext = mApnContexts.get(apnType);
4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext == null || !isApnTypeAvailable(apnType)) {
4810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("enableApnType: " + apnType + " is type not available");
4820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return PhoneConstants.APN_TYPE_NOT_AVAILABLE;
4830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If already active, return
4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("enableApnType: " + apnType + " mState(" + apnContext.getState() + ")");
4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext.getState() == DctConstants.State.CONNECTED) {
4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("enableApnType: return APN_ALREADY_ACTIVE");
4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return PhoneConstants.APN_ALREADY_ACTIVE;
4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        setEnabled(apnTypeToId(apnType), true);
4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("enableApnType: new apn request for type " + apnType +
4950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " return APN_REQUEST_STARTED");
4960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return PhoneConstants.APN_REQUEST_STARTED;
4980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // A new APN has gone active and needs to send events to catch up with the
5010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // current condition
5020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void notifyApnIdUpToCurrent(String reason, ApnContext apnContext, String type) {
5030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (apnContext.getState()) {
5040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case IDLE:
5050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case INITING:
5060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
5070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case CONNECTING:
5080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case SCANNING:
5090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPhone.notifyDataConnection(reason, type, PhoneConstants.DataState.CONNECTING);
5100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
5110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case CONNECTED:
5120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DISCONNECTING:
5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPhone.notifyDataConnection(reason, type, PhoneConstants.DataState.CONNECTING);
5140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPhone.notifyDataConnection(reason, type, PhoneConstants.DataState.CONNECTED);
5150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public synchronized int disableApnType(String type) {
5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("disableApnType:" + type);
5220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnContext apnContext = mApnContexts.get(type);
5230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext != null) {
5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setEnabled(apnTypeToId(type), false);
5260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (apnContext.getState() != DctConstants.State.IDLE && apnContext.getState()
5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    != DctConstants.State.FAILED) {
5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("diableApnType: return APN_REQUEST_STARTED");
5290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return PhoneConstants.APN_REQUEST_STARTED;
5300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
5310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("disableApnType: return APN_ALREADY_INACTIVE");
5320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return PhoneConstants.APN_ALREADY_INACTIVE;
5330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
5360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
5370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("disableApnType: no apn context was found, return APN_REQUEST_FAILED");
5380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return PhoneConstants.APN_REQUEST_FAILED;
5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
5440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected boolean isApnTypeAvailable(String type) {
5450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (type.equals(PhoneConstants.APN_TYPE_DUN) && fetchDunApn() != null) {
5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mAllApns != null) {
5500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (ApnSetting apn : mAllApns) {
5510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (apn.canHandleType(type)) {
5520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return true;
5530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return false;
5570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Report on whether data connectivity is enabled for any APN.
5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return {@code false} if data connectivity has been explicitly disabled,
5620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * {@code true} otherwise.
5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
5650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean getAnyDataEnabled() {
5660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized (mDataEnabledLock) {
5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!(mInternalDataEnabled && mUserDataEnabled && sPolicyDataEnabled)) return false;
5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (ApnContext apnContext : mApnContexts.values()) {
5690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Make sure we dont have a context that going down
5700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // and is explicitly disabled.
5710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (isDataAllowed(apnContext)) {
5720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return true;
5730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
5760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean isDataAllowed(ApnContext apnContext) {
5800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return apnContext.isReady() && isDataAllowed();
5810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //****** Called from ServiceStateTracker
5840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Invoked when ServiceStateTracker observes a transition from GPRS
5860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * attach to detach.
5870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
5880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onDataConnectionDetached() {
5890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        /*
5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * We presently believe it is unnecessary to tear down the PDP context
5910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * when GPRS detaches, but we should stop the network polling.
5920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         */
5930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log ("onDataConnectionDetached: stop polling and notify detached");
5940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        stopNetStatPoll();
5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        stopDataStallAlarm();
5960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        notifyDataConnection(Phone.REASON_DATA_DETACHED);
5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void onDataConnectionAttached() {
6000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onDataConnectionAttached");
6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (getOverallState() == DctConstants.State.CONNECTED) {
6020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("onDataConnectionAttached: start polling notify attached");
6030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            startNetStatPoll();
6040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
6050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notifyDataConnection(Phone.REASON_DATA_ATTACHED);
6060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
6070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // update APN availability so that APN can be enabled.
6080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notifyOffApnsOfAvailability(Phone.REASON_DATA_ATTACHED);
6090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        setupDataOnReadyApns(Phone.REASON_DATA_ATTACHED);
6120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
6150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected boolean isDataAllowed() {
6160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        final boolean internalDataEnabled;
6170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized (mDataEnabledLock) {
6180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            internalDataEnabled = mInternalDataEnabled;
6190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int gprsState = mPhone.getServiceStateTracker().getCurrentDataConnectionState();
6220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
623e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        IccRecords r = mIccRecords.get();
624e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        boolean recordsLoaded = (r != null) ? r.getRecordsLoaded() : false;
6250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean allowed =
6270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    (gprsState == ServiceState.STATE_IN_SERVICE || mAutoAttachOnCreation) &&
628e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                    recordsLoaded &&
6290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    (mPhone.getState() == PhoneConstants.State.IDLE ||
6300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                     mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) &&
6310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    internalDataEnabled &&
6320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    (!mPhone.getServiceState().getRoaming() || getDataOnRoamingEnabled()) &&
6330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    !mIsPsRestricted &&
6340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    desiredPowerState;
6350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!allowed && DBG) {
6360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String reason = "";
6370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!((gprsState == ServiceState.STATE_IN_SERVICE) || mAutoAttachOnCreation)) {
6380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                reason += " - gprs= " + gprsState;
6390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
640e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            if (!recordsLoaded) reason += " - SIM not loaded";
6410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (mPhone.getState() != PhoneConstants.State.IDLE &&
6420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
6430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                reason += " - PhoneState= " + mPhone.getState();
6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                reason += " - Concurrent voice and data not allowed";
6450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!internalDataEnabled) reason += " - mInternalDataEnabled= false";
6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (mPhone.getServiceState().getRoaming() && !getDataOnRoamingEnabled()) {
6480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                reason += " - Roaming and data roaming not enabled";
6490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (mIsPsRestricted) reason += " - mIsPsRestricted= true";
6510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!desiredPowerState) reason += " - desiredPowerState= false";
6520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("isDataAllowed: not allowed due to" + reason);
6530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return allowed;
6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void setupDataOnReadyApns(String reason) {
6580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Stop reconnect alarms on all data connections pending
6590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // retry. Reset ApnContext state to IDLE.
6600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
6610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dcac.getReconnectIntentSync() != null) {
6620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cancelReconnectAlarm(dcac);
6630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // update retry config for existing calls to match up
6650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // ones for the new RAT.
6660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dcac.dataConnection != null) {
6670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Collection<ApnContext> apns = dcac.getApnListSync();
6680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                boolean hasDefault = false;
6700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                for (ApnContext apnContext : apns) {
6710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)) {
6720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        hasDefault = true;
6730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        break;
6740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
6750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
6760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                configureRetry(dcac.dataConnection, hasDefault, 0);
6770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Be sure retry counts for Apncontexts and DC's are sync'd.
6810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // When DCT/ApnContexts are refactored and we cleanup retrying
6820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // this won't be needed.
6830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        resetAllRetryCounts();
6840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Only check for default APN state
6860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (ApnContext apnContext : mApnContexts.values()) {
6870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (apnContext.getState() == DctConstants.State.FAILED) {
6880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // By this time, alarms for all failed Apns
6890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // should be stopped if any.
6900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Make sure to set the state back to IDLE
6910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // so that setup data can happen.
6920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext.setState(DctConstants.State.IDLE);
6930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (apnContext.isReady()) {
69520659cc78b898b553a54bb6d9d7728f326b77bd1Robert Greenwalt                if (apnContext.getState() == DctConstants.State.IDLE ||
69620659cc78b898b553a54bb6d9d7728f326b77bd1Robert Greenwalt                        apnContext.getState() == DctConstants.State.SCANNING) {
6970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.setReason(reason);
6980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    trySetupData(apnContext);
6990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
7000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean trySetupData(String reason, String type) {
7050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
7060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("trySetupData: " + type + " due to " + (reason == null ? "(unspecified)" : reason)
7070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    + " isPsRestricted=" + mIsPsRestricted);
7080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (type == null) {
7110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            type = PhoneConstants.APN_TYPE_DEFAULT;
7120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnContext apnContext = mApnContexts.get(type);
7150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext == null ){
7170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("trySetupData new apn context for type:" + type);
7180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apnContext = new ApnContext(type, LOG_TAG);
7190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mApnContexts.put(type, apnContext);
7200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        apnContext.setReason(reason);
7220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return trySetupData(apnContext);
7240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean trySetupData(ApnContext apnContext) {
7270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
7280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("trySetupData for type:" + apnContext.getApnType() +
7290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " due to " + apnContext.getReason());
7300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("trySetupData with mIsPsRestricted=" + mIsPsRestricted);
7310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mPhone.getSimulatedRadioControl() != null) {
7340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Assume data is connected on the simulator
7350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // FIXME  this can be improved
7360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apnContext.setState(DctConstants.State.CONNECTED);
7370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
7380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("trySetupData: (fix?) We're on the simulator; assuming data is connected");
7400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
7410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
7440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if ((apnContext.getState() == DctConstants.State.IDLE ||
7460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.getState() == DctConstants.State.SCANNING) &&
7470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                isDataAllowed(apnContext) && getAnyDataEnabled() && !isEmergency()) {
7480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (apnContext.getState() == DctConstants.State.IDLE) {
7500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ArrayList<ApnSetting> waitingApns = buildWaitingApns(apnContext.getApnType());
7510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (waitingApns.isEmpty()) {
7520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) log("trySetupData: No APN found");
7530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    notifyNoData(GsmDataConnection.FailCause.MISSING_UNKNOWN_APN, apnContext);
7540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    notifyOffApnsOfAvailability(apnContext.getReason());
7550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return false;
7560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
7570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.setWaitingApns(waitingApns);
7580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) {
7590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log ("trySetupData: Create from mAllApns : " + apnListToString(mAllApns));
7600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
7610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
7620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
7650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log ("Setup watingApns : " + apnListToString(apnContext.getWaitingApns()));
7660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // apnContext.setReason(apnContext.getReason());
7680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            boolean retValue = setupData(apnContext);
7690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notifyOffApnsOfAvailability(apnContext.getReason());
7700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return retValue;
7710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
7720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // TODO: check the condition.
7730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
7740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                && (apnContext.getState() == DctConstants.State.IDLE
7750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    || apnContext.getState() == DctConstants.State.SCANNING))
7760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
7770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notifyOffApnsOfAvailability(apnContext.getReason());
7780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
7790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
7830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Disabled apn's still need avail/unavail notificiations - send them out
7840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void notifyOffApnsOfAvailability(String reason) {
7850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (ApnContext apnContext : mApnContexts.values()) {
7860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!apnContext.isReady()) {
7870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("notifyOffApnOfAvailability type:" + apnContext.getApnType());
7880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
7890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                            apnContext.getApnType(),
7900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                            PhoneConstants.DataState.DISCONNECTED);
7910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
7920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) {
7930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("notifyOffApnsOfAvailability skipped apn due to isReady==false: " +
7940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            apnContext.toString());
7950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
7960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
8010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * If tearDown is true, this only tears down a CONNECTED session. Presently,
8020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * there is no mechanism for abandoning an INITING/CONNECTING session,
8030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * but would likely involve cancelling pending async requests or
8040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * setting a flag or new state to ignore them when they came in
8050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param tearDown true if the underlying GsmDataConnection should be
8060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * disconnected.
8070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param reason reason for the clean up.
8080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
8090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void cleanUpAllConnections(boolean tearDown, String reason) {
8100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("cleanUpAllConnections: tearDown=" + tearDown + " reason=" + reason);
8110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (ApnContext apnContext : mApnContexts.values()) {
8130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apnContext.setReason(reason);
8140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cleanUpConnection(tearDown, apnContext);
8150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        stopNetStatPoll();
8180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        stopDataStallAlarm();
8190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // TODO: Do we need mRequestedApnType?
8210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
8220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
8250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Cleanup all connections.
8260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
8270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * TODO: Cleanup only a specified connection passed as a parameter.
8280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *       Also, make sure when you clean up a conn, if it is last apply
8290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *       logic as though it is cleanupAllConnections
8300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
8310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param tearDown true if the underlying DataConnection should be disconnected.
8320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param reason for the clean up.
8330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
8340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
8360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onCleanUpAllConnections(String cause) {
8370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cleanUpAllConnections(true, cause);
8380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void cleanUpConnection(boolean tearDown, ApnContext apnContext) {
8410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext == null) {
8430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("cleanUpConnection: apn context is null");
8440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
8450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        DataConnectionAc dcac = apnContext.getDataConnectionAc();
8480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
8490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("cleanUpConnection: E tearDown=" + tearDown + " reason=" + apnContext.getReason() +
8500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " apnContext=" + apnContext);
8510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (tearDown) {
8530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (apnContext.isDisconnected()) {
8540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // The request is tearDown and but ApnContext is not connected.
8550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // If apnContext is not enabled anymore, break the linkage to the DCAC/DC.
8560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext.setState(DctConstants.State.IDLE);
8570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!apnContext.isReady()) {
8580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.setDataConnection(null);
8590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.setDataConnectionAc(null);
8600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
8610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
8620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Connection is still there. Try to clean up.
8630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (dcac != null) {
8640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (apnContext.getState() != DctConstants.State.DISCONNECTING) {
8650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        boolean disconnectAll = false;
8660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (PhoneConstants.APN_TYPE_DUN.equals(apnContext.getApnType())) {
8670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            ApnSetting dunSetting = fetchDunApn();
8680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (dunSetting != null &&
8690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    dunSetting.equals(apnContext.getApnSetting())) {
8700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (DBG) log("tearing down dedicated DUN connection");
8710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                // we need to tear it down - we brought it up just for dun and
8720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                // other people are camped on it and now dun is done.  We need
8730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                // to stop using it and let the normal apn list get used to find
8740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                // connections for the remaining desired connections
8750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                disconnectAll = true;
8760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
8770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
8780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) {
8790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            log("cleanUpConnection: tearing down" + (disconnectAll ? " all" :""));
8800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
8810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        Message msg = obtainMessage(DctConstants.EVENT_DISCONNECT_DONE, apnContext);
8820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (disconnectAll) {
8830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            apnContext.getDataConnection().tearDownAll(apnContext.getReason(), msg);
8840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        } else {
8850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            apnContext.getDataConnection().tearDown(apnContext.getReason(), msg);
8860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
8870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        apnContext.setState(DctConstants.State.DISCONNECTING);
8880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
8890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
8900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // apn is connected but no reference to dcac.
8910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Should not be happen, but reset the state in case.
8920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.setState(DctConstants.State.IDLE);
8930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mPhone.notifyDataConnection(apnContext.getReason(),
8940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                                apnContext.getApnType());
8950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
8960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
8980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // force clean up the data connection.
8990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dcac != null) dcac.resetSync();
9000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apnContext.setState(DctConstants.State.IDLE);
9010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
9020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apnContext.setDataConnection(null);
9030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apnContext.setDataConnectionAc(null);
9040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // make sure reconnection alarm is cleaned up if there is no ApnContext
9070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // associated to the connection.
9080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (dcac != null) {
9090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Collection<ApnContext> apnList = dcac.getApnListSync();
9100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (apnList.isEmpty()) {
9110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cancelReconnectAlarm(dcac);
9120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
9130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
9150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("cleanUpConnection: X tearDown=" + tearDown + " reason=" + apnContext.getReason() +
9160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " apnContext=" + apnContext + " dc=" + apnContext.getDataConnection());
9170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
9210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Cancels the alarm associated with DCAC.
9220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
9230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param DataConnectionAc on which the alarm should be stopped.
9240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
9250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void cancelReconnectAlarm(DataConnectionAc dcac) {
9260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (dcac == null) return;
9270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        PendingIntent intent = dcac.getReconnectIntentSync();
9290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (intent != null) {
9310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                AlarmManager am =
9320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
9330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                am.cancel(intent);
9340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                dcac.setReconnectIntentSync(null);
9350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
9390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param types comma delimited list of APN types
9400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return array of APN types
9410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
9420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private String[] parseTypes(String types) {
9430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String[] result;
9440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If unset, set to DEFAULT.
9450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (types == null || types.equals("")) {
9460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            result = new String[1];
9470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            result[0] = PhoneConstants.APN_TYPE_ALL;
9480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
9490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            result = types.split(",");
9500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return result;
9520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private ArrayList<ApnSetting> createApnList(Cursor cursor) {
9550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ArrayList<ApnSetting> result = new ArrayList<ApnSetting>();
9560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (cursor.moveToFirst()) {
9570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            do {
9580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                String[] types = parseTypes(
9590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.TYPE)));
9600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ApnSetting apn = new ApnSetting(
9610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID)),
9620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NUMERIC)),
9630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NAME)),
9640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN)),
9650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        NetworkUtils.trimV4AddrZeros(
9660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                cursor.getString(
9670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY))),
9680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PORT)),
9690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        NetworkUtils.trimV4AddrZeros(
9700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                cursor.getString(
9710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC))),
9720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        NetworkUtils.trimV4AddrZeros(
9730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                cursor.getString(
9740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY))),
9750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPORT)),
9760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)),
9770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)),
9780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.AUTH_TYPE)),
9790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        types,
9800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROTOCOL)),
9810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        cursor.getString(cursor.getColumnIndexOrThrow(
9820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                Telephony.Carriers.ROAMING_PROTOCOL)),
9830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        cursor.getInt(cursor.getColumnIndexOrThrow(
9840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                Telephony.Carriers.CARRIER_ENABLED)) == 1,
9850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.BEARER)));
9860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                result.add(apn);
9870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } while (cursor.moveToNext());
9880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("createApnList: X result=" + result);
9900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return result;
9910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean dataConnectionNotInUse(DataConnectionAc dcac) {
994ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville        if (DBG) log("dataConnectionNotInUse: check if dcac is inuse dc=" + dcac.dataConnection);
9950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (ApnContext apnContext : mApnContexts.values()) {
996ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville            if (apnContext.getDataConnectionAc() == dcac) {
997ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville                if (DBG) log("dataConnectionNotInUse: in use by apnContext=" + apnContext);
998ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville                return false;
999ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville            }
1000ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville        }
1001ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville        // TODO: Fix retry handling so free DataConnections have empty apnlists.
1002ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville        // Probably move retry handling into DataConnections and reduce complexity
1003ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville        // of DCT.
1004ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville        for (ApnContext apnContext : dcac.getApnListSync()) {
1005ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville            if (DBG) {
1006ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville                log("dataConnectionNotInUse: removing apnContext=" + apnContext);
1007ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville            }
1008ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville            dcac.removeApnContextSync(apnContext);
10090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1010ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville        if (DBG) log("dataConnectionNotInUse: not in use return true");
10110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return true;
10120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private GsmDataConnection findFreeDataConnection() {
10150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
10160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dcac.isInactiveSync() && dataConnectionNotInUse(dcac)) {
10170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                DataConnection dc = dcac.dataConnection;
10180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) {
10190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("findFreeDataConnection: found free GsmDataConnection=" +
10200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        " dcac=" + dcac + " dc=" + dc);
10210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
10220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return (GsmDataConnection) dc;
10230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
10240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        log("findFreeDataConnection: NO free GsmDataConnection");
10260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return null;
10270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected GsmDataConnection findReadyDataConnection(ApnSetting apn) {
10300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apn == null) {
10310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return null;
10320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
10340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("findReadyDataConnection: apn string <" + apn + ">" +
10350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " dcacs.size=" + mDataConnectionAsyncChannels.size());
10360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
10380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ApnSetting apnSetting = dcac.getApnSettingSync();
10390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
10400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("findReadyDataConnection: dc apn string <" +
10410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                         (apnSetting != null ? (apnSetting.toString()) : "null") + ">");
10420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
10430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if ((apnSetting != null) && TextUtils.equals(apnSetting.toString(), apn.toString())) {
10440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                DataConnection dc = dcac.dataConnection;
10450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) {
10460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("findReadyDataConnection: found ready GsmDataConnection=" +
10470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        " dcac=" + dcac + " dc=" + dc);
10480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
10490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return (GsmDataConnection) dc;
10500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
10510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return null;
10530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean setupData(ApnContext apnContext) {
10570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("setupData: apnContext=" + apnContext);
10580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnSetting apn;
10590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        GsmDataConnection dc;
10600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int profileId = getApnProfileID(apnContext.getApnType());
10620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        apn = apnContext.getNextWaitingApn();
10630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apn == null) {
10640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("setupData: return for no apn found!");
10650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
10660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        dc = (GsmDataConnection) checkForConnectionForApnContext(apnContext);
10700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (dc == null) {
10720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            dc = findReadyDataConnection(apn);
10730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dc == null) {
10750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("setupData: No ready GsmDataConnection found!");
10760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // TODO: When allocating you are mapping type to id. If more than 1 free,
10770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // then could findFreeDataConnection get the wrong one??
10780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                dc = findFreeDataConnection();
10790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
10800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dc == null) {
10820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                dc = createDataConnection();
10830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
10840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dc == null) {
10860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("setupData: No free GsmDataConnection found!");
10870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return false;
10880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
10890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
10900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apn = mDataConnectionAsyncChannels.get(dc.getDataConnectionId()).getApnSettingSync();
10910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        DataConnectionAc dcac = mDataConnectionAsyncChannels.get(dc.getDataConnectionId());
10940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        dc.setProfileId( profileId );  //  assumed no connection sharing on profiled types
10950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int refCount = dcac.getRefCountSync();
10970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("setupData: init dc and apnContext refCount=" + refCount);
10980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // configure retry count if no other Apn is using the same connection.
11000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (refCount == 0) {
11010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            configureRetry(dc, apn.canHandleType(PhoneConstants.APN_TYPE_DEFAULT),
11020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.getRetryCount());
11030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        apnContext.setDataConnectionAc(dcac);
11050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        apnContext.setDataConnection(dc);
11060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        apnContext.setApnSetting(apn);
11080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        apnContext.setState(DctConstants.State.INITING);
11090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
11100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If reconnect alarm is active on this DataConnection, wait for the alarm being
11110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // fired so that we don't disruppt data retry pattern engaged.
11120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext.getDataConnectionAc().getReconnectIntentSync() != null) {
11130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("setupData: data reconnection pending");
11140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apnContext.setState(DctConstants.State.FAILED);
11150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
11160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
11170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Message msg = obtainMessage();
11200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        msg.what = DctConstants.EVENT_DATA_SETUP_COMPLETE;
11210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        msg.obj = apnContext;
11220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        dc.bringUp(msg, apn);
11230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("setupData: initing!");
11250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return true;
11260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Handles changes to the APN database.
11300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void onApnChanged() {
11320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        DctConstants.State overallState = getOverallState();
11330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean isDisconnected = (overallState == DctConstants.State.IDLE ||
11340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                overallState == DctConstants.State.FAILED);
11350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mPhone instanceof GSMPhone) {
11370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // The "current" may no longer be valid.  MMS depends on this to send properly. TBD
11380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ((GSMPhone)mPhone).updateCurrentCarrierInProvider();
11390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // TODO: It'd be nice to only do this if the changed entrie(s)
11420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // match the current operator.
11430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onApnChanged: createAllApnList and cleanUpAllConnections");
11440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        createAllApnList();
11450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cleanUpAllConnections(!isDisconnected, Phone.REASON_APN_CHANGED);
11460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (isDisconnected) {
11470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setupDataOnReadyApns(Phone.REASON_APN_CHANGED);
11480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param cid Connection id provided from RIL.
11530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return DataConnectionAc associated with specified cid.
11540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private DataConnectionAc findDataConnectionAcByCid(int cid) {
11560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
11570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dcac.getCidSync() == cid) {
11580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return dcac;
11590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
11600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return null;
11620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param dcacs Collection of DataConnectionAc reported from RIL.
11660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return List of ApnContext which is connected, but is not present in
11670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *         data connection list reported from RIL.
11680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private List<ApnContext> findApnContextToClean(Collection<DataConnectionAc> dcacs) {
11700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (dcacs == null) return null;
11710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("findApnContextToClean(ar): E dcacs=" + dcacs);
11730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ArrayList<ApnContext> list = new ArrayList<ApnContext>();
11750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (ApnContext apnContext : mApnContexts.values()) {
11760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (apnContext.getState() == DctConstants.State.CONNECTED) {
11770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                boolean found = false;
11780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                for (DataConnectionAc dcac : dcacs) {
11790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (dcac == apnContext.getDataConnectionAc()) {
11800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // ApnContext holds the ref to dcac present in data call list.
11810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        found = true;
11820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        break;
11830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
11840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
11850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!found) {
11860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // ApnContext does not have dcac reported in data call list.
11870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Fetch all the ApnContexts that map to this dcac which are in
11880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // INITING state too.
11890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) log("findApnContextToClean(ar): Connected apn not found in the list (" +
11900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                 apnContext.toString() + ")");
11910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (apnContext.getDataConnectionAc() != null) {
11920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        list.addAll(apnContext.getDataConnectionAc().getApnListSync());
11930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
11940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        list.add(apnContext);
11950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
11960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
11970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
11980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("findApnContextToClean(ar): X list=" + list);
12000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return list;
12010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param ar is the result of RIL_REQUEST_DATA_CALL_LIST
12050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * or RIL_UNSOL_DATA_CALL_LIST_CHANGED
12060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
12070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void onDataStateChanged (AsyncResult ar) {
12080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ArrayList<DataCallState> dataCallStates;
12090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onDataStateChanged(ar): E");
12110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        dataCallStates = (ArrayList<DataCallState>)(ar.result);
12120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ar.exception != null) {
12140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // This is probably "radio not available" or something
12150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // of that sort. If so, the whole connection is going
12160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // to come down soon anyway
12170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("onDataStateChanged(ar): exception; likely radio not available, ignore");
12180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
12190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
12200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onDataStateChanged(ar): DataCallState size=" + dataCallStates.size());
12210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1222b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla        boolean isAnyDataCallDormant = false;
1223b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla        boolean isAnyDataCallActive = false;
1224b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla
12250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Create a hash map to store the dataCallState of each DataConnectionAc
12260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        HashMap<DataCallState, DataConnectionAc> dataCallStateToDcac;
12270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        dataCallStateToDcac = new HashMap<DataCallState, DataConnectionAc>();
12280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (DataCallState dataCallState : dataCallStates) {
12290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            DataConnectionAc dcac = findDataConnectionAcByCid(dataCallState.cid);
12300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dcac != null) dataCallStateToDcac.put(dataCallState, dcac);
12320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
12330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // A list of apns to cleanup, those that aren't in the list we know we have to cleanup
12350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        List<ApnContext> apnsToCleanup = findApnContextToClean(dataCallStateToDcac.values());
12360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Find which connections have changed state and send a notification or cleanup
12380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (DataCallState newState : dataCallStates) {
12390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            DataConnectionAc dcac = dataCallStateToDcac.get(newState);
12400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dcac == null) {
12420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                loge("onDataStateChanged(ar): No associated DataConnection ignore");
12430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                continue;
12440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
12450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1246b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            if (newState.active == DATA_CONNECTION_ACTIVE_PH_LINK_UP) isAnyDataCallActive = true;
1247b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            if (newState.active == DATA_CONNECTION_ACTIVE_PH_LINK_DOWN) isAnyDataCallDormant = true;
1248b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla
12490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // The list of apn's associated with this DataConnection
12500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Collection<ApnContext> apns = dcac.getApnListSync();
12510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Find which ApnContexts of this DC are in the "Connected/Connecting" state.
12530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ArrayList<ApnContext> connectedApns = new ArrayList<ApnContext>();
12540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (ApnContext apnContext : apns) {
12550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (apnContext.getState() == DctConstants.State.CONNECTED ||
12560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                       apnContext.getState() == DctConstants.State.CONNECTING ||
12570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                       apnContext.getState() == DctConstants.State.INITING) {
12580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    connectedApns.add(apnContext);
12590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
12600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
12610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (connectedApns.size() == 0) {
12620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("onDataStateChanged(ar): no connected apns");
12630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
12640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Determine if the connection/apnContext should be cleaned up
12650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // or just a notification should be sent out.
12660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("onDataStateChanged(ar): Found ConnId=" + newState.cid
12670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        + " newState=" + newState.toString());
12680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (newState.active == 0) {
12690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) {
12700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("onDataStateChanged(ar): inactive, cleanup apns=" + connectedApns);
12710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
12720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnsToCleanup.addAll(connectedApns);
12730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
12740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Its active so update the DataConnections link properties
12750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    UpdateLinkPropertyResult result =
12760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        dcac.updateLinkPropertiesDataCallStateSync(newState);
12770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (result.oldLp.equals(result.newLp)) {
12780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("onDataStateChanged(ar): no change");
12790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
12800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (result.oldLp.isIdenticalInterfaceName(result.newLp)) {
12810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (! result.oldLp.isIdenticalDnses(result.newLp) ||
12820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    ! result.oldLp.isIdenticalRoutes(result.newLp) ||
12830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    ! result.oldLp.isIdenticalHttpProxy(result.newLp) ||
12840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    ! result.oldLp.isIdenticalAddresses(result.newLp)) {
12850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                // If the same address type was removed and added we need to cleanup
12860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                CompareResult<LinkAddress> car =
12870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    result.oldLp.compareAddresses(result.newLp);
12880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (DBG) {
12890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    log("onDataStateChanged: oldLp=" + result.oldLp +
12900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                            " newLp=" + result.newLp + " car=" + car);
12910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                }
12920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                boolean needToClean = false;
12930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                for (LinkAddress added : car.added) {
12940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    for (LinkAddress removed : car.removed) {
12950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        if (NetworkUtils.addressTypeMatches(removed.getAddress(),
12960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                                added.getAddress())) {
12970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                            needToClean = true;
12980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                            break;
12990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        }
13000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    }
13010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                }
13020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (needToClean) {
13030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    if (DBG) {
13040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        log("onDataStateChanged(ar): addr change, cleanup apns=" +
13050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                                connectedApns + " oldLp=" + result.oldLp +
13060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                                " newLp=" + result.newLp);
13070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    }
13080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    apnsToCleanup.addAll(connectedApns);
13090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                } else {
13100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    if (DBG) log("onDataStateChanged(ar): simple change");
13110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    for (ApnContext apnContext : connectedApns) {
13120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                         mPhone.notifyDataConnection(
13130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                                 PhoneConstants.REASON_LINK_PROPERTIES_CHANGED,
13140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                                 apnContext.getApnType());
13150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    }
13160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                }
13170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            } else {
13180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (DBG) {
13190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    log("onDataStateChanged(ar): no changes");
13200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                }
13210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
13220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        } else {
13230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (DBG) {
13240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                log("onDataStateChanged(ar): interface change, cleanup apns="
13250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        + connectedApns);
13260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
13270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            apnsToCleanup.addAll(connectedApns);
13280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
13290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
13300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
13310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
13320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
13330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1334b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla        if (isAnyDataCallDormant && !isAnyDataCallActive) {
1335b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            // There is no way to indicate link activity per APN right now. So
1336b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            // Link Activity will be considered dormant only when all data calls
1337b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            // are dormant.
1338b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            // If a single data call is in dormant state and none of the data
1339b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            // calls are active broadcast overall link state as dormant.
1340b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            mActivity = DctConstants.Activity.DORMANT;
1341b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            if (DBG) {
1342b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla                log("onDataStateChanged: Data Activity updated to DORMANT. stopNetStatePoll");
1343b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            }
1344b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            stopNetStatPoll();
1345b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla        } else {
1346b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            mActivity = DctConstants.Activity.NONE;
1347b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            if (DBG) {
1348b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla                log("onDataStateChanged: Data Activity updated to NONE. " +
1349b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla                         "isAnyDataCallActive = " + isAnyDataCallActive +
1350b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla                         " isAnyDataCallDormant = " + isAnyDataCallDormant);
1351b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            }
1352b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            if (isAnyDataCallActive) startNetStatPoll();
1353b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla        }
1354b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla        mPhone.notifyDataActivity();
1355b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla
13560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnsToCleanup.size() != 0) {
13570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Add an event log when the network drops PDP
13580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int cid = getCellLocationId();
13590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP, cid,
13600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                TelephonyManager.getDefault().getNetworkType());
13610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
13620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Cleanup those dropped connections
13640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onDataStateChange(ar): apnsToCleanup=" + apnsToCleanup);
13650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (ApnContext apnContext : apnsToCleanup) {
13660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cleanUpConnection(true, apnContext);
13670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
13680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onDataStateChanged(ar): X");
13700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
13710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void notifyDefaultData(ApnContext apnContext) {
13730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
13740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("notifyDefaultData: type=" + apnContext.getApnType()
13750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                + ", reason:" + apnContext.getReason());
13760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
13770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        apnContext.setState(DctConstants.State.CONNECTED);
13780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // setState(DctConstants.State.CONNECTED);
13790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
13800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        startNetStatPoll();
13810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
13820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // reset reconnect timer
13830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        apnContext.setRetryCount(0);
13840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
13850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // TODO: For multiple Active APNs not exactly sure how to do this.
13870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void gotoIdleAndNotifyDataConnection(String reason) {
13880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("gotoIdleAndNotifyDataConnection: reason=" + reason);
13890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        notifyDataConnection(reason);
13900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mActiveApn = null;
13910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
13920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
13940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void restartRadio() {
13950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("restartRadio: ************TURN OFF RADIO**************");
13960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cleanUpAllConnections(true, Phone.REASON_RADIO_TURNED_OFF);
13970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.getServiceStateTracker().powerOffRadioSafely(this);
13980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        /* Note: no need to call setRadioPower(true).  Assuming the desired
13990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * radio power state is still ON (as tracked by ServiceStateTracker),
14000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * ServiceStateTracker will call setRadioPower when it receives the
14010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * RADIO_STATE_CHANGED notification for the power off.  And if the
14020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * desired power state has changed in the interim, we don't want to
14030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * override it with an unconditional power on.
14040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         */
14050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int reset = Integer.parseInt(SystemProperties.get("net.ppp.reset-by-timeout", "0"));
14070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SystemProperties.set("net.ppp.reset-by-timeout", String.valueOf(reset+1));
14080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
14110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Returns true if the last fail cause is something that
14120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * seems like it deserves an error notification.
14130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Transient errors are ignored
14140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
14150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean shouldPostNotification(GsmDataConnection.FailCause  cause) {
14160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return (cause != GsmDataConnection.FailCause.UNKNOWN);
14170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
14200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Return true if data connection need to be setup after disconnected due to
14210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * reason.
14220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
14230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param reason the reason why data is disconnected
14240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if try setup data connection is need for this reason
14250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
14260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean retryAfterDisconnected(String reason) {
14270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean retry = true;
14280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) ) {
14300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            retry = false;
14310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
14320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return retry;
14330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void reconnectAfterFail(FailCause lastFailCauseCode,
14360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    ApnContext apnContext, int retryOverride) {
14370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext == null) {
14380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            loge("reconnectAfterFail: apnContext == null, impossible");
14390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
14400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
14410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
14420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("reconnectAfterFail: lastFailCause=" + lastFailCauseCode +
14430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " retryOverride=" + retryOverride + " apnContext=" + apnContext);
14440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
14450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if ((apnContext.getState() == DctConstants.State.FAILED) &&
14460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            (apnContext.getDataConnection() != null)) {
14470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!apnContext.getDataConnection().isRetryNeeded()) {
14480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)) {
14490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType());
14500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return;
14510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
14520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (mReregisterOnReconnectFailure) {
14530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // We've re-registerd once now just retry forever.
14540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.getDataConnection().retryForeverUsingLastTimeout();
14550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
14560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Try to Re-register to the network.
14570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) log("reconnectAfterFail: activate failed, Reregistering to network");
14580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mReregisterOnReconnectFailure = true;
14590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mPhone.getServiceStateTracker().reRegisterNetwork(null);
14600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.setRetryCount(0);
14610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return;
14620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
14630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
14640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // If retry needs to be backed off for specific case (determined by RIL/Modem)
14660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // use the specified timer instead of pre-configured retry pattern.
14670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int nextReconnectDelay = retryOverride;
14680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (nextReconnectDelay < 0) {
14690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                nextReconnectDelay = apnContext.getDataConnection().getRetryTimer();
14700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext.getDataConnection().increaseRetryCount();
14710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) {
14720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("reconnectAfterFail: increaseRetryCount=" +
14730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            apnContext.getDataConnection().getRetryCount() +
14740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            " nextReconnectDelay=" + nextReconnectDelay);
14750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
14760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
14770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            startAlarmForReconnect(nextReconnectDelay, apnContext);
14780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!shouldPostNotification(lastFailCauseCode)) {
14800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) {
14810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("reconnectAfterFail: NOT Posting GPRS Unavailable notification "
14820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                + "-- likely transient error");
14830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
14840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
14850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                notifyNoData(lastFailCauseCode, apnContext);
14860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
14870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
14880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void startAlarmForReconnect(int delay, ApnContext apnContext) {
14910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        DataConnectionAc dcac = apnContext.getDataConnectionAc();
14930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if ((dcac == null) || (dcac.dataConnection == null)) {
14950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // should not happen, but just in case.
14960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            loge("startAlarmForReconnect: null dcac or dc.");
14970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
14980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
14990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        AlarmManager am =
15010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
15020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Intent intent = new Intent(INTENT_RECONNECT_ALARM + '.' +
15040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                   dcac.dataConnection.getDataConnectionId());
15050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String reason = apnContext.getReason();
15060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, reason);
15070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int connectionId = dcac.dataConnection.getDataConnectionId();
15080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, connectionId);
15090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // TODO: Until a real fix is created, which probably entails pushing
15110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // retires into the DC itself, this fix gets the retry count and
15120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // puts it in the reconnect alarm. When the reconnect alarm fires
15130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // onActionIntentReconnectAlarm is called which will use the value saved
15140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // here and save it in the ApnContext and send the EVENT_CONNECT message
15150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // which invokes setupData. Then setupData will use the value in the ApnContext
15160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // and to tell the DC to set the retry count in the retry manager.
15170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int retryCount = dcac.dataConnection.getRetryCount();
15180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_RETRY_COUNT, retryCount);
15190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
15210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("startAlarmForReconnect: next attempt in " + (delay / 1000) + "s" +
15220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " reason='" + reason + "' connectionId=" + connectionId +
15230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " retryCount=" + retryCount);
15240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        PendingIntent alarmIntent = PendingIntent.getBroadcast (mPhone.getContext(), 0,
15270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        intent, PendingIntent.FLAG_UPDATE_CURRENT);
15280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        dcac.setReconnectIntentSync(alarmIntent);
15290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
15300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                SystemClock.elapsedRealtime() + delay, alarmIntent);
15310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void notifyNoData(GsmDataConnection.FailCause lastFailCauseCode,
15350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                              ApnContext apnContext) {
15360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log( "notifyNoData: type=" + apnContext.getApnType());
15370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        apnContext.setState(DctConstants.State.FAILED);
15380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (lastFailCauseCode.isPermanentFail()
15390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            && (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT))) {
15400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
15410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void onRecordsLoaded() {
15450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onRecordsLoaded: createAllApnList");
15460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        createAllApnList();
15470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mPhone.mCM.getRadioState().isOn()) {
15480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("onRecordsLoaded: notifying data availability");
15490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notifyOffApnsOfAvailability(Phone.REASON_SIM_LOADED);
15500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        setupDataOnReadyApns(Phone.REASON_SIM_LOADED);
15520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
15550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onSetDependencyMet(String apnType, boolean met) {
15560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // don't allow users to tweak hipri to work around default dependency not met
15570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (PhoneConstants.APN_TYPE_HIPRI.equals(apnType)) return;
15580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnContext apnContext = mApnContexts.get(apnType);
15600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext == null) {
15610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            loge("onSetDependencyMet: ApnContext not found in onSetDependencyMet(" +
15620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnType + ", " + met + ")");
15630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
15640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        applyNewState(apnContext, apnContext.isEnabled(), met);
15660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (PhoneConstants.APN_TYPE_DEFAULT.equals(apnType)) {
15670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // tie actions on default to similar actions on HIPRI regarding dependencyMet
15680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apnContext = mApnContexts.get(PhoneConstants.APN_TYPE_HIPRI);
15690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (apnContext != null) applyNewState(apnContext, apnContext.isEnabled(), met);
15700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void applyNewState(ApnContext apnContext, boolean enabled, boolean met) {
15740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean cleanup = false;
15750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean trySetup = false;
15760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
15770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("applyNewState(" + apnContext.getApnType() + ", " + enabled +
15780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    "(" + apnContext.isEnabled() + "), " + met + "(" +
15790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.getDependencyMet() +"))");
15800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext.isReady()) {
15820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (enabled && met) return;
15830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!enabled) {
15840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext.setReason(Phone.REASON_DATA_DISABLED);
15850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
15860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_UNMET);
15870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
15880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cleanup = true;
15890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
15900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (enabled && met) {
15910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (apnContext.isEnabled()) {
15920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_MET);
15930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
15940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.setReason(Phone.REASON_DATA_ENABLED);
15950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
15960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (apnContext.getState() == DctConstants.State.FAILED) {
15970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.setState(DctConstants.State.IDLE);
15980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
15990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                trySetup = true;
16000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
16010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        apnContext.setEnabled(enabled);
16030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        apnContext.setDependencyMet(met);
16040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (cleanup) cleanUpConnection(true, apnContext);
16050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (trySetup) trySetupData(apnContext);
16060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private DataConnection checkForConnectionForApnContext(ApnContext apnContext) {
16090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Loop through all apnContexts looking for one with a conn that satisfies this apnType
16100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String apnType = apnContext.getApnType();
16110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnSetting dunSetting = null;
16120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (PhoneConstants.APN_TYPE_DUN.equals(apnType)) {
16140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            dunSetting = fetchDunApn();
16150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        DataConnection potential = null;
16180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (ApnContext c : mApnContexts.values()) {
16190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            DataConnection conn = c.getDataConnection();
16200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (conn != null) {
16210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ApnSetting apnSetting = c.getApnSetting();
16220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (dunSetting != null) {
16230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (dunSetting.equals(apnSetting)) {
16240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        switch (c.getState()) {
16250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            case CONNECTED:
16260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (DBG) {
16270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    log("checkForConnectionForApnContext: apnContext=" +
16280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                            apnContext + " found conn=" + conn);
16290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                }
16300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                return conn;
16310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            case CONNECTING:
16320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                potential = conn;
16330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
16340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
16350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (apnSetting != null && apnSetting.canHandleType(apnType)) {
16360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    switch (c.getState()) {
16370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        case CONNECTED:
16380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (DBG) {
16390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                log("checkForConnectionForApnContext: apnContext=" + apnContext +
16400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        " found conn=" + conn);
16410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
16420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            return conn;
16430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        case CONNECTING:
16440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            potential = conn;
16450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
16460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
16470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
16480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (potential != null) {
16500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
16510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("checkForConnectionForApnContext: apnContext=" + apnContext +
16520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " found conn=" + potential);
16530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
16540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return potential;
16550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("checkForConnectionForApnContext: apnContext=" + apnContext + " NO conn");
16580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return null;
16590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
16620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onEnableApn(int apnId, int enabled) {
16630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnContext apnContext = mApnContexts.get(apnIdToType(apnId));
16640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext == null) {
16650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            loge("onEnableApn(" + apnId + ", " + enabled + "): NO ApnContext");
16660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
16670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // TODO change our retry manager to use the appropriate numbers for the new APN
16690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onEnableApn: apnContext=" + apnContext + " call applyNewState");
16700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        applyNewState(apnContext, enabled == DctConstants.ENABLED, apnContext.getDependencyMet());
16710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
16740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // TODO: We shouldnt need this.
16750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected boolean onTrySetupData(String reason) {
16760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onTrySetupData: reason=" + reason);
16770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        setupDataOnReadyApns(reason);
16780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return true;
16790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected boolean onTrySetupData(ApnContext apnContext) {
16820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onTrySetupData: apnContext=" + apnContext);
16830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return trySetupData(apnContext);
16840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
16870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onRoamingOff() {
16880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onRoamingOff");
16890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mUserDataEnabled == false) return;
16910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (getDataOnRoamingEnabled() == false) {
16930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_OFF);
16940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setupDataOnReadyApns(Phone.REASON_ROAMING_OFF);
16950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
16960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notifyDataConnection(Phone.REASON_ROAMING_OFF);
16970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
17010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onRoamingOn() {
17020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mUserDataEnabled == false) return;
17030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (getDataOnRoamingEnabled()) {
17050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("onRoamingOn: setup data on roaming");
17060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setupDataOnReadyApns(Phone.REASON_ROAMING_ON);
17070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notifyDataConnection(Phone.REASON_ROAMING_ON);
17080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
17090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("onRoamingOn: Tear down data connection on roaming.");
17100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cleanUpAllConnections(true, Phone.REASON_ROAMING_ON);
17110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
17120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
17140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
17160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onRadioAvailable() {
17170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onRadioAvailable");
17180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mPhone.getSimulatedRadioControl() != null) {
17190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Assume data is connected on the simulator
17200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // FIXME  this can be improved
17210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // setState(DctConstants.State.CONNECTED);
17220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notifyDataConnection(null);
17230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("onRadioAvailable: We're on the simulator; assuming data is connected");
17250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1727e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        IccRecords r = mIccRecords.get();
1728e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        if (r != null && r.getRecordsLoaded()) {
17290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notifyOffApnsOfAvailability(null);
17300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (getOverallState() != DctConstants.State.IDLE) {
17330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cleanUpConnection(true, null);
17340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
17360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
17380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onRadioOffOrNotAvailable() {
17390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Make sure our reconnect delay starts at the initial value
17400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // next time the radio comes on
17410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        resetAllRetryCounts();
17430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mReregisterOnReconnectFailure = false;
17440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mPhone.getSimulatedRadioControl() != null) {
17460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Assume data is connected on the simulator
17470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // FIXME  this can be improved
17480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("We're on the simulator; assuming radio off is meaningless");
17490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
17500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("onRadioOffOrNotAvailable: is off and clean up all connections");
17510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cleanUpAllConnections(false, Phone.REASON_RADIO_TURNED_OFF);
17520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        notifyOffApnsOfAvailability(null);
17540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
17550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
17570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onDataSetupComplete(AsyncResult ar) {
17580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        DataConnection.FailCause cause = DataConnection.FailCause.UNKNOWN;
17600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean handleError = false;
17610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnContext apnContext = null;
17620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if(ar.userObj instanceof ApnContext){
17640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apnContext = (ApnContext)ar.userObj;
17650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
17660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new RuntimeException("onDataSetupComplete: No apnContext");
17670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (isDataSetupCompleteOk(ar)) {
17700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            DataConnectionAc dcac = apnContext.getDataConnectionAc();
17710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (RADIO_TESTS) {
17730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Note: To change radio.test.onDSC.null.dcac from command line you need to
17740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // adb root and adb remount and from the command line you can only change the
17750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // value to 1 once. To change it a second time you can reboot or execute
17760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // adb shell stop and then adb shell start. The command line to set the value is:
17770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                //   adb shell sqlite3 /data/data/com.android.providers.settings/databases/settings.db "insert into system (name,value) values ('radio.test.onDSC.null.dcac', '1');"
17780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ContentResolver cr = mPhone.getContext().getContentResolver();
17790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                String radioTestProperty = "radio.test.onDSC.null.dcac";
17800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (Settings.System.getInt(cr, radioTestProperty, 0) == 1) {
17810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("onDataSetupComplete: " + radioTestProperty +
17820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            " is true, set dcac to null and reset property to false");
17830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    dcac = null;
17840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    Settings.System.putInt(cr, radioTestProperty, 0);
17850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("onDataSetupComplete: " + radioTestProperty + "=" +
17860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            Settings.System.getInt(mPhone.getContext().getContentResolver(),
17870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    radioTestProperty, -1));
17880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
17890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
17900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dcac == null) {
17910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("onDataSetupComplete: no connection to DC, handle as error");
17920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cause = DataConnection.FailCause.CONNECTION_TO_DATACONNECTIONAC_BROKEN;
17930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                handleError = true;
17940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
17950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                DataConnection dc = apnContext.getDataConnection();
17960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ApnSetting apn = apnContext.getApnSetting();
17970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) {
17980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("onDataSetupComplete: success apn=" + (apn == null ? "unknown" : apn.apn));
17990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
18000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (apn != null && apn.proxy != null && apn.proxy.length() != 0) {
18010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    try {
18020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        String port = apn.port;
18030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (TextUtils.isEmpty(port)) port = "8080";
18040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        ProxyProperties proxy = new ProxyProperties(apn.proxy,
18050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                Integer.parseInt(port), null);
18060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        dcac.setLinkPropertiesHttpProxySync(proxy);
18070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } catch (NumberFormatException e) {
18080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        loge("onDataSetupComplete: NumberFormatException making ProxyProperties (" +
18090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                apn.port + "): " + e);
18100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
18110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
18120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // everything is setup
18140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if(TextUtils.equals(apnContext.getApnType(),PhoneConstants.APN_TYPE_DEFAULT)) {
18150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    SystemProperties.set("gsm.defaultpdpcontext.active", "true");
18160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (canSetPreferApn && mPreferredApn == null) {
18170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("onDataSetupComplete: PREFERED APN is null");
18180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mPreferredApn = apn;
18190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (mPreferredApn != null) {
18200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            setPreferredApn(mPreferredApn.id);
18210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
18220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
18230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
18240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    SystemProperties.set("gsm.defaultpdpcontext.active", "false");
18250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
18260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                notifyDefaultData(apnContext);
18270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
18280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
18290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cause = (DataConnection.FailCause) (ar.result);
18300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
18310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ApnSetting apn = apnContext.getApnSetting();
18320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log(String.format("onDataSetupComplete: error apn=%s cause=%s",
18330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        (apn == null ? "unknown" : apn.apn), cause));
18340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
18350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (cause.isEventLoggable()) {
18360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Log this failure to the Event Logs.
18370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                int cid = getCellLocationId();
18380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                EventLog.writeEvent(EventLogTags.PDP_SETUP_FAIL,
18390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        cause.ordinal(), cid, TelephonyManager.getDefault().getNetworkType());
18400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
18410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Count permanent failures and remove the APN we just tried
18430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (cause.isPermanentFail()) apnContext.decWaitingApnsPermFailCount();
18440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apnContext.removeWaitingApn(apnContext.getApnSetting());
18460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
18470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log(String.format("onDataSetupComplete: WaitingApns.size=%d" +
18480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        " WaitingApnsPermFailureCountDown=%d",
18490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        apnContext.getWaitingApns().size(),
18500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        apnContext.getWaitingApnsPermFailCount()));
18510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
18520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            handleError = true;
18530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
18540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (handleError) {
18560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // See if there are more APN's to try
18570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (apnContext.getWaitingApns().isEmpty()) {
18580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (apnContext.getWaitingApnsPermFailCount() == 0) {
18590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) {
18600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("onDataSetupComplete: All APN's had permanent failures, stop retrying");
18610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
18620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.setState(DctConstants.State.FAILED);
18630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType());
18640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.setDataConnection(null);
18660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.setDataConnectionAc(null);
18670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
18680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) log("onDataSetupComplete: Not all permanent failures, retry");
18690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // check to see if retry should be overridden for this failure.
18700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int retryOverride = -1;
18710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (ar.exception instanceof DataConnection.CallSetupException) {
18720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        retryOverride =
18730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            ((DataConnection.CallSetupException)ar.exception).getRetryOverride();
18740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
18750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (retryOverride == RILConstants.MAX_INT) {
18760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("No retry is suggested.");
18770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
18780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        startDelayedRetry(cause, apnContext, retryOverride);
18790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
18800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
18810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
18820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("onDataSetupComplete: Try next APN");
18830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext.setState(DctConstants.State.SCANNING);
18840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Wait a bit before trying the next APN, so that
18850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // we're not tying up the RIL command channel
18860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                startAlarmForReconnect(APN_DELAY_MILLIS, apnContext);
18870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
18880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
18890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
18900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
18920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Called when EVENT_DISCONNECT_DONE is received.
18930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
18940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
18950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onDisconnectDone(int connId, AsyncResult ar) {
18960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnContext apnContext = null;
18970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ar.userObj instanceof ApnContext) {
18990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apnContext = (ApnContext) ar.userObj;
19000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
1901ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville            loge("onDisconnectDone: Invalid ar in onDisconnectDone, ignore");
19020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
19030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
19040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1905ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville        if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE apnContext=" + apnContext);
19060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        apnContext.setState(DctConstants.State.IDLE);
19070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
19080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
19090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
19100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // if all data connection are gone, check whether Airplane mode request was
19110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // pending.
19120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (isDisconnected()) {
19130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (mPhone.getServiceStateTracker().processPendingRadioPowerOffAfterDataOff()) {
19140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Radio will be turned off. No need to retry data setup
19150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext.setApnSetting(null);
19160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext.setDataConnection(null);
19170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext.setDataConnectionAc(null);
19180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
19190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
19200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
19210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
19220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If APN is still enabled, try to bring it back up automatically
19230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext.isReady() && retryAfterDisconnected(apnContext.getReason())) {
19240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            SystemProperties.set("gsm.defaultpdpcontext.active", "false");  // TODO - what the heck?  This shoudld go
19250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Wait a bit before trying the next APN, so that
19260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // we're not tying up the RIL command channel.
19270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // This also helps in any external dependency to turn off the context.
19280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            startAlarmForReconnect(APN_DELAY_MILLIS, apnContext);
19290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
19300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apnContext.setApnSetting(null);
19310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apnContext.setDataConnection(null);
19320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apnContext.setDataConnectionAc(null);
19330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
19340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
19350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
19360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onPollPdp() {
19370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (getOverallState() == DctConstants.State.CONNECTED) {
19380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // only poll when connected
19390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mPhone.mCM.getDataCallList(this.obtainMessage(DctConstants.EVENT_DATA_STATE_CHANGED));
19400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            sendMessageDelayed(obtainMessage(DctConstants.EVENT_POLL_PDP), POLL_PDP_MILLIS);
19410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
19420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
19430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
19440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
19450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onVoiceCallStarted() {
19460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onVoiceCallStarted");
19470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (isConnected() && ! mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
19480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("onVoiceCallStarted stop polling");
19490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            stopNetStatPoll();
19500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            stopDataStallAlarm();
19510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
19520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
19530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
19540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
19550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
19560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onVoiceCallEnded() {
19570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onVoiceCallEnded");
19580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (isConnected()) {
19590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
19600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                startNetStatPoll();
19610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
19620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
19630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
19640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // clean slate after call end.
19650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                resetPollStats();
19660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
19670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
19680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // reset reconnect timer
19690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        setupDataOnReadyApns(Phone.REASON_VOICE_CALL_ENDED);
19700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
19710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
19720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
19730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onCleanUpConnection(boolean tearDown, int apnId, String reason) {
19740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onCleanUpConnection");
19750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnContext apnContext = mApnContexts.get(apnIdToType(apnId));
19760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext != null) {
19770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apnContext.setReason(reason);
19780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cleanUpConnection(tearDown, apnContext);
19790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
19800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
19810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
19820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected boolean isConnected() {
19830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (ApnContext apnContext : mApnContexts.values()) {
19840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (apnContext.getState() ==DctConstants.State.CONNECTED) {
19850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // At least one context is connected, return true
19860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return true;
19870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
19880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
19890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // There are not any contexts connected, return false
19900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return false;
19910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
19920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
19930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
19940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean isDisconnected() {
19950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (ApnContext apnContext : mApnContexts.values()) {
19960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!apnContext.isDisconnected()) {
19970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // At least one context was not disconnected return false
19980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return false;
19990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
20000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
20010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // All contexts were disconnected so return true
20020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return true;
20030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
20040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
20060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void notifyDataConnection(String reason) {
20070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("notifyDataConnection: reason=" + reason);
20080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (ApnContext apnContext : mApnContexts.values()) {
20090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (apnContext.isReady()) {
20100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("notifyDataConnection: type:"+apnContext.getApnType());
20110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
20120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        apnContext.getApnType());
20130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
20140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
20150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        notifyOffApnsOfAvailability(reason);
20160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
20170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
20190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Based on the sim operator numeric, create a list for all possible
20200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Data Connections and setup the preferredApn.
20210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
20220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void createAllApnList() {
20230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mAllApns = new ArrayList<ApnSetting>();
2024e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        IccRecords r = mIccRecords.get();
2025e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        String operator = (r != null) ? r.getOperatorNumeric() : "";
20260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (operator != null) {
20270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String selection = "numeric = '" + operator + "'";
20280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // query only enabled apn.
20290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // carrier_enabled : 1 means enabled apn, 0 disabled apn.
20300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            selection += " and carrier_enabled = 1";
20310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("createAllApnList: selection=" + selection);
20320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Cursor cursor = mPhone.getContext().getContentResolver().query(
20340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    Telephony.Carriers.CONTENT_URI, null, selection, null, null);
20350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (cursor != null) {
20370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (cursor.getCount() > 0) {
20380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mAllApns = createApnList(cursor);
20390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
20400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cursor.close();
20410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
20420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
20430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mAllApns.isEmpty()) {
20450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("createAllApnList: No APN found for carrier: " + operator);
20460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mPreferredApn = null;
20470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // TODO: What is the right behaviour?
20480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            //notifyNoData(GsmDataConnection.FailCause.MISSING_UNKNOWN_APN);
20490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
20500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mPreferredApn = getPreferredApn();
20510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator)) {
20520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPreferredApn = null;
20530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setPreferredApn(-1);
20540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
20550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("createAllApnList: mPreferredApn=" + mPreferredApn);
20560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
20570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("createAllApnList: X mAllApns=" + mAllApns);
20580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
20590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Return the id for a new data connection */
20610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private GsmDataConnection createDataConnection() {
20620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("createDataConnection E");
20630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        RetryManager rm = new RetryManager();
20650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int id = mUniqueIdGenerator.getAndIncrement();
20660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        GsmDataConnection conn = GsmDataConnection.makeDataConnection(mPhone, id, rm, this);
20670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDataConnections.put(id, conn);
20680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        DataConnectionAc dcac = new DataConnectionAc(conn, LOG_TAG);
20690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int status = dcac.fullyConnectSync(mPhone.getContext(), this, conn.getHandler());
20700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (status == AsyncChannel.STATUS_SUCCESSFUL) {
20710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mDataConnectionAsyncChannels.put(dcac.dataConnection.getDataConnectionId(), dcac);
20720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
20730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            loge("createDataConnection: Could not connect to dcac.mDc=" + dcac.dataConnection +
20740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " status=" + status);
20750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
20760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // install reconnect intent filter for this data connection.
20780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        IntentFilter filter = new IntentFilter();
20790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        filter.addAction(INTENT_RECONNECT_ALARM + '.' + id);
20800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
20810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("createDataConnection() X id=" + id + " dc=" + conn);
20830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return conn;
20840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
20850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void configureRetry(DataConnection dc, boolean forDefault, int retryCount) {
20870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
20880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("configureRetry: forDefault=" + forDefault + " retryCount=" + retryCount +
20890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " dc=" + dc);
20900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
20910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (dc == null) return;
20920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!dc.configureRetry(getReryConfig(forDefault))) {
20940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (forDefault) {
20950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!dc.configureRetry(DEFAULT_DATA_RETRY_CONFIG)) {
20960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Should never happen, log an error and default to a simple linear sequence.
20970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    loge("configureRetry: Could not configure using " +
20980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            "DEFAULT_DATA_RETRY_CONFIG=" + DEFAULT_DATA_RETRY_CONFIG);
20990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    dc.configureRetry(20, 2000, 1000);
21000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
21010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
21020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!dc.configureRetry(SECONDARY_DATA_RETRY_CONFIG)) {
21030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Should never happen, log an error and default to a simple sequence.
21040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    loge("configureRetry: Could note configure using " +
21050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            "SECONDARY_DATA_RETRY_CONFIG=" + SECONDARY_DATA_RETRY_CONFIG);
21060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    dc.configureRetry("max_retries=3, 333, 333, 333");
21070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
21080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
21090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
21100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        dc.setRetryCount(retryCount);
21110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
21120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
21130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void destroyDataConnections() {
21140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if(mDataConnections != null) {
21150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("destroyDataConnections: clear mDataConnectionList");
21160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mDataConnections.clear();
21170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
21180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("destroyDataConnections: mDataConnecitonList is empty, ignore");
21190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
21200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
21210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
21220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
21230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Build a list of APNs to be used to create PDP's.
21240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
21250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param requestedApnType
21260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return waitingApns list to be used to create PDP
21270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *          error when waitingApns.isEmpty()
21280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
21290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private ArrayList<ApnSetting> buildWaitingApns(String requestedApnType) {
21300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ArrayList<ApnSetting> apnList = new ArrayList<ApnSetting>();
21310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
21320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (requestedApnType.equals(PhoneConstants.APN_TYPE_DUN)) {
21330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ApnSetting dun = fetchDunApn();
21340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dun != null) {
21350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnList.add(dun);
21360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("buildWaitingApns: X added APN_TYPE_DUN apnList=" + apnList);
21370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return apnList;
21380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
21390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
21400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2141e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        IccRecords r = mIccRecords.get();
2142e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        String operator = (r != null) ? r.getOperatorNumeric() : "";
214362b20cd5b7ce5d7809ff1fe2b5796b2e605165e5Robert Greenwalt        int radioTech = mPhone.getServiceState().getRilRadioTechnology();
21440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2145175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin        // This is a workaround for a bug (7305641) where we don't failover to other
2146175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin        // suitable APNs if our preferred APN fails.  On prepaid ATT sims we need to
2147175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin        // failover to a provisioning APN, but once we've used their default data
2148175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin        // connection we are locked to it for life.  This change allows ATT devices
2149175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin        // to say they don't want to use preferred at all.
2150175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin        boolean usePreferred = true;
2151175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin        try {
2152175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin            usePreferred = ! mPhone.getContext().getResources().getBoolean(com.android.
2153175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin                    internal.R.bool.config_dontPreferApn);
2154175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin        } catch (Resources.NotFoundException e) {
2155175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin            usePreferred = true;
2156175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin        }
2157175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin
2158175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin        if (usePreferred && canSetPreferApn && mPreferredApn != null &&
21590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPreferredApn.canHandleType(requestedApnType)) {
21600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
21610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("buildWaitingApns: Preferred APN:" + operator + ":"
21620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        + mPreferredApn.numeric + ":" + mPreferredApn);
21630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
21640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (mPreferredApn.numeric.equals(operator)) {
216562b20cd5b7ce5d7809ff1fe2b5796b2e605165e5Robert Greenwalt                if (mPreferredApn.bearer == 0 || mPreferredApn.bearer == radioTech) {
21660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnList.add(mPreferredApn);
21670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
21680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return apnList;
21690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
21700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) log("buildWaitingApns: no preferred APN");
21710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setPreferredApn(-1);
21720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mPreferredApn = null;
21730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
21740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
21750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("buildWaitingApns: no preferred APN");
21760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setPreferredApn(-1);
21770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPreferredApn = null;
21780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
21790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
21800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mAllApns != null) {
21810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (ApnSetting apn : mAllApns) {
21820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (apn.canHandleType(requestedApnType)) {
218362b20cd5b7ce5d7809ff1fe2b5796b2e605165e5Robert Greenwalt                    if (apn.bearer == 0 || apn.bearer == radioTech) {
21840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("apn info : " +apn.toString());
21850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        apnList.add(apn);
21860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
21870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
21880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
21890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
21900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            loge("mAllApns is empty!");
21910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
21920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("buildWaitingApns: X apnList=" + apnList);
21930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return apnList;
21940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
21950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
21960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private String apnListToString (ArrayList<ApnSetting> apns) {
21970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        StringBuilder result = new StringBuilder();
21980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0, size = apns.size(); i < size; i++) {
21990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            result.append('[')
22000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                  .append(apns.get(i).toString())
22010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                  .append(']');
22020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
22030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return result.toString();
22040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
22050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void startDelayedRetry(GsmDataConnection.FailCause cause,
22070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                   ApnContext apnContext, int retryOverride) {
22080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        notifyNoData(cause, apnContext);
22090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        reconnectAfterFail(cause, apnContext, retryOverride);
22100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
22110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void setPreferredApn(int pos) {
22130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!canSetPreferApn) {
22140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("setPreferredApn: X !canSEtPreferApn");
22150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
22160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
22170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        log("setPreferredApn: delete");
22190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ContentResolver resolver = mPhone.getContext().getContentResolver();
22200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        resolver.delete(PREFERAPN_NO_UPDATE_URI, null, null);
22210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (pos >= 0) {
22230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("setPreferredApn: insert");
22240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ContentValues values = new ContentValues();
22250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            values.put(APN_ID, pos);
22260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            resolver.insert(PREFERAPN_NO_UPDATE_URI, values);
22270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
22280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
22290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private ApnSetting getPreferredApn() {
22310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mAllApns.isEmpty()) {
22320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("getPreferredApn: X not found mAllApns.isEmpty");
22330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return null;
22340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
22350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Cursor cursor = mPhone.getContext().getContentResolver().query(
22370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                PREFERAPN_NO_UPDATE_URI, new String[] { "_id", "name", "apn" },
22380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
22390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (cursor != null) {
22410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            canSetPreferApn = true;
22420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
22430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            canSetPreferApn = false;
22440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
22450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (canSetPreferApn && cursor.getCount() > 0) {
22470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int pos;
22480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cursor.moveToFirst();
22490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pos = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID));
22500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for(ApnSetting p:mAllApns) {
22510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (p.id == pos && p.canHandleType(mRequestedApnType)) {
22520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("getPreferredApn: X found apnSetting" + p);
22530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    cursor.close();
22540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return p;
22550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
22560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
22570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
22580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (cursor != null) {
22600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cursor.close();
22610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
22620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        log("getPreferredApn: X not found");
22640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return null;
22650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
22660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
22680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void handleMessage (Message msg) {
22690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("handleMessage msg=" + msg);
22700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!mPhone.mIsTheCurrentActivePhone || mIsDisposed) {
22720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            loge("handleMessage: Ignore GSM msgs since GSM phone is inactive");
22730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
22740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
22750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (msg.what) {
22770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DctConstants.EVENT_RECORDS_LOADED:
22780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                onRecordsLoaded();
22790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
22800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DctConstants.EVENT_DATA_CONNECTION_DETACHED:
22820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                onDataConnectionDetached();
22830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
22840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DctConstants.EVENT_DATA_CONNECTION_ATTACHED:
22860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                onDataConnectionAttached();
22870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
22880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DctConstants.EVENT_DATA_STATE_CHANGED:
22900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                onDataStateChanged((AsyncResult) msg.obj);
22910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
22920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DctConstants.EVENT_POLL_PDP:
22940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                onPollPdp();
22950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
22960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DctConstants.EVENT_DO_RECOVERY:
22980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                doRecovery();
22990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
23000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DctConstants.EVENT_APN_CHANGED:
23020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                onApnChanged();
23030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
23040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DctConstants.EVENT_PS_RESTRICT_ENABLED:
23060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                /**
23070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 * We don't need to explicitly to tear down the PDP context
23080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 * when PS restricted is enabled. The base band will deactive
23090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 * PDP context and notify us with PDP_CONTEXT_CHANGED.
23100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 * But we should stop the network polling and prevent reset PDP.
23110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 */
23120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
23130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                stopNetStatPoll();
23140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                stopDataStallAlarm();
23150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mIsPsRestricted = true;
23160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
23170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DctConstants.EVENT_PS_RESTRICT_DISABLED:
23190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                /**
23200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 * When PS restrict is removed, we need setup PDP connection if
23210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 * PDP connection is down.
23220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 */
23230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("EVENT_PS_RESTRICT_DISABLED " + mIsPsRestricted);
23240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mIsPsRestricted  = false;
23250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (isConnected()) {
23260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    startNetStatPoll();
23270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
23280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
23290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // TODO: Should all PDN states be checked to fail?
23300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (mState ==DctConstants.State.FAILED) {
23310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        cleanUpAllConnections(false, Phone.REASON_PS_RESTRICT_ENABLED);
23320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        resetAllRetryCounts();
23330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mReregisterOnReconnectFailure = false;
23340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
23350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    trySetupData(Phone.REASON_PS_RESTRICT_ENABLED, PhoneConstants.APN_TYPE_DEFAULT);
23360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
23370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
23380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DctConstants.EVENT_TRY_SETUP_DATA:
23390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (msg.obj instanceof ApnContext) {
23400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    onTrySetupData((ApnContext)msg.obj);
23410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (msg.obj instanceof String) {
23420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    onTrySetupData((String)msg.obj);
23430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
23440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    loge("EVENT_TRY_SETUP request w/o apnContext or String");
23450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
23460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
23470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DctConstants.EVENT_CLEAN_UP_CONNECTION:
23490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                boolean tearDown = (msg.arg1 == 0) ? false : true;
23500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("EVENT_CLEAN_UP_CONNECTION tearDown=" + tearDown);
23510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (msg.obj instanceof ApnContext) {
23520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    cleanUpConnection(tearDown, (ApnContext)msg.obj);
23530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
23540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    loge("EVENT_CLEAN_UP_CONNECTION request w/o apn context");
23550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
23560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
23570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
23580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // handle the message in the super class DataConnectionTracker
23590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                super.handleMessage(msg);
23600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
23610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
23620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
23630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected int getApnProfileID(String apnType) {
23650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IMS)) {
23660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return RILConstants.DATA_PROFILE_IMS;
23670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_FOTA)) {
23680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return RILConstants.DATA_PROFILE_FOTA;
23690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_CBS)) {
23700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return RILConstants.DATA_PROFILE_CBS;
23710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
23720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return RILConstants.DATA_PROFILE_DEFAULT;
23730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
23740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
23750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int getCellLocationId() {
23770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int cid = -1;
23780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CellLocation loc = mPhone.getCellLocation();
23790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (loc != null) {
23810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (loc instanceof GsmCellLocation) {
23820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cid = ((GsmCellLocation)loc).getCid();
23830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (loc instanceof CdmaCellLocation) {
23840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cid = ((CdmaCellLocation)loc).getBaseStationId();
23850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
23860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
23870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return cid;
23880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
23890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
2391e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected void onUpdateIcc() {
2392e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        if (mUiccController == null ) {
2393e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            return;
2394e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        }
2395e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
2396e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        IccRecords newIccRecords = mUiccController.getIccRecords(UiccController.APP_FAM_3GPP);
2397e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
2398e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        IccRecords r = mIccRecords.get();
2399e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        if (r != newIccRecords) {
2400e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            if (r != null) {
2401e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                log("Removing stale icc objects.");
2402e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                r.unregisterForRecordsLoaded(this);
2403e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                mIccRecords.set(null);
2404e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            }
2405e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            if (newIccRecords != null) {
2406e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                log("New records found");
2407e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                mIccRecords.set(newIccRecords);
2408e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                newIccRecords.registerForRecordsLoaded(
2409e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                        this, DctConstants.EVENT_RECORDS_LOADED, null);
2410e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            }
2411e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        }
2412e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    }
2413e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
2414e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    @Override
24150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void log(String s) {
24160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Log.d(LOG_TAG, "[GsmDCT] "+ s);
24170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
24180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
24190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
24200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void loge(String s) {
24210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Log.e(LOG_TAG, "[GsmDCT] " + s);
24220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
24230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
24240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
24250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
24260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println("GsmDataConnectionTracker extends:");
24270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        super.dump(fd, pw, args);
24280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mReregisterOnReconnectFailure=" + mReregisterOnReconnectFailure);
24290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" canSetPreferApn=" + canSetPreferApn);
24300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mApnObserver=" + mApnObserver);
24310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" getOverallState=" + getOverallState());
243227814a2e735c0221935d46654fb00ff3ec2c45eaWink Saville        pw.println(" mDataConnectionAsyncChannels=%s\n" + mDataConnectionAsyncChannels);
24330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
24340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
2435