DcTracker.java revision fd5de4dae153c57e13bf8979d6f7a8aa86e3dede
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;
52ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Savilleimport android.telephony.Rlog;
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;
650825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.Phone;
660825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.PhoneBase;
670825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.PhoneConstants;
680825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.RILConstants;
690825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.RetryManager;
70d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccRecords;
71d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.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        }
610f08c4c89622ddcbc4ed9315fe6b399941dad4939Wink Saville        mAutoAttachOnCreation = true;
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
954fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi   private boolean imsiMatches(String imsiDB, String imsiSIM) {
955fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        // Note: imsiDB value has digit number or 'x' character for seperating USIM information
956fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        // for MVNO operator. And then digit number is matched at same order and 'x' character
957fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        // could replace by any digit number.
958fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        // ex) if imsiDB inserted '310260x10xxxxxx' for GG Operator,
959fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        //     that means first 6 digits, 8th and 9th digit
960fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        //     should be set in USIM for GG Operator.
961fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        int len = imsiDB.length();
962fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        int idxCompare = 0;
963fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
964fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        if (len <= 0) return false;
965fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        if (len > imsiSIM.length()) return false;
966fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
967fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        for (int idx=0; idx<len; idx++) {
968fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            char c = imsiDB.charAt(idx);
969fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            if ((c == 'x') || (c == 'X') || (c == imsiSIM.charAt(idx))) {
970fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                continue;
971fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            } else {
972fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                return false;
973fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            }
974fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        }
975fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        return true;
976fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    }
977fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
978fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    private boolean mvnoMatches(IccRecords r, String mvno_type, String mvno_match_data) {
979fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        if (mvno_type.equalsIgnoreCase("spn")) {
980fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            if ((r.getServiceProviderName() != null) &&
981fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    r.getServiceProviderName().equalsIgnoreCase(mvno_match_data)) {
982fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                return true;
983fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            }
984fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        } else if (mvno_type.equalsIgnoreCase("imsi")) {
985fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            String imsiSIM = r.getIMSI();
986fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            if ((imsiSIM != null) && imsiMatches(mvno_match_data, imsiSIM)) {
987fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                return true;
988fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            }
989fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        } else if (mvno_type.equalsIgnoreCase("gid")) {
990fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            String gid1 = r.getGid1();
991fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            if ((gid1 != null) && gid1.substring(0,
992fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    mvno_match_data.length()).equalsIgnoreCase(mvno_match_data)) {
993fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                return true;
994fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            }
995fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        }
996fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        return false;
997fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    }
998fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
999fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    private ApnSetting makeApnSetting(Cursor cursor) {
1000fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        String[] types = parseTypes(
1001fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.TYPE)));
1002fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        ApnSetting apn = new ApnSetting(
1003fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID)),
1004fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NUMERIC)),
1005fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NAME)),
1006fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN)),
1007fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1008fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1009fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY))),
1010fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PORT)),
1011fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1012fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1013fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC))),
1014fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1015fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1016fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY))),
1017fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPORT)),
1018fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)),
1019fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)),
1020fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.AUTH_TYPE)),
1021fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                types,
1022fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROTOCOL)),
1023fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(
1024fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        Telephony.Carriers.ROAMING_PROTOCOL)),
1025fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(
1026fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        Telephony.Carriers.CARRIER_ENABLED)) == 1,
1027fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.BEARER)));
1028fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        return apn;
1029fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    }
1030fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
10310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private ArrayList<ApnSetting> createApnList(Cursor cursor) {
10320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ArrayList<ApnSetting> result = new ArrayList<ApnSetting>();
1033fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        IccRecords r = mIccRecords.get();
1034fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
10350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (cursor.moveToFirst()) {
1036fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            String mvnoType = null;
1037fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            String mvnoMatchData = null;
10380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            do {
1039fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                String cursorMvnoType = cursor.getString(
1040fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_TYPE));
1041fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                String cursorMvnoMatchData = cursor.getString(
1042fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_MATCH_DATA));
1043fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                if (mvnoType != null) {
1044fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    if (mvnoType.equals(cursorMvnoType) &&
1045fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                            mvnoMatchData.equals(cursorMvnoMatchData)) {
1046fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        result.add(makeApnSetting(cursor));
1047fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    }
1048fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                } else {
1049fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    // no mvno match yet
1050fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    if (mvnoMatches(r, cursorMvnoType, cursorMvnoMatchData)) {
1051fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        // first match - toss out non-mvno data
1052fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        result.clear();
1053fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        mvnoType = cursorMvnoType;
1054fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        mvnoMatchData = cursorMvnoMatchData;
1055fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        result.add(makeApnSetting(cursor));
1056fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    } else {
1057fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        // add only non-mvno data
1058fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        if (cursorMvnoType.equals("")) {
1059fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                            result.add(makeApnSetting(cursor));
1060fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        }
1061fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    }
1062fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                }
10630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } while (cursor.moveToNext());
10640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("createApnList: X result=" + result);
10660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return result;
10670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean dataConnectionNotInUse(DataConnectionAc dcac) {
1070ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville        if (DBG) log("dataConnectionNotInUse: check if dcac is inuse dc=" + dcac.dataConnection);
10710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1072ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville            if (apnContext.getDataConnectionAc() == dcac) {
1073ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville                if (DBG) log("dataConnectionNotInUse: in use by apnContext=" + apnContext);
1074ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville                return false;
1075ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville            }
1076ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville        }
1077ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville        // TODO: Fix retry handling so free DataConnections have empty apnlists.
1078ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville        // Probably move retry handling into DataConnections and reduce complexity
1079ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville        // of DCT.
1080ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville        for (ApnContext apnContext : dcac.getApnListSync()) {
1081ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville            if (DBG) {
1082ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville                log("dataConnectionNotInUse: removing apnContext=" + apnContext);
1083ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville            }
1084ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville            dcac.removeApnContextSync(apnContext);
10850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1086ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville        if (DBG) log("dataConnectionNotInUse: not in use return true");
10870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return true;
10880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private GsmDataConnection findFreeDataConnection() {
10910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
10920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dcac.isInactiveSync() && dataConnectionNotInUse(dcac)) {
10930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                DataConnection dc = dcac.dataConnection;
10940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) {
10950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("findFreeDataConnection: found free GsmDataConnection=" +
10960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        " dcac=" + dcac + " dc=" + dc);
10970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
10980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return (GsmDataConnection) dc;
10990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
11000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        log("findFreeDataConnection: NO free GsmDataConnection");
11020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return null;
11030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected GsmDataConnection findReadyDataConnection(ApnSetting apn) {
11060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apn == null) {
11070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return null;
11080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
11100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("findReadyDataConnection: apn string <" + apn + ">" +
11110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " dcacs.size=" + mDataConnectionAsyncChannels.size());
11120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
11140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ApnSetting apnSetting = dcac.getApnSettingSync();
11150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
11160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("findReadyDataConnection: dc apn string <" +
11170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                         (apnSetting != null ? (apnSetting.toString()) : "null") + ">");
11180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
11190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if ((apnSetting != null) && TextUtils.equals(apnSetting.toString(), apn.toString())) {
11200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                DataConnection dc = dcac.dataConnection;
11210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) {
11220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("findReadyDataConnection: found ready GsmDataConnection=" +
11230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        " dcac=" + dcac + " dc=" + dc);
11240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
11250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return (GsmDataConnection) dc;
11260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
11270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return null;
11290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean setupData(ApnContext apnContext) {
11330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("setupData: apnContext=" + apnContext);
11340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnSetting apn;
11350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        GsmDataConnection dc;
11360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int profileId = getApnProfileID(apnContext.getApnType());
11380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        apn = apnContext.getNextWaitingApn();
11390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apn == null) {
11400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("setupData: return for no apn found!");
11410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
11420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        dc = (GsmDataConnection) checkForConnectionForApnContext(apnContext);
11460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (dc == null) {
11480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            dc = findReadyDataConnection(apn);
11490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dc == null) {
11510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("setupData: No ready GsmDataConnection found!");
11520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // TODO: When allocating you are mapping type to id. If more than 1 free,
11530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // then could findFreeDataConnection get the wrong one??
11540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                dc = findFreeDataConnection();
11550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
11560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dc == null) {
11580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                dc = createDataConnection();
11590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
11600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dc == null) {
11620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("setupData: No free GsmDataConnection found!");
11630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return false;
11640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
11650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
11660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apn = mDataConnectionAsyncChannels.get(dc.getDataConnectionId()).getApnSettingSync();
11670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        DataConnectionAc dcac = mDataConnectionAsyncChannels.get(dc.getDataConnectionId());
11700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        dc.setProfileId( profileId );  //  assumed no connection sharing on profiled types
11710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int refCount = dcac.getRefCountSync();
11730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("setupData: init dc and apnContext refCount=" + refCount);
11740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // configure retry count if no other Apn is using the same connection.
11760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (refCount == 0) {
11770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            configureRetry(dc, apn.canHandleType(PhoneConstants.APN_TYPE_DEFAULT),
11780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.getRetryCount());
11790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        apnContext.setDataConnectionAc(dcac);
11810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        apnContext.setDataConnection(dc);
11820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        apnContext.setApnSetting(apn);
11840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        apnContext.setState(DctConstants.State.INITING);
11850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
11860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If reconnect alarm is active on this DataConnection, wait for the alarm being
11870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // fired so that we don't disruppt data retry pattern engaged.
11880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext.getDataConnectionAc().getReconnectIntentSync() != null) {
11890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("setupData: data reconnection pending");
11900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apnContext.setState(DctConstants.State.FAILED);
11910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
11920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
11930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Message msg = obtainMessage();
11960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        msg.what = DctConstants.EVENT_DATA_SETUP_COMPLETE;
11970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        msg.obj = apnContext;
11980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        dc.bringUp(msg, apn);
11990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("setupData: initing!");
12010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return true;
12020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Handles changes to the APN database.
12060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
12070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void onApnChanged() {
12080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        DctConstants.State overallState = getOverallState();
12090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean isDisconnected = (overallState == DctConstants.State.IDLE ||
12100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                overallState == DctConstants.State.FAILED);
12110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mPhone instanceof GSMPhone) {
12130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // The "current" may no longer be valid.  MMS depends on this to send properly. TBD
12140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ((GSMPhone)mPhone).updateCurrentCarrierInProvider();
12150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
12160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // TODO: It'd be nice to only do this if the changed entrie(s)
12180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // match the current operator.
12190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onApnChanged: createAllApnList and cleanUpAllConnections");
12200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        createAllApnList();
12210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cleanUpAllConnections(!isDisconnected, Phone.REASON_APN_CHANGED);
12220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (isDisconnected) {
12230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setupDataOnReadyApns(Phone.REASON_APN_CHANGED);
12240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
12250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param cid Connection id provided from RIL.
12290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return DataConnectionAc associated with specified cid.
12300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
12310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private DataConnectionAc findDataConnectionAcByCid(int cid) {
12320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
12330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dcac.getCidSync() == cid) {
12340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return dcac;
12350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
12360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
12370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return null;
12380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param dcacs Collection of DataConnectionAc reported from RIL.
12420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return List of ApnContext which is connected, but is not present in
12430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *         data connection list reported from RIL.
12440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
12450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private List<ApnContext> findApnContextToClean(Collection<DataConnectionAc> dcacs) {
12460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (dcacs == null) return null;
12470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("findApnContextToClean(ar): E dcacs=" + dcacs);
12490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ArrayList<ApnContext> list = new ArrayList<ApnContext>();
12510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (ApnContext apnContext : mApnContexts.values()) {
12520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (apnContext.getState() == DctConstants.State.CONNECTED) {
12530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                boolean found = false;
12540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                for (DataConnectionAc dcac : dcacs) {
12550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (dcac == apnContext.getDataConnectionAc()) {
12560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // ApnContext holds the ref to dcac present in data call list.
12570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        found = true;
12580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        break;
12590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
12600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
12610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!found) {
12620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // ApnContext does not have dcac reported in data call list.
12630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Fetch all the ApnContexts that map to this dcac which are in
12640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // INITING state too.
12650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) log("findApnContextToClean(ar): Connected apn not found in the list (" +
12660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                 apnContext.toString() + ")");
12670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (apnContext.getDataConnectionAc() != null) {
12680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        list.addAll(apnContext.getDataConnectionAc().getApnListSync());
12690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
12700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        list.add(apnContext);
12710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
12720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
12730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
12740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
12750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("findApnContextToClean(ar): X list=" + list);
12760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return list;
12770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param ar is the result of RIL_REQUEST_DATA_CALL_LIST
12810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * or RIL_UNSOL_DATA_CALL_LIST_CHANGED
12820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
12830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void onDataStateChanged (AsyncResult ar) {
12840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ArrayList<DataCallState> dataCallStates;
12850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onDataStateChanged(ar): E");
12870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        dataCallStates = (ArrayList<DataCallState>)(ar.result);
12880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ar.exception != null) {
12900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // This is probably "radio not available" or something
12910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // of that sort. If so, the whole connection is going
12920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // to come down soon anyway
12930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("onDataStateChanged(ar): exception; likely radio not available, ignore");
12940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
12950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
12960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onDataStateChanged(ar): DataCallState size=" + dataCallStates.size());
12970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1298b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla        boolean isAnyDataCallDormant = false;
1299b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla        boolean isAnyDataCallActive = false;
1300b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla
13010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Create a hash map to store the dataCallState of each DataConnectionAc
13020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        HashMap<DataCallState, DataConnectionAc> dataCallStateToDcac;
13030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        dataCallStateToDcac = new HashMap<DataCallState, DataConnectionAc>();
13040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (DataCallState dataCallState : dataCallStates) {
13050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            DataConnectionAc dcac = findDataConnectionAcByCid(dataCallState.cid);
13060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dcac != null) dataCallStateToDcac.put(dataCallState, dcac);
13080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
13090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // A list of apns to cleanup, those that aren't in the list we know we have to cleanup
13110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        List<ApnContext> apnsToCleanup = findApnContextToClean(dataCallStateToDcac.values());
13120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Find which connections have changed state and send a notification or cleanup
13140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (DataCallState newState : dataCallStates) {
13150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            DataConnectionAc dcac = dataCallStateToDcac.get(newState);
13160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dcac == null) {
13180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                loge("onDataStateChanged(ar): No associated DataConnection ignore");
13190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                continue;
13200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
13210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1322b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            if (newState.active == DATA_CONNECTION_ACTIVE_PH_LINK_UP) isAnyDataCallActive = true;
1323b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            if (newState.active == DATA_CONNECTION_ACTIVE_PH_LINK_DOWN) isAnyDataCallDormant = true;
1324b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla
13250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // The list of apn's associated with this DataConnection
13260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Collection<ApnContext> apns = dcac.getApnListSync();
13270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Find which ApnContexts of this DC are in the "Connected/Connecting" state.
13290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ArrayList<ApnContext> connectedApns = new ArrayList<ApnContext>();
13300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (ApnContext apnContext : apns) {
13310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (apnContext.getState() == DctConstants.State.CONNECTED ||
13320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                       apnContext.getState() == DctConstants.State.CONNECTING ||
13330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                       apnContext.getState() == DctConstants.State.INITING) {
13340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    connectedApns.add(apnContext);
13350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
13360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
13370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (connectedApns.size() == 0) {
13380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("onDataStateChanged(ar): no connected apns");
13390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
13400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Determine if the connection/apnContext should be cleaned up
13410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // or just a notification should be sent out.
13420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("onDataStateChanged(ar): Found ConnId=" + newState.cid
13430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        + " newState=" + newState.toString());
13440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (newState.active == 0) {
13450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) {
13460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("onDataStateChanged(ar): inactive, cleanup apns=" + connectedApns);
13470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
13480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnsToCleanup.addAll(connectedApns);
13490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
13500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Its active so update the DataConnections link properties
13510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    UpdateLinkPropertyResult result =
13520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        dcac.updateLinkPropertiesDataCallStateSync(newState);
13530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (result.oldLp.equals(result.newLp)) {
13540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("onDataStateChanged(ar): no change");
13550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
13560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (result.oldLp.isIdenticalInterfaceName(result.newLp)) {
13570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (! result.oldLp.isIdenticalDnses(result.newLp) ||
13580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    ! result.oldLp.isIdenticalRoutes(result.newLp) ||
13590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    ! result.oldLp.isIdenticalHttpProxy(result.newLp) ||
13600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    ! result.oldLp.isIdenticalAddresses(result.newLp)) {
13610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                // If the same address type was removed and added we need to cleanup
13620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                CompareResult<LinkAddress> car =
13630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    result.oldLp.compareAddresses(result.newLp);
13640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (DBG) {
13650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    log("onDataStateChanged: oldLp=" + result.oldLp +
13660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                            " newLp=" + result.newLp + " car=" + car);
13670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                }
13680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                boolean needToClean = false;
13690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                for (LinkAddress added : car.added) {
13700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    for (LinkAddress removed : car.removed) {
13710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        if (NetworkUtils.addressTypeMatches(removed.getAddress(),
13720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                                added.getAddress())) {
13730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                            needToClean = true;
13740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                            break;
13750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        }
13760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    }
13770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                }
13780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (needToClean) {
13790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    if (DBG) {
13800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        log("onDataStateChanged(ar): addr change, cleanup apns=" +
13810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                                connectedApns + " oldLp=" + result.oldLp +
13820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                                " newLp=" + result.newLp);
13830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    }
13840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    apnsToCleanup.addAll(connectedApns);
13850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                } else {
13860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    if (DBG) log("onDataStateChanged(ar): simple change");
13870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    for (ApnContext apnContext : connectedApns) {
13880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                         mPhone.notifyDataConnection(
13890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                                 PhoneConstants.REASON_LINK_PROPERTIES_CHANGED,
13900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                                 apnContext.getApnType());
13910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    }
13920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                }
13930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            } else {
13940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (DBG) {
13950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    log("onDataStateChanged(ar): no changes");
13960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                }
13970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
13980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        } else {
13990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (DBG) {
14000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                log("onDataStateChanged(ar): interface change, cleanup apns="
14010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        + connectedApns);
14020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
14030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            apnsToCleanup.addAll(connectedApns);
14040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
14050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
14060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
14070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
14080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
14090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1410b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla        if (isAnyDataCallDormant && !isAnyDataCallActive) {
1411b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            // There is no way to indicate link activity per APN right now. So
1412b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            // Link Activity will be considered dormant only when all data calls
1413b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            // are dormant.
1414b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            // If a single data call is in dormant state and none of the data
1415b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            // calls are active broadcast overall link state as dormant.
1416b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            mActivity = DctConstants.Activity.DORMANT;
1417b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            if (DBG) {
1418b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla                log("onDataStateChanged: Data Activity updated to DORMANT. stopNetStatePoll");
1419b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            }
1420b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            stopNetStatPoll();
1421b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla        } else {
1422b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            mActivity = DctConstants.Activity.NONE;
1423b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            if (DBG) {
1424b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla                log("onDataStateChanged: Data Activity updated to NONE. " +
1425b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla                         "isAnyDataCallActive = " + isAnyDataCallActive +
1426b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla                         " isAnyDataCallDormant = " + isAnyDataCallDormant);
1427b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            }
1428b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla            if (isAnyDataCallActive) startNetStatPoll();
1429b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla        }
1430b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla        mPhone.notifyDataActivity();
1431b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla
14320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnsToCleanup.size() != 0) {
14330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Add an event log when the network drops PDP
14340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int cid = getCellLocationId();
14350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP, cid,
14360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                TelephonyManager.getDefault().getNetworkType());
14370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
14380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Cleanup those dropped connections
14400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onDataStateChange(ar): apnsToCleanup=" + apnsToCleanup);
14410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (ApnContext apnContext : apnsToCleanup) {
14420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cleanUpConnection(true, apnContext);
14430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
14440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onDataStateChanged(ar): X");
14460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void notifyDefaultData(ApnContext apnContext) {
14490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
14500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("notifyDefaultData: type=" + apnContext.getApnType()
14510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                + ", reason:" + apnContext.getReason());
14520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
14530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        apnContext.setState(DctConstants.State.CONNECTED);
14540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // setState(DctConstants.State.CONNECTED);
14550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
14560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        startNetStatPoll();
14570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
14580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // reset reconnect timer
14590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        apnContext.setRetryCount(0);
14600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // TODO: For multiple Active APNs not exactly sure how to do this.
14630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void gotoIdleAndNotifyDataConnection(String reason) {
14640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("gotoIdleAndNotifyDataConnection: reason=" + reason);
14650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        notifyDataConnection(reason);
14660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mActiveApn = null;
14670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
14700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void restartRadio() {
14710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("restartRadio: ************TURN OFF RADIO**************");
14720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cleanUpAllConnections(true, Phone.REASON_RADIO_TURNED_OFF);
14730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.getServiceStateTracker().powerOffRadioSafely(this);
14740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        /* Note: no need to call setRadioPower(true).  Assuming the desired
14750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * radio power state is still ON (as tracked by ServiceStateTracker),
14760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * ServiceStateTracker will call setRadioPower when it receives the
14770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * RADIO_STATE_CHANGED notification for the power off.  And if the
14780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * desired power state has changed in the interim, we don't want to
14790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * override it with an unconditional power on.
14800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         */
14810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int reset = Integer.parseInt(SystemProperties.get("net.ppp.reset-by-timeout", "0"));
14830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SystemProperties.set("net.ppp.reset-by-timeout", String.valueOf(reset+1));
14840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
14870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Returns true if the last fail cause is something that
14880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * seems like it deserves an error notification.
14890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Transient errors are ignored
14900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
14910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean shouldPostNotification(GsmDataConnection.FailCause  cause) {
14920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return (cause != GsmDataConnection.FailCause.UNKNOWN);
14930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
14960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Return true if data connection need to be setup after disconnected due to
14970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * reason.
14980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
14990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param reason the reason why data is disconnected
15000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if try setup data connection is need for this reason
15010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
15020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean retryAfterDisconnected(String reason) {
15030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean retry = true;
15040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) ) {
15060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            retry = false;
15070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return retry;
15090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void reconnectAfterFail(FailCause lastFailCauseCode,
15120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    ApnContext apnContext, int retryOverride) {
15130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext == null) {
15140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            loge("reconnectAfterFail: apnContext == null, impossible");
15150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
15160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
15180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("reconnectAfterFail: lastFailCause=" + lastFailCauseCode +
15190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " retryOverride=" + retryOverride + " apnContext=" + apnContext);
15200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if ((apnContext.getState() == DctConstants.State.FAILED) &&
15220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            (apnContext.getDataConnection() != null)) {
15230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!apnContext.getDataConnection().isRetryNeeded()) {
15240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)) {
15250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType());
15260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return;
15270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
15280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (mReregisterOnReconnectFailure) {
15290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // We've re-registerd once now just retry forever.
15300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.getDataConnection().retryForeverUsingLastTimeout();
15310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
15320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Try to Re-register to the network.
15330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) log("reconnectAfterFail: activate failed, Reregistering to network");
15340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mReregisterOnReconnectFailure = true;
15350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mPhone.getServiceStateTracker().reRegisterNetwork(null);
15360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.setRetryCount(0);
15370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return;
15380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
15390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
15400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // If retry needs to be backed off for specific case (determined by RIL/Modem)
15420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // use the specified timer instead of pre-configured retry pattern.
15430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int nextReconnectDelay = retryOverride;
15440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (nextReconnectDelay < 0) {
15450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                nextReconnectDelay = apnContext.getDataConnection().getRetryTimer();
15460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext.getDataConnection().increaseRetryCount();
15470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) {
15480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("reconnectAfterFail: increaseRetryCount=" +
15490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            apnContext.getDataConnection().getRetryCount() +
15500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            " nextReconnectDelay=" + nextReconnectDelay);
15510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
15520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
15530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            startAlarmForReconnect(nextReconnectDelay, apnContext);
15540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!shouldPostNotification(lastFailCauseCode)) {
15560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) {
15570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("reconnectAfterFail: NOT Posting GPRS Unavailable notification "
15580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                + "-- likely transient error");
15590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
15600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
15610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                notifyNoData(lastFailCauseCode, apnContext);
15620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
15630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void startAlarmForReconnect(int delay, ApnContext apnContext) {
15670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        DataConnectionAc dcac = apnContext.getDataConnectionAc();
15690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if ((dcac == null) || (dcac.dataConnection == null)) {
15710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // should not happen, but just in case.
15720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            loge("startAlarmForReconnect: null dcac or dc.");
15730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
15740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        AlarmManager am =
15770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
15780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Intent intent = new Intent(INTENT_RECONNECT_ALARM + '.' +
15800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                   dcac.dataConnection.getDataConnectionId());
15810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String reason = apnContext.getReason();
15820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, reason);
15830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int connectionId = dcac.dataConnection.getDataConnectionId();
15840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, connectionId);
15850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // TODO: Until a real fix is created, which probably entails pushing
15870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // retires into the DC itself, this fix gets the retry count and
15880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // puts it in the reconnect alarm. When the reconnect alarm fires
15890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // onActionIntentReconnectAlarm is called which will use the value saved
15900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // here and save it in the ApnContext and send the EVENT_CONNECT message
15910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // which invokes setupData. Then setupData will use the value in the ApnContext
15920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // and to tell the DC to set the retry count in the retry manager.
15930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int retryCount = dcac.dataConnection.getRetryCount();
15940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_RETRY_COUNT, retryCount);
15950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
15970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("startAlarmForReconnect: next attempt in " + (delay / 1000) + "s" +
15980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " reason='" + reason + "' connectionId=" + connectionId +
15990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " retryCount=" + retryCount);
16000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        PendingIntent alarmIntent = PendingIntent.getBroadcast (mPhone.getContext(), 0,
16030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        intent, PendingIntent.FLAG_UPDATE_CURRENT);
16040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        dcac.setReconnectIntentSync(alarmIntent);
16050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
16060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                SystemClock.elapsedRealtime() + delay, alarmIntent);
16070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void notifyNoData(GsmDataConnection.FailCause lastFailCauseCode,
16110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                              ApnContext apnContext) {
16120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log( "notifyNoData: type=" + apnContext.getApnType());
16130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        apnContext.setState(DctConstants.State.FAILED);
16140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (lastFailCauseCode.isPermanentFail()
16150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            && (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT))) {
16160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
16170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void onRecordsLoaded() {
16210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onRecordsLoaded: createAllApnList");
16220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        createAllApnList();
16230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mPhone.mCM.getRadioState().isOn()) {
16240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("onRecordsLoaded: notifying data availability");
16250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notifyOffApnsOfAvailability(Phone.REASON_SIM_LOADED);
16260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        setupDataOnReadyApns(Phone.REASON_SIM_LOADED);
16280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
16310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onSetDependencyMet(String apnType, boolean met) {
16320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // don't allow users to tweak hipri to work around default dependency not met
16330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (PhoneConstants.APN_TYPE_HIPRI.equals(apnType)) return;
16340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnContext apnContext = mApnContexts.get(apnType);
16360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext == null) {
16370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            loge("onSetDependencyMet: ApnContext not found in onSetDependencyMet(" +
16380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnType + ", " + met + ")");
16390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
16400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        applyNewState(apnContext, apnContext.isEnabled(), met);
16420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (PhoneConstants.APN_TYPE_DEFAULT.equals(apnType)) {
16430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // tie actions on default to similar actions on HIPRI regarding dependencyMet
16440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apnContext = mApnContexts.get(PhoneConstants.APN_TYPE_HIPRI);
16450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (apnContext != null) applyNewState(apnContext, apnContext.isEnabled(), met);
16460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void applyNewState(ApnContext apnContext, boolean enabled, boolean met) {
16500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean cleanup = false;
16510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean trySetup = false;
16520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
16530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("applyNewState(" + apnContext.getApnType() + ", " + enabled +
16540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    "(" + apnContext.isEnabled() + "), " + met + "(" +
16550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.getDependencyMet() +"))");
16560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext.isReady()) {
16580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (enabled && met) return;
16590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!enabled) {
16600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext.setReason(Phone.REASON_DATA_DISABLED);
16610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
16620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_UNMET);
16630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
16640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cleanup = true;
16650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
16660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (enabled && met) {
16670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (apnContext.isEnabled()) {
16680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_MET);
16690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
16700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.setReason(Phone.REASON_DATA_ENABLED);
16710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
16720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (apnContext.getState() == DctConstants.State.FAILED) {
16730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.setState(DctConstants.State.IDLE);
16740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
16750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                trySetup = true;
16760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
16770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        apnContext.setEnabled(enabled);
16790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        apnContext.setDependencyMet(met);
16800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (cleanup) cleanUpConnection(true, apnContext);
16810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (trySetup) trySetupData(apnContext);
16820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private DataConnection checkForConnectionForApnContext(ApnContext apnContext) {
16850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Loop through all apnContexts looking for one with a conn that satisfies this apnType
16860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String apnType = apnContext.getApnType();
16870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnSetting dunSetting = null;
16880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (PhoneConstants.APN_TYPE_DUN.equals(apnType)) {
16900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            dunSetting = fetchDunApn();
16910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        DataConnection potential = null;
16940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (ApnContext c : mApnContexts.values()) {
16950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            DataConnection conn = c.getDataConnection();
16960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (conn != null) {
16970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ApnSetting apnSetting = c.getApnSetting();
16980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (dunSetting != null) {
16990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (dunSetting.equals(apnSetting)) {
17000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        switch (c.getState()) {
17010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            case CONNECTED:
17020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (DBG) {
17030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    log("checkForConnectionForApnContext: apnContext=" +
17040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                            apnContext + " found conn=" + conn);
17050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                }
17060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                return conn;
17070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            case CONNECTING:
17080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                potential = conn;
17090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
17100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
17110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (apnSetting != null && apnSetting.canHandleType(apnType)) {
17120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    switch (c.getState()) {
17130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        case CONNECTED:
17140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (DBG) {
17150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                log("checkForConnectionForApnContext: apnContext=" + apnContext +
17160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        " found conn=" + conn);
17170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
17180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            return conn;
17190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        case CONNECTING:
17200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            potential = conn;
17210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
17220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
17230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
17240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (potential != null) {
17260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
17270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("checkForConnectionForApnContext: apnContext=" + apnContext +
17280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " found conn=" + potential);
17290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
17300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return potential;
17310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("checkForConnectionForApnContext: apnContext=" + apnContext + " NO conn");
17340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return null;
17350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
17360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
17380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onEnableApn(int apnId, int enabled) {
17390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnContext apnContext = mApnContexts.get(apnIdToType(apnId));
17400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext == null) {
17410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            loge("onEnableApn(" + apnId + ", " + enabled + "): NO ApnContext");
17420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
17430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // TODO change our retry manager to use the appropriate numbers for the new APN
17450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onEnableApn: apnContext=" + apnContext + " call applyNewState");
17460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        applyNewState(apnContext, enabled == DctConstants.ENABLED, apnContext.getDependencyMet());
17470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
17480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
17500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // TODO: We shouldnt need this.
17510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected boolean onTrySetupData(String reason) {
17520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onTrySetupData: reason=" + reason);
17530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        setupDataOnReadyApns(reason);
17540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return true;
17550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
17560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected boolean onTrySetupData(ApnContext apnContext) {
17580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onTrySetupData: apnContext=" + apnContext);
17590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return trySetupData(apnContext);
17600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
17610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
17630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onRoamingOff() {
17640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onRoamingOff");
17650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mUserDataEnabled == false) return;
17670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (getDataOnRoamingEnabled() == false) {
17690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_OFF);
17700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setupDataOnReadyApns(Phone.REASON_ROAMING_OFF);
17710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
17720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notifyDataConnection(Phone.REASON_ROAMING_OFF);
17730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
17750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
17770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onRoamingOn() {
17780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mUserDataEnabled == false) return;
17790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (getDataOnRoamingEnabled()) {
17810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("onRoamingOn: setup data on roaming");
17820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setupDataOnReadyApns(Phone.REASON_ROAMING_ON);
17830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notifyDataConnection(Phone.REASON_ROAMING_ON);
17840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
17850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("onRoamingOn: Tear down data connection on roaming.");
17860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cleanUpAllConnections(true, Phone.REASON_ROAMING_ON);
17870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
17880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
17900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
17920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onRadioAvailable() {
17930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onRadioAvailable");
17940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mPhone.getSimulatedRadioControl() != null) {
17950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Assume data is connected on the simulator
17960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // FIXME  this can be improved
17970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // setState(DctConstants.State.CONNECTED);
17980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notifyDataConnection(null);
17990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("onRadioAvailable: We're on the simulator; assuming data is connected");
18010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
18020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1803e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        IccRecords r = mIccRecords.get();
1804e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        if (r != null && r.getRecordsLoaded()) {
18050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notifyOffApnsOfAvailability(null);
18060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
18070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (getOverallState() != DctConstants.State.IDLE) {
18090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cleanUpConnection(true, null);
18100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
18110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
18120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
18140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onRadioOffOrNotAvailable() {
18150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Make sure our reconnect delay starts at the initial value
18160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // next time the radio comes on
18170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        resetAllRetryCounts();
18190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mReregisterOnReconnectFailure = false;
18200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mPhone.getSimulatedRadioControl() != null) {
18220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Assume data is connected on the simulator
18230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // FIXME  this can be improved
18240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("We're on the simulator; assuming radio off is meaningless");
18250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
18260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("onRadioOffOrNotAvailable: is off and clean up all connections");
18270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cleanUpAllConnections(false, Phone.REASON_RADIO_TURNED_OFF);
18280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
18290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        notifyOffApnsOfAvailability(null);
18300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
18310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
18330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onDataSetupComplete(AsyncResult ar) {
18340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        DataConnection.FailCause cause = DataConnection.FailCause.UNKNOWN;
18360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean handleError = false;
18370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnContext apnContext = null;
18380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if(ar.userObj instanceof ApnContext){
18400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apnContext = (ApnContext)ar.userObj;
18410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
18420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new RuntimeException("onDataSetupComplete: No apnContext");
18430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
18440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (isDataSetupCompleteOk(ar)) {
18460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            DataConnectionAc dcac = apnContext.getDataConnectionAc();
18470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (RADIO_TESTS) {
18490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Note: To change radio.test.onDSC.null.dcac from command line you need to
18500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // adb root and adb remount and from the command line you can only change the
18510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // value to 1 once. To change it a second time you can reboot or execute
18520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // adb shell stop and then adb shell start. The command line to set the value is:
18530825495a331bb44df395a0cdb79fab85e68db5d5Wink 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');"
18540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ContentResolver cr = mPhone.getContext().getContentResolver();
18550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                String radioTestProperty = "radio.test.onDSC.null.dcac";
18560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (Settings.System.getInt(cr, radioTestProperty, 0) == 1) {
18570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("onDataSetupComplete: " + radioTestProperty +
18580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            " is true, set dcac to null and reset property to false");
18590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    dcac = null;
18600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    Settings.System.putInt(cr, radioTestProperty, 0);
18610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("onDataSetupComplete: " + radioTestProperty + "=" +
18620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            Settings.System.getInt(mPhone.getContext().getContentResolver(),
18630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    radioTestProperty, -1));
18640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
18650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
18660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dcac == null) {
18670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("onDataSetupComplete: no connection to DC, handle as error");
18680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cause = DataConnection.FailCause.CONNECTION_TO_DATACONNECTIONAC_BROKEN;
18690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                handleError = true;
18700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
18710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                DataConnection dc = apnContext.getDataConnection();
18720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ApnSetting apn = apnContext.getApnSetting();
18730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) {
18740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("onDataSetupComplete: success apn=" + (apn == null ? "unknown" : apn.apn));
18750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
18760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (apn != null && apn.proxy != null && apn.proxy.length() != 0) {
18770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    try {
18780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        String port = apn.port;
18790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (TextUtils.isEmpty(port)) port = "8080";
18800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        ProxyProperties proxy = new ProxyProperties(apn.proxy,
18810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                Integer.parseInt(port), null);
18820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        dcac.setLinkPropertiesHttpProxySync(proxy);
18830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } catch (NumberFormatException e) {
18840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        loge("onDataSetupComplete: NumberFormatException making ProxyProperties (" +
18850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                apn.port + "): " + e);
18860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
18870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
18880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // everything is setup
18900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if(TextUtils.equals(apnContext.getApnType(),PhoneConstants.APN_TYPE_DEFAULT)) {
18910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    SystemProperties.set("gsm.defaultpdpcontext.active", "true");
18920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (canSetPreferApn && mPreferredApn == null) {
18930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("onDataSetupComplete: PREFERED APN is null");
18940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mPreferredApn = apn;
18950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (mPreferredApn != null) {
18960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            setPreferredApn(mPreferredApn.id);
18970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
18980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
18990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
19000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    SystemProperties.set("gsm.defaultpdpcontext.active", "false");
19010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
19020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                notifyDefaultData(apnContext);
19030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
19040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
19050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cause = (DataConnection.FailCause) (ar.result);
19060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
19070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ApnSetting apn = apnContext.getApnSetting();
19080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log(String.format("onDataSetupComplete: error apn=%s cause=%s",
19090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        (apn == null ? "unknown" : apn.apn), cause));
19100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
19110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (cause.isEventLoggable()) {
19120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Log this failure to the Event Logs.
19130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                int cid = getCellLocationId();
19140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                EventLog.writeEvent(EventLogTags.PDP_SETUP_FAIL,
19150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        cause.ordinal(), cid, TelephonyManager.getDefault().getNetworkType());
19160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
19170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
19180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Count permanent failures and remove the APN we just tried
19190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (cause.isPermanentFail()) apnContext.decWaitingApnsPermFailCount();
19200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
19210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apnContext.removeWaitingApn(apnContext.getApnSetting());
19220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
19230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log(String.format("onDataSetupComplete: WaitingApns.size=%d" +
19240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        " WaitingApnsPermFailureCountDown=%d",
19250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        apnContext.getWaitingApns().size(),
19260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        apnContext.getWaitingApnsPermFailCount()));
19270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
19280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            handleError = true;
19290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
19300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
19310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (handleError) {
19320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // See if there are more APN's to try
19330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (apnContext.getWaitingApns().isEmpty()) {
19340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (apnContext.getWaitingApnsPermFailCount() == 0) {
19350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) {
19360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("onDataSetupComplete: All APN's had permanent failures, stop retrying");
19370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
19380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.setState(DctConstants.State.FAILED);
19390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType());
19400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
19410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.setDataConnection(null);
19420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnContext.setDataConnectionAc(null);
19430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
19440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) log("onDataSetupComplete: Not all permanent failures, retry");
19450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // check to see if retry should be overridden for this failure.
19460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int retryOverride = -1;
19470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (ar.exception instanceof DataConnection.CallSetupException) {
19480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        retryOverride =
19490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            ((DataConnection.CallSetupException)ar.exception).getRetryOverride();
19500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
19510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (retryOverride == RILConstants.MAX_INT) {
19520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("No retry is suggested.");
19530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
19540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        startDelayedRetry(cause, apnContext, retryOverride);
19550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
19560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
19570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
19580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("onDataSetupComplete: Try next APN");
19590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext.setState(DctConstants.State.SCANNING);
19600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Wait a bit before trying the next APN, so that
19610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // we're not tying up the RIL command channel
19620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                startAlarmForReconnect(APN_DELAY_MILLIS, apnContext);
19630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
19640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
19650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
19660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
19670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
19680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Called when EVENT_DISCONNECT_DONE is received.
19690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
19700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
19710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onDisconnectDone(int connId, AsyncResult ar) {
19720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnContext apnContext = null;
19730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
19740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ar.userObj instanceof ApnContext) {
19750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apnContext = (ApnContext) ar.userObj;
19760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
1977ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville            loge("onDisconnectDone: Invalid ar in onDisconnectDone, ignore");
19780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
19790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
19800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1981ffcb548fa2fdcc170ef4bbbe50f0348959cac8f1Wink Saville        if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE apnContext=" + apnContext);
19820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        apnContext.setState(DctConstants.State.IDLE);
19830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
19840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
19850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
19860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // if all data connection are gone, check whether Airplane mode request was
19870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // pending.
19880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (isDisconnected()) {
19890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (mPhone.getServiceStateTracker().processPendingRadioPowerOffAfterDataOff()) {
19900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Radio will be turned off. No need to retry data setup
19910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext.setApnSetting(null);
19920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext.setDataConnection(null);
19930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnContext.setDataConnectionAc(null);
19940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
19950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
19960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
19970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
19980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If APN is still enabled, try to bring it back up automatically
19990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext.isReady() && retryAfterDisconnected(apnContext.getReason())) {
20000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            SystemProperties.set("gsm.defaultpdpcontext.active", "false");  // TODO - what the heck?  This shoudld go
20010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Wait a bit before trying the next APN, so that
20020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // we're not tying up the RIL command channel.
20030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // This also helps in any external dependency to turn off the context.
20040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            startAlarmForReconnect(APN_DELAY_MILLIS, apnContext);
20050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
20060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apnContext.setApnSetting(null);
20070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apnContext.setDataConnection(null);
20080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apnContext.setDataConnectionAc(null);
20090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
20100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
20110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onPollPdp() {
20130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (getOverallState() == DctConstants.State.CONNECTED) {
20140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // only poll when connected
20150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mPhone.mCM.getDataCallList(this.obtainMessage(DctConstants.EVENT_DATA_STATE_CHANGED));
20160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            sendMessageDelayed(obtainMessage(DctConstants.EVENT_POLL_PDP), POLL_PDP_MILLIS);
20170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
20180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
20190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
20210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onVoiceCallStarted() {
20220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onVoiceCallStarted");
20230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (isConnected() && ! mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
20240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("onVoiceCallStarted stop polling");
20250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            stopNetStatPoll();
20260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            stopDataStallAlarm();
20270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
20280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
20290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
20300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
20320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onVoiceCallEnded() {
20330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onVoiceCallEnded");
20340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (isConnected()) {
20350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
20360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                startNetStatPoll();
20370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
20380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
20390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
20400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // clean slate after call end.
20410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                resetPollStats();
20420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
20430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
20440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // reset reconnect timer
20450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        setupDataOnReadyApns(Phone.REASON_VOICE_CALL_ENDED);
20460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
20470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
20490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void onCleanUpConnection(boolean tearDown, int apnId, String reason) {
20500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onCleanUpConnection");
20510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ApnContext apnContext = mApnContexts.get(apnIdToType(apnId));
20520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (apnContext != null) {
20530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            apnContext.setReason(reason);
20540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cleanUpConnection(tearDown, apnContext);
20550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
20560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
20570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected boolean isConnected() {
20590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (ApnContext apnContext : mApnContexts.values()) {
20600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (apnContext.getState() ==DctConstants.State.CONNECTED) {
20610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // At least one context is connected, return true
20620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return true;
20630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
20640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
20650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // There are not any contexts connected, return false
20660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return false;
20670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
20680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
20700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean isDisconnected() {
20710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (ApnContext apnContext : mApnContexts.values()) {
20720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!apnContext.isDisconnected()) {
20730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // At least one context was not disconnected return false
20740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return false;
20750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
20760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
20770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // All contexts were disconnected so return true
20780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return true;
20790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
20800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
20820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void notifyDataConnection(String reason) {
20830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("notifyDataConnection: reason=" + reason);
20840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (ApnContext apnContext : mApnContexts.values()) {
20850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (apnContext.isReady()) {
20860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("notifyDataConnection: type:"+apnContext.getApnType());
20870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
20880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        apnContext.getApnType());
20890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
20900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
20910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        notifyOffApnsOfAvailability(reason);
20920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
20930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
20950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Based on the sim operator numeric, create a list for all possible
20960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Data Connections and setup the preferredApn.
20970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
20980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void createAllApnList() {
20990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mAllApns = new ArrayList<ApnSetting>();
2100e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        IccRecords r = mIccRecords.get();
2101e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        String operator = (r != null) ? r.getOperatorNumeric() : "";
21020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (operator != null) {
21030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String selection = "numeric = '" + operator + "'";
21040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // query only enabled apn.
21050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // carrier_enabled : 1 means enabled apn, 0 disabled apn.
21060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            selection += " and carrier_enabled = 1";
21070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("createAllApnList: selection=" + selection);
21080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
21090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Cursor cursor = mPhone.getContext().getContentResolver().query(
21100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    Telephony.Carriers.CONTENT_URI, null, selection, null, null);
21110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
21120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (cursor != null) {
21130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (cursor.getCount() > 0) {
21140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mAllApns = createApnList(cursor);
21150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
21160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cursor.close();
21170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
21180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
21190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
21200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mAllApns.isEmpty()) {
21210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("createAllApnList: No APN found for carrier: " + operator);
21220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mPreferredApn = null;
21230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // TODO: What is the right behaviour?
21240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            //notifyNoData(GsmDataConnection.FailCause.MISSING_UNKNOWN_APN);
21250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
21260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mPreferredApn = getPreferredApn();
21270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator)) {
21280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPreferredApn = null;
21290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setPreferredApn(-1);
21300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
21310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("createAllApnList: mPreferredApn=" + mPreferredApn);
21320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
21330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("createAllApnList: X mAllApns=" + mAllApns);
21340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
21350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
21360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Return the id for a new data connection */
21370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private GsmDataConnection createDataConnection() {
21380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("createDataConnection E");
21390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
21400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        RetryManager rm = new RetryManager();
21410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int id = mUniqueIdGenerator.getAndIncrement();
21420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        GsmDataConnection conn = GsmDataConnection.makeDataConnection(mPhone, id, rm, this);
21430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDataConnections.put(id, conn);
21440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        DataConnectionAc dcac = new DataConnectionAc(conn, LOG_TAG);
21450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int status = dcac.fullyConnectSync(mPhone.getContext(), this, conn.getHandler());
21460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (status == AsyncChannel.STATUS_SUCCESSFUL) {
21470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mDataConnectionAsyncChannels.put(dcac.dataConnection.getDataConnectionId(), dcac);
21480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
21490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            loge("createDataConnection: Could not connect to dcac.mDc=" + dcac.dataConnection +
21500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " status=" + status);
21510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
21520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
21530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // install reconnect intent filter for this data connection.
21540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        IntentFilter filter = new IntentFilter();
21550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        filter.addAction(INTENT_RECONNECT_ALARM + '.' + id);
21560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
21570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
21580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("createDataConnection() X id=" + id + " dc=" + conn);
21590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return conn;
21600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
21610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
21620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void configureRetry(DataConnection dc, boolean forDefault, int retryCount) {
21630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
21640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("configureRetry: forDefault=" + forDefault + " retryCount=" + retryCount +
21650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " dc=" + dc);
21660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
21670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (dc == null) return;
21680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
21690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!dc.configureRetry(getReryConfig(forDefault))) {
21700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (forDefault) {
21710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!dc.configureRetry(DEFAULT_DATA_RETRY_CONFIG)) {
21720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Should never happen, log an error and default to a simple linear sequence.
21730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    loge("configureRetry: Could not configure using " +
21740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            "DEFAULT_DATA_RETRY_CONFIG=" + DEFAULT_DATA_RETRY_CONFIG);
21750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    dc.configureRetry(20, 2000, 1000);
21760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
21770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
21780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!dc.configureRetry(SECONDARY_DATA_RETRY_CONFIG)) {
21790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Should never happen, log an error and default to a simple sequence.
21800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    loge("configureRetry: Could note configure using " +
21810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            "SECONDARY_DATA_RETRY_CONFIG=" + SECONDARY_DATA_RETRY_CONFIG);
21820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    dc.configureRetry("max_retries=3, 333, 333, 333");
21830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
21840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
21850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
21860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        dc.setRetryCount(retryCount);
21870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
21880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
21890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void destroyDataConnections() {
21900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if(mDataConnections != null) {
21910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("destroyDataConnections: clear mDataConnectionList");
21920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mDataConnections.clear();
21930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
21940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("destroyDataConnections: mDataConnecitonList is empty, ignore");
21950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
21960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
21970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
21980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
21990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Build a list of APNs to be used to create PDP's.
22000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
22010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param requestedApnType
22020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return waitingApns list to be used to create PDP
22030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *          error when waitingApns.isEmpty()
22040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
22050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private ArrayList<ApnSetting> buildWaitingApns(String requestedApnType) {
22060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ArrayList<ApnSetting> apnList = new ArrayList<ApnSetting>();
22070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (requestedApnType.equals(PhoneConstants.APN_TYPE_DUN)) {
22090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ApnSetting dun = fetchDunApn();
22100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dun != null) {
22110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                apnList.add(dun);
22120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("buildWaitingApns: X added APN_TYPE_DUN apnList=" + apnList);
22130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return apnList;
22140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
22150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
22160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2217e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        IccRecords r = mIccRecords.get();
2218e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        String operator = (r != null) ? r.getOperatorNumeric() : "";
221962b20cd5b7ce5d7809ff1fe2b5796b2e605165e5Robert Greenwalt        int radioTech = mPhone.getServiceState().getRilRadioTechnology();
22200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2221175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin        // This is a workaround for a bug (7305641) where we don't failover to other
2222175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin        // suitable APNs if our preferred APN fails.  On prepaid ATT sims we need to
2223175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin        // failover to a provisioning APN, but once we've used their default data
2224175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin        // connection we are locked to it for life.  This change allows ATT devices
2225175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin        // to say they don't want to use preferred at all.
2226175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin        boolean usePreferred = true;
2227175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin        try {
2228175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin            usePreferred = ! mPhone.getContext().getResources().getBoolean(com.android.
2229175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin                    internal.R.bool.config_dontPreferApn);
2230175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin        } catch (Resources.NotFoundException e) {
2231175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin            usePreferred = true;
2232175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin        }
2233175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin
2234175442fc1d7ed440e4c2a7aaffe38521446dec8cBaligh Uddin        if (usePreferred && canSetPreferApn && mPreferredApn != null &&
22350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPreferredApn.canHandleType(requestedApnType)) {
22360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
22370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("buildWaitingApns: Preferred APN:" + operator + ":"
22380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        + mPreferredApn.numeric + ":" + mPreferredApn);
22390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
22400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (mPreferredApn.numeric.equals(operator)) {
224162b20cd5b7ce5d7809ff1fe2b5796b2e605165e5Robert Greenwalt                if (mPreferredApn.bearer == 0 || mPreferredApn.bearer == radioTech) {
22420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    apnList.add(mPreferredApn);
22430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
22440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return apnList;
22450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
22460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) log("buildWaitingApns: no preferred APN");
22470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setPreferredApn(-1);
22480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mPreferredApn = null;
22490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
22500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
22510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("buildWaitingApns: no preferred APN");
22520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setPreferredApn(-1);
22530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPreferredApn = null;
22540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
22550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
22560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mAllApns != null) {
22570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (ApnSetting apn : mAllApns) {
22580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (apn.canHandleType(requestedApnType)) {
225962b20cd5b7ce5d7809ff1fe2b5796b2e605165e5Robert Greenwalt                    if (apn.bearer == 0 || apn.bearer == radioTech) {
22600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("apn info : " +apn.toString());
22610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        apnList.add(apn);
22620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
22630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
22640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
22650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
22660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            loge("mAllApns is empty!");
22670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
22680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("buildWaitingApns: X apnList=" + apnList);
22690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return apnList;
22700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
22710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private String apnListToString (ArrayList<ApnSetting> apns) {
22730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        StringBuilder result = new StringBuilder();
22740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0, size = apns.size(); i < size; i++) {
22750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            result.append('[')
22760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                  .append(apns.get(i).toString())
22770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                  .append(']');
22780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
22790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return result.toString();
22800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
22810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void startDelayedRetry(GsmDataConnection.FailCause cause,
22830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                   ApnContext apnContext, int retryOverride) {
22840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        notifyNoData(cause, apnContext);
22850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        reconnectAfterFail(cause, apnContext, retryOverride);
22860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
22870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void setPreferredApn(int pos) {
22890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!canSetPreferApn) {
22900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("setPreferredApn: X !canSEtPreferApn");
22910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
22920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
22930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        log("setPreferredApn: delete");
22950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ContentResolver resolver = mPhone.getContext().getContentResolver();
22960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        resolver.delete(PREFERAPN_NO_UPDATE_URI, null, null);
22970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (pos >= 0) {
22990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("setPreferredApn: insert");
23000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ContentValues values = new ContentValues();
23010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            values.put(APN_ID, pos);
23020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            resolver.insert(PREFERAPN_NO_UPDATE_URI, values);
23030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
23040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
23050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private ApnSetting getPreferredApn() {
23070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mAllApns.isEmpty()) {
23080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("getPreferredApn: X not found mAllApns.isEmpty");
23090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return null;
23100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
23110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Cursor cursor = mPhone.getContext().getContentResolver().query(
23130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                PREFERAPN_NO_UPDATE_URI, new String[] { "_id", "name", "apn" },
23140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
23150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (cursor != null) {
23170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            canSetPreferApn = true;
23180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
23190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            canSetPreferApn = false;
23200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
23210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (canSetPreferApn && cursor.getCount() > 0) {
23230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int pos;
23240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cursor.moveToFirst();
23250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pos = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID));
23260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for(ApnSetting p:mAllApns) {
23270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (p.id == pos && p.canHandleType(mRequestedApnType)) {
23280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("getPreferredApn: X found apnSetting" + p);
23290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    cursor.close();
23300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return p;
23310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
23320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
23330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
23340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (cursor != null) {
23360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cursor.close();
23370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
23380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        log("getPreferredApn: X not found");
23400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return null;
23410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
23420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
23440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void handleMessage (Message msg) {
23450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("handleMessage msg=" + msg);
23460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!mPhone.mIsTheCurrentActivePhone || mIsDisposed) {
23480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            loge("handleMessage: Ignore GSM msgs since GSM phone is inactive");
23490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
23500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
23510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (msg.what) {
23530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DctConstants.EVENT_RECORDS_LOADED:
23540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                onRecordsLoaded();
23550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
23560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DctConstants.EVENT_DATA_CONNECTION_DETACHED:
23580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                onDataConnectionDetached();
23590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
23600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DctConstants.EVENT_DATA_CONNECTION_ATTACHED:
23620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                onDataConnectionAttached();
23630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
23640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DctConstants.EVENT_DATA_STATE_CHANGED:
23660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                onDataStateChanged((AsyncResult) msg.obj);
23670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
23680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DctConstants.EVENT_POLL_PDP:
23700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                onPollPdp();
23710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
23720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DctConstants.EVENT_DO_RECOVERY:
23740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                doRecovery();
23750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
23760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DctConstants.EVENT_APN_CHANGED:
23780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                onApnChanged();
23790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
23800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DctConstants.EVENT_PS_RESTRICT_ENABLED:
23820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                /**
23830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 * We don't need to explicitly to tear down the PDP context
23840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 * when PS restricted is enabled. The base band will deactive
23850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 * PDP context and notify us with PDP_CONTEXT_CHANGED.
23860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 * But we should stop the network polling and prevent reset PDP.
23870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 */
23880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
23890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                stopNetStatPoll();
23900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                stopDataStallAlarm();
23910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mIsPsRestricted = true;
23920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
23930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DctConstants.EVENT_PS_RESTRICT_DISABLED:
23950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                /**
23960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 * When PS restrict is removed, we need setup PDP connection if
23970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 * PDP connection is down.
23980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 */
23990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("EVENT_PS_RESTRICT_DISABLED " + mIsPsRestricted);
24000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mIsPsRestricted  = false;
24010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (isConnected()) {
24020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    startNetStatPoll();
24030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
24040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
24050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // TODO: Should all PDN states be checked to fail?
24060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (mState ==DctConstants.State.FAILED) {
24070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        cleanUpAllConnections(false, Phone.REASON_PS_RESTRICT_ENABLED);
24080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        resetAllRetryCounts();
24090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mReregisterOnReconnectFailure = false;
24100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
24110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    trySetupData(Phone.REASON_PS_RESTRICT_ENABLED, PhoneConstants.APN_TYPE_DEFAULT);
24120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
24130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
24140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DctConstants.EVENT_TRY_SETUP_DATA:
24150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (msg.obj instanceof ApnContext) {
24160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    onTrySetupData((ApnContext)msg.obj);
24170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (msg.obj instanceof String) {
24180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    onTrySetupData((String)msg.obj);
24190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
24200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    loge("EVENT_TRY_SETUP request w/o apnContext or String");
24210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
24220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
24230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
24240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case DctConstants.EVENT_CLEAN_UP_CONNECTION:
24250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                boolean tearDown = (msg.arg1 == 0) ? false : true;
24260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("EVENT_CLEAN_UP_CONNECTION tearDown=" + tearDown);
24270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (msg.obj instanceof ApnContext) {
24280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    cleanUpConnection(tearDown, (ApnContext)msg.obj);
24290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
24300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    loge("EVENT_CLEAN_UP_CONNECTION request w/o apn context");
24310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
24320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
24330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
24340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // handle the message in the super class DataConnectionTracker
24350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                super.handleMessage(msg);
24360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
24370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
24380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
24390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
24400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected int getApnProfileID(String apnType) {
24410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IMS)) {
24420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return RILConstants.DATA_PROFILE_IMS;
24430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_FOTA)) {
24440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return RILConstants.DATA_PROFILE_FOTA;
24450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_CBS)) {
24460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return RILConstants.DATA_PROFILE_CBS;
24470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
24480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return RILConstants.DATA_PROFILE_DEFAULT;
24490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
24500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
24510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
24520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int getCellLocationId() {
24530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int cid = -1;
24540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CellLocation loc = mPhone.getCellLocation();
24550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
24560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (loc != null) {
24570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (loc instanceof GsmCellLocation) {
24580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cid = ((GsmCellLocation)loc).getCid();
24590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (loc instanceof CdmaCellLocation) {
24600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cid = ((CdmaCellLocation)loc).getBaseStationId();
24610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
24620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
24630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return cid;
24640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
24650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
24660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
2467e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected void onUpdateIcc() {
2468e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        if (mUiccController == null ) {
2469e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            return;
2470e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        }
2471e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
2472e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        IccRecords newIccRecords = mUiccController.getIccRecords(UiccController.APP_FAM_3GPP);
2473e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
2474e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        IccRecords r = mIccRecords.get();
2475e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        if (r != newIccRecords) {
2476e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            if (r != null) {
2477e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                log("Removing stale icc objects.");
2478e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                r.unregisterForRecordsLoaded(this);
2479e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                mIccRecords.set(null);
2480e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            }
2481e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            if (newIccRecords != null) {
2482e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                log("New records found");
2483e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                mIccRecords.set(newIccRecords);
2484e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                newIccRecords.registerForRecordsLoaded(
2485e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                        this, DctConstants.EVENT_RECORDS_LOADED, null);
2486e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            }
2487e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        }
2488e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    }
2489e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
2490e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    @Override
24910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void log(String s) {
2492ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville        Rlog.d(LOG_TAG, "[GsmDCT] "+ s);
24930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
24940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
24950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
24960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void loge(String s) {
2497ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville        Rlog.e(LOG_TAG, "[GsmDCT] " + s);
24980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
24990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
25000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
25010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
25020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println("GsmDataConnectionTracker extends:");
25030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        super.dump(fd, pw, args);
25040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mReregisterOnReconnectFailure=" + mReregisterOnReconnectFailure);
25050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" canSetPreferApn=" + canSetPreferApn);
25060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mApnObserver=" + mApnObserver);
25070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" getOverallState=" + getOverallState());
250827814a2e735c0221935d46654fb00ff3ec2c45eaWink Saville        pw.println(" mDataConnectionAsyncChannels=%s\n" + mDataConnectionAsyncChannels);
25090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
25100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
2511