DcTracker.java revision 1f2a2323572b2f3ab18234726cc1b048c670fbab
1c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/*
2c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Copyright (C) 2006 The Android Open Source Project
3c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
4c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Licensed under the Apache License, Version 2.0 (the "License");
5c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * you may not use this file except in compliance with the License.
6c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * You may obtain a copy of the License at
7c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
8c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *      http://www.apache.org/licenses/LICENSE-2.0
9c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
10c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Unless required by applicable law or agreed to in writing, software
11c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * distributed under the License is distributed on an "AS IS" BASIS,
12c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * See the License for the specific language governing permissions and
14c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * limitations under the License.
15c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
16c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
174918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savillepackage com.android.internal.telephony.dataconnection;
18c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
19cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kallaimport android.app.AlarmManager;
20c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.app.PendingIntent;
21c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.ContentResolver;
22cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.content.ContentValues;
23c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Context;
24c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Intent;
25c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.IntentFilter;
26cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.content.res.Resources;
27c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.database.ContentObserver;
28cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.database.Cursor;
29cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.ConnectivityManager;
30c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.net.LinkCapabilities;
31c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.net.LinkProperties;
32cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.NetworkConfig;
33cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.NetworkUtils;
34cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.ProxyProperties;
35cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.Uri;
36c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.AsyncResult;
37c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Message;
381f2a2323572b2f3ab18234726cc1b048c670fbabRobert Greenwaltimport android.os.Messenger;
39c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemClock;
40c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemProperties;
41c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.provider.Settings;
42cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.provider.Telephony;
43cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.CellLocation;
44c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.telephony.ServiceState;
45c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.telephony.TelephonyManager;
46cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.cdma.CdmaCellLocation;
47cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.gsm.GsmCellLocation;
48c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.text.TextUtils;
49cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kallaimport android.util.EventLog;
5099c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Savilleimport android.telephony.Rlog;
51c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
524918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savilleimport com.android.internal.telephony.Phone;
534918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savilleimport com.android.internal.telephony.PhoneBase;
54cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.DctConstants;
55cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.EventLogTags;
56cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.gsm.GSMPhone;
574918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savilleimport com.android.internal.telephony.PhoneConstants;
58cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.RILConstants;
59d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccRecords;
60bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenkaimport com.android.internal.telephony.uicc.UiccController;
61c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.util.AsyncChannel;
62c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
63c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.io.FileDescriptor;
64c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.io.PrintWriter;
65c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.ArrayList;
66c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.HashMap;
67c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
68c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/**
69c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * {@hide}
70c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
71454b1dfd508844b42eb775e4ab2359be74d3672bWink Savillepublic final class DcTracker extends DcTrackerBase {
72cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected final String LOG_TAG = "DCT";
73c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
74b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla    /**
75cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Handles changes to the APN db.
76b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla     */
77cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private class ApnChangeObserver extends ContentObserver {
78cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public ApnChangeObserver () {
79cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            super(mDataConnectionTracker);
80cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
81c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
82cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
83cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public void onChange(boolean selfChange) {
84cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            sendMessage(obtainMessage(DctConstants.EVENT_APN_CHANGED));
85cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
86cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
87c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
88cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Instance Variables
89c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
90cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean mReregisterOnReconnectFailure = false;
91c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
92c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
93cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Constants
94c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
95ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    // Used by puppetmaster/*/radio_stress.py
96ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private static final String PUPPET_MASTER_RADIO_STRESS_TEST = "gsm.defaultpdpcontext.active";
97c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
98ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private static final int POLL_PDP_MILLIS = 5 * 1000;
99c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
100cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final Uri PREFERAPN_NO_UPDATE_URI =
101cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        Uri.parse("content://telephony/carriers/preferapn_no_update");
102cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final String APN_ID = "apn_id";
103cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
104ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private boolean mCanSetPreferApn = false;
105c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
106cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** Watches for changes to the APN db. */
107cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ApnChangeObserver mApnObserver;
108cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
109cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Constructor
110cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
111454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    public DcTracker(PhoneBase p) {
112cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        super(p);
113cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("GsmDCT.constructor");
11422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        p.mCi.registerForAvailable (this, DctConstants.EVENT_RADIO_AVAILABLE, null);
11522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        p.mCi.registerForOffOrNotAvailable(this, DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE,
116cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                null);
11722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        p.mCi.registerForDataNetworkStateChanged (this, DctConstants.EVENT_DATA_STATE_CHANGED,
118cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                null);
119cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        p.getCallTracker().registerForVoiceCallEnded (this, DctConstants.EVENT_VOICE_CALL_ENDED,
120cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                null);
121cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        p.getCallTracker().registerForVoiceCallStarted (this, DctConstants.EVENT_VOICE_CALL_STARTED,
122cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                null);
123cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        p.getServiceStateTracker().registerForDataConnectionAttached(this,
124cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null);
125cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        p.getServiceStateTracker().registerForDataConnectionDetached(this,
126cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                DctConstants.EVENT_DATA_CONNECTION_DETACHED, null);
127cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        p.getServiceStateTracker().registerForRoamingOn(this, DctConstants.EVENT_ROAMING_ON, null);
128cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        p.getServiceStateTracker().registerForRoamingOff(this, DctConstants.EVENT_ROAMING_OFF,
129cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                null);
130cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        p.getServiceStateTracker().registerForPsRestrictedEnabled(this,
131cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                DctConstants.EVENT_PS_RESTRICT_ENABLED, null);
132cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        p.getServiceStateTracker().registerForPsRestrictedDisabled(this,
133cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                DctConstants.EVENT_PS_RESTRICT_DISABLED, null);
134cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
135cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mDataConnectionTracker = this;
136cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
137cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mApnObserver = new ApnChangeObserver();
138cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        p.getContext().getContentResolver().registerContentObserver(
139cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                Telephony.Carriers.CONTENT_URI, true, mApnObserver);
140cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
141cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        initApnContextsAndDataConnection();
1421f2a2323572b2f3ab18234726cc1b048c670fbabRobert Greenwalt
1431f2a2323572b2f3ab18234726cc1b048c670fbabRobert Greenwalt        ConnectivityManager cm = (ConnectivityManager)p.getContext().getSystemService(
1441f2a2323572b2f3ab18234726cc1b048c670fbabRobert Greenwalt                Context.CONNECTIVITY_SERVICE);
1451f2a2323572b2f3ab18234726cc1b048c670fbabRobert Greenwalt        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE, new Messenger(this));
1461f2a2323572b2f3ab18234726cc1b048c670fbabRobert Greenwalt        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE_MMS, new Messenger(this));
1471f2a2323572b2f3ab18234726cc1b048c670fbabRobert Greenwalt        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE_SUPL, new Messenger(this));
1481f2a2323572b2f3ab18234726cc1b048c670fbabRobert Greenwalt        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE_DUN, new Messenger(this));
1491f2a2323572b2f3ab18234726cc1b048c670fbabRobert Greenwalt        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE_HIPRI, new Messenger(this));
1501f2a2323572b2f3ab18234726cc1b048c670fbabRobert Greenwalt        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE_FOTA, new Messenger(this));
1511f2a2323572b2f3ab18234726cc1b048c670fbabRobert Greenwalt        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE_IMS, new Messenger(this));
1521f2a2323572b2f3ab18234726cc1b048c670fbabRobert Greenwalt        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE_CBS, new Messenger(this));
153cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
154c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
155cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
156cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void dispose() {
157cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("GsmDCT.dispose");
158cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, null);
159cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
160cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        super.dispose();
161cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
162cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        //Unregister for all events
16322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.unregisterForAvailable(this);
16422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.unregisterForOffOrNotAvailable(this);
165cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
166cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (r != null) { r.unregisterForRecordsLoaded(this);}
16722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.unregisterForDataNetworkStateChanged(this);
168cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getCallTracker().unregisterForVoiceCallEnded(this);
169cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getCallTracker().unregisterForVoiceCallStarted(this);
170cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().unregisterForDataConnectionAttached(this);
171cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().unregisterForDataConnectionDetached(this);
172cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().unregisterForRoamingOn(this);
173cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().unregisterForRoamingOff(this);
174cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().unregisterForPsRestrictedEnabled(this);
175cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().unregisterForPsRestrictedDisabled(this);
176cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
17722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.getContext().getContentResolver().unregisterContentObserver(mApnObserver);
178cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mApnContexts.clear();
179cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
180cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        destroyDataConnections();
181cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
182cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
183cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
184cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isApnTypeActive(String type) {
185cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(type);
186cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) return false;
187cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
188ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        return (apnContext.getDcAc() != null);
189cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
190cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
191cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
192cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isDataPossible(String apnType) {
193cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
194cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
195cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
196cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
197cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean apnContextIsEnabled = apnContext.isEnabled();
198cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        DctConstants.State apnContextState = apnContext.getState();
199cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean apnTypePossible = !(apnContextIsEnabled &&
200cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                (apnContextState == DctConstants.State.FAILED));
201cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean dataAllowed = isDataAllowed();
202cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean possible = dataAllowed && apnTypePossible;
203cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
204ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (VDBG) {
205cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log(String.format("isDataPossible(%s): possible=%b isDataAllowed=%b " +
206cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    "apnTypePossible=%b apnContextisEnabled=%b apnContextState()=%s",
207cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnType, possible, dataAllowed, apnTypePossible,
208cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContextIsEnabled, apnContextState));
209cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
210cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return possible;
211cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
212cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
213cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
214cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void finalize() {
215cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(DBG) log("finalize");
216cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
217cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
218cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ApnContext addApnContext(String type) {
219cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = new ApnContext(type, LOG_TAG);
220cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setDependencyMet(false);
221cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mApnContexts.put(type, apnContext);
222cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return apnContext;
223cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
224cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
225cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void initApnContextsAndDataConnection() {
226cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean defaultEnabled = SystemProperties.getBoolean(DEFALUT_DATA_ON_BOOT_PROP, true);
227cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Load device network attributes from resources
228cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String[] networkConfigStrings = mPhone.getContext().getResources().getStringArray(
229cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                com.android.internal.R.array.networkAttributes);
230cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (String networkConfigString : networkConfigStrings) {
231cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            NetworkConfig networkConfig = new NetworkConfig(networkConfigString);
232cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ApnContext apnContext = null;
233cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
234cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            switch (networkConfig.type) {
235cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case ConnectivityManager.TYPE_MOBILE:
236cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext = addApnContext(PhoneConstants.APN_TYPE_DEFAULT);
237cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setEnabled(defaultEnabled);
238cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
239cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case ConnectivityManager.TYPE_MOBILE_MMS:
240cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext = addApnContext(PhoneConstants.APN_TYPE_MMS);
241cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
242cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case ConnectivityManager.TYPE_MOBILE_SUPL:
243cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext = addApnContext(PhoneConstants.APN_TYPE_SUPL);
244cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
245cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case ConnectivityManager.TYPE_MOBILE_DUN:
246cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext = addApnContext(PhoneConstants.APN_TYPE_DUN);
247cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
248cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case ConnectivityManager.TYPE_MOBILE_HIPRI:
249cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext = addApnContext(PhoneConstants.APN_TYPE_HIPRI);
250cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ApnContext defaultContext = mApnContexts.get(PhoneConstants.APN_TYPE_DEFAULT);
251cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (defaultContext != null) {
252cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    applyNewState(apnContext, apnContext.isEnabled(),
253cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            defaultContext.getDependencyMet());
254cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
255cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // the default will set the hipri dep-met when it is created
256c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
257cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                continue;
258cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case ConnectivityManager.TYPE_MOBILE_FOTA:
259cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext = addApnContext(PhoneConstants.APN_TYPE_FOTA);
260cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
261cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case ConnectivityManager.TYPE_MOBILE_IMS:
262cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext = addApnContext(PhoneConstants.APN_TYPE_IMS);
263cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
264cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case ConnectivityManager.TYPE_MOBILE_CBS:
265cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext = addApnContext(PhoneConstants.APN_TYPE_CBS);
266cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
267cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            default:
268cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // skip unknown types
269cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                continue;
270cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
271cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext != null) {
272cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // set the prop, but also apply the newly set enabled and dependency values
273cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onSetDependencyMet(apnContext.getApnType(), networkConfig.dependencyMet);
274c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
275c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
276cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
277c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
278cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
279cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public LinkProperties getLinkProperties(String apnType) {
280cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
281cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
282454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = apnContext.getDcAc();
283cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac != null) {
284cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("return link properites for " + apnType);
285cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return dcac.getLinkPropertiesSync();
286cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
287cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
288cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("return new LinkProperties");
289cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return new LinkProperties();
290cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
291cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
292cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
293cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public LinkCapabilities getLinkCapabilities(String apnType) {
294cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
295cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext!=null) {
296454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dataConnectionAc = apnContext.getDcAc();
297cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dataConnectionAc != null) {
298cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("get active pdp is not null, return link Capabilities for " + apnType);
299cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return dataConnectionAc.getLinkCapabilitiesSync();
300cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
301cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
302cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("return new LinkCapabilities");
303cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return new LinkCapabilities();
304cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
305cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
306cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
307cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return all active apn types
308cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public String[] getActiveApnTypes() {
309cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("get all active apn types");
310cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ArrayList<String> result = new ArrayList<String>();
311cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
312cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
313cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.isReady()) {
314cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                result.add(apnContext.getApnType());
315cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
316cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
317c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
318cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result.toArray(new String[0]);
319cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
320cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
321cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
322cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return active apn of specific apn type
323cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public String getActiveApnString(String apnType) {
324ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (VDBG) log( "get active apn string for type:" + apnType);
325cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
326cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
327cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ApnSetting apnSetting = apnContext.getApnSetting();
328cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnSetting != null) {
329cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return apnSetting.apn;
330cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
331cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
332cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
333cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
334cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
335cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
336cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isApnTypeEnabled(String apnType) {
337cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
338cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
339cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
340cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
341cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return apnContext.isEnabled();
342cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
343cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
344cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
345cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void setState(DctConstants.State s) {
346cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setState should not be used in GSM" + s);
347cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
348cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
349cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return state of specific apn type
350cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
351cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public DctConstants.State getState(String apnType) {
352cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
353cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
354cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return apnContext.getState();
355c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
356cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return DctConstants.State.FAILED;
357cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
358c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
359cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return state of overall
360cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
361cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public DctConstants.State getOverallState() {
362cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isConnecting = false;
363cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isFailed = true; // All enabled Apns should be FAILED.
364cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isAnyEnabled = false;
365cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
366cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
367cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.isEnabled()) {
368cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                isAnyEnabled = true;
369cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                switch (apnContext.getState()) {
370cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case CONNECTED:
371cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case DISCONNECTING:
372cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("overall state is CONNECTED");
373cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return DctConstants.State.CONNECTED;
374ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                case RETRYING:
375cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case CONNECTING:
376cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isConnecting = true;
377cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isFailed = false;
378cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
379cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case IDLE:
380cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case SCANNING:
381cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isFailed = false;
382cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
383cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                default:
384cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isAnyEnabled = true;
385cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
386cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
387cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
388c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
389c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
390cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (!isAnyEnabled) { // Nothing enabled. return IDLE.
391cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log( "overall state is IDLE");
392cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.IDLE;
393c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
394c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
395cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnecting) {
396cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log( "overall state is CONNECTING");
397cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.CONNECTING;
398cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (!isFailed) {
399cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log( "overall state is IDLE");
400cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.IDLE;
401cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
402cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log( "overall state is FAILED");
403cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.FAILED;
404c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
405c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
406c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
407c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
408cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Ensure that we are connected to an APN of the specified type.
409c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
410cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param apnType the APN type
411cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return Success is indicated by {@code PhoneConstants.APN_ALREADY_ACTIVE} or
412cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *         {@code PhoneConstants.APN_REQUEST_STARTED}. In the latter case, a
413cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *         broadcast will be sent by the ConnectivityManager when a
414cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *         connection to the APN has been established.
415c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
416cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
417cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public synchronized int enableApnType(String apnType) {
418cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
419cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null || !isApnTypeAvailable(apnType)) {
420cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("enableApnType: " + apnType + " is type not available");
421cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return PhoneConstants.APN_TYPE_NOT_AVAILABLE;
422c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
423c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
424cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // If already active, return
425cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("enableApnType: " + apnType + " mState(" + apnContext.getState() + ")");
426c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
427cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext.getState() == DctConstants.State.CONNECTED) {
428cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("enableApnType: return APN_ALREADY_ACTIVE");
429cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return PhoneConstants.APN_ALREADY_ACTIVE;
430c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
431cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        setEnabled(apnTypeToId(apnType), true);
432cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
433cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("enableApnType: new apn request for type " + apnType +
434cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    " return APN_REQUEST_STARTED");
435cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
436cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return PhoneConstants.APN_REQUEST_STARTED;
437cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
438c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
439cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
440cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public synchronized int disableApnType(String type) {
441cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("disableApnType:" + type);
442cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(type);
443cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
444cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
445cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            setEnabled(apnTypeToId(type), false);
446cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.getState() != DctConstants.State.IDLE && apnContext.getState()
447cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    != DctConstants.State.FAILED) {
448cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("diableApnType: return APN_REQUEST_STARTED");
449cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return PhoneConstants.APN_REQUEST_STARTED;
450cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
451cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("disableApnType: return APN_ALREADY_INACTIVE");
452cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return PhoneConstants.APN_ALREADY_INACTIVE;
453cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
454cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
455cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
456cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
457cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("disableApnType: no apn context was found, return APN_REQUEST_FAILED");
458cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
459cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return PhoneConstants.APN_REQUEST_FAILED;
460c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
461cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
462c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
463cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
464cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean isApnTypeAvailable(String type) {
465cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (type.equals(PhoneConstants.APN_TYPE_DUN) && fetchDunApn() != null) {
466cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return true;
467c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
468c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
469ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings != null) {
470ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for (ApnSetting apn : mAllApnSettings) {
471cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn.canHandleType(type)) {
472cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return true;
473cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
474cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
475c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
476cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return false;
477c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
478c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
479cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
480cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Report on whether data connectivity is enabled for any APN.
481cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return {@code false} if data connectivity has been explicitly disabled,
482cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * {@code true} otherwise.
483cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
484cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
485cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean getAnyDataEnabled() {
486cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        synchronized (mDataEnabledLock) {
487cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!(mInternalDataEnabled && mUserDataEnabled && sPolicyDataEnabled)) return false;
488cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            for (ApnContext apnContext : mApnContexts.values()) {
489cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Make sure we don't have a context that is going down
490cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // and is explicitly disabled.
491cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (isDataAllowed(apnContext)) {
492cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return true;
493cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
494cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
495cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
496c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
497c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
498c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
499cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean isDataAllowed(ApnContext apnContext) {
500cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return apnContext.isReady() && isDataAllowed();
501c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
502c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
503cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //****** Called from ServiceStateTracker
504c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
505cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Invoked when ServiceStateTracker observes a transition from GPRS
506cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * attach to detach.
507c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
508cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onDataConnectionDetached() {
509cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        /*
510cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * We presently believe it is unnecessary to tear down the PDP context
511cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * when GPRS detaches, but we should stop the network polling.
512cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         */
513cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log ("onDataConnectionDetached: stop polling and notify detached");
514cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopNetStatPoll();
515cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopDataStallAlarm();
516cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyDataConnection(Phone.REASON_DATA_DETACHED);
517cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
518c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
519cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onDataConnectionAttached() {
520cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onDataConnectionAttached");
521cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getOverallState() == DctConstants.State.CONNECTED) {
522cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onDataConnectionAttached: start polling notify attached");
523cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            startNetStatPoll();
524cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
525cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_DATA_ATTACHED);
526cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
527cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // update APN availability so that APN can be enabled.
528cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_DATA_ATTACHED);
529cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
530cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mAutoAttachOnCreation = true;
531ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(Phone.REASON_DATA_ATTACHED);
532cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
533c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
534cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
535cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean isDataAllowed() {
536cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        final boolean internalDataEnabled;
537cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        synchronized (mDataEnabledLock) {
538cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            internalDataEnabled = mInternalDataEnabled;
539cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
540cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
541cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int gprsState = mPhone.getServiceStateTracker().getCurrentDataConnectionState();
542cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
543cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
544cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean recordsLoaded = (r != null) ? r.getRecordsLoaded() : false;
545cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
546cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean allowed =
547cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    (gprsState == ServiceState.STATE_IN_SERVICE || mAutoAttachOnCreation) &&
548cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    recordsLoaded &&
549cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    (mPhone.getState() == PhoneConstants.State.IDLE ||
550cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                     mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) &&
551cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    internalDataEnabled &&
552cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    (!mPhone.getServiceState().getRoaming() || getDataOnRoamingEnabled()) &&
553cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    !mIsPsRestricted &&
554cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    desiredPowerState;
555cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (!allowed && DBG) {
556cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            String reason = "";
557cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!((gprsState == ServiceState.STATE_IN_SERVICE) || mAutoAttachOnCreation)) {
558cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                reason += " - gprs= " + gprsState;
559cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
560cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!recordsLoaded) reason += " - SIM not loaded";
561cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPhone.getState() != PhoneConstants.State.IDLE &&
562cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
563cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                reason += " - PhoneState= " + mPhone.getState();
564cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                reason += " - Concurrent voice and data not allowed";
565cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
566cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!internalDataEnabled) reason += " - mInternalDataEnabled= false";
567cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPhone.getServiceState().getRoaming() && !getDataOnRoamingEnabled()) {
568cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                reason += " - Roaming and data roaming not enabled";
569cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
570cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mIsPsRestricted) reason += " - mIsPsRestricted= true";
571cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!desiredPowerState) reason += " - desiredPowerState= false";
572cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("isDataAllowed: not allowed due to" + reason);
573c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
574cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return allowed;
575cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
576c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
577ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void setupDataOnConnectableApns(String reason) {
578cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
579cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.getState() == DctConstants.State.FAILED) {
580cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setState(DctConstants.State.IDLE);
581cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
582ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.isConnectable()) {
583ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                log("setupDataOnConnectableApns: isConnectable() call trySetupData");
584ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setReason(reason);
585ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                trySetupData(apnContext);
586cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
587cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
588c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
589c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
590cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean trySetupData(String reason, String type) {
591cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
592cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("trySetupData: " + type + " due to " + (reason == null ? "(unspecified)" : reason)
593cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " isPsRestricted=" + mIsPsRestricted);
594cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
595cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
596cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (type == null) {
597cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            type = PhoneConstants.APN_TYPE_DEFAULT;
598c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
599c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
600cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(type);
601cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
602cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null ){
603cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("trySetupData new apn context for type:" + type);
604cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext = new ApnContext(type, LOG_TAG);
605cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mApnContexts.put(type, apnContext);
606cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
607cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setReason(reason);
608cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
609cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return trySetupData(apnContext);
610c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
611c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
612cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean trySetupData(ApnContext apnContext) {
613cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
614cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("trySetupData for type:" + apnContext.getApnType() +
615cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    " due to " + apnContext.getReason() + " apnContext=" + apnContext);
616cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("trySetupData with mIsPsRestricted=" + mIsPsRestricted);
617cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
618cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
619cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
620cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
621cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
622cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setState(DctConstants.State.CONNECTED);
623cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
624cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
625cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("trySetupData: X We're on the simulator; assuming connected retValue=true");
626cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return true;
627cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
628cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
629cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
630cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
631ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnContext.isConnectable() &&
632cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                isDataAllowed(apnContext) && getAnyDataEnabled() && !isEmergency()) {
633ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getState() == DctConstants.State.FAILED) {
634ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) log("trySetupData: make a FAILED ApnContext IDLE so its reusable");
635ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setState(DctConstants.State.IDLE);
636ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
637cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.getState() == DctConstants.State.IDLE) {
638cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ArrayList<ApnSetting> waitingApns = buildWaitingApns(apnContext.getApnType());
639cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (waitingApns.isEmpty()) {
640ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    notifyNoData(DcFailCause.MISSING_UNKNOWN_APN, apnContext);
641cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    notifyOffApnsOfAvailability(apnContext.getReason());
642cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("trySetupData: X No APN found retValue=false");
643cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return false;
644cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
645cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setWaitingApns(waitingApns);
646cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) {
647ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        log ("trySetupData: Create from mAllApnSettings : "
648ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                    + apnListToString(mAllApnSettings));
649cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
650cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
651cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
652cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
653cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
654cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("trySetupData: call setupData, waitingApns : "
655cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        + apnListToString(apnContext.getWaitingApns()));
656cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
657cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            boolean retValue = setupData(apnContext);
658cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(apnContext.getReason());
659cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
660cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("trySetupData: X retValue=" + retValue);
661cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return retValue;
662cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
663cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
664ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    && apnContext.isConnectable()) {
665cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
666ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
667cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(apnContext.getReason());
668cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log ("trySetupData: X apnContext not 'ready' retValue=false");
669cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
670cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
671c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
672c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
673cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
674cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Disabled apn's still need avail/unavail notificiations - send them out
675cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void notifyOffApnsOfAvailability(String reason) {
676cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
677cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!apnContext.isReady()) {
678ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) log("notifyOffApnOfAvailability type:" + apnContext.getApnType());
679cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
680cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                            apnContext.getApnType(),
681cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                            PhoneConstants.DataState.DISCONNECTED);
682cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
683ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) {
684cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("notifyOffApnsOfAvailability skipped apn due to isReady==true: " +
685cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            apnContext.toString());
686cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
687c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
688c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
689c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
690c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
691cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
692cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * If tearDown is true, this only tears down a CONNECTED session. Presently,
693cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * there is no mechanism for abandoning an CONNECTING session,
694cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * but would likely involve cancelling pending async requests or
695cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * setting a flag or new state to ignore them when they came in
696cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param tearDown true if the underlying DataConnection should be
697cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * disconnected.
698cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param reason reason for the clean up.
699cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
700cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void cleanUpAllConnections(boolean tearDown, String reason) {
701cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("cleanUpAllConnections: tearDown=" + tearDown + " reason=" + reason);
702cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
703cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
704cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setReason(reason);
705cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpConnection(tearDown, apnContext);
706c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
707cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
708cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopNetStatPoll();
709cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopDataStallAlarm();
710cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
711cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: Do we need mRequestedApnType?
712cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
713cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
714cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
715cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
716cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Cleanup all connections.
717cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
718cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * TODO: Cleanup only a specified connection passed as a parameter.
719cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *       Also, make sure when you clean up a conn, if it is last apply
720cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *       logic as though it is cleanupAllConnections
721cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
722cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param cause for the clean up.
723cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
724cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
725cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
726cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onCleanUpAllConnections(String cause) {
727cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, cause);
728cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
729cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
730cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void cleanUpConnection(boolean tearDown, ApnContext apnContext) {
731cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
732cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
733cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("cleanUpConnection: apn context is null");
734cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
735cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
736cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
737454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac = apnContext.getDcAc();
738cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
739cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("cleanUpConnection: E tearDown=" + tearDown + " reason=" + apnContext.getReason() +
740cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    " apnContext=" + apnContext);
741cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
742cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (tearDown) {
743cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.isDisconnected()) {
744cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // The request is tearDown and but ApnContext is not connected.
745cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // If apnContext is not enabled anymore, break the linkage to the DCAC/DC.
746cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setState(DctConstants.State.IDLE);
747cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (!apnContext.isReady()) {
748cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setDataConnectionAc(null);
749cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
750cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
751cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Connection is still there. Try to clean up.
752cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (dcac != null) {
753cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (apnContext.getState() != DctConstants.State.DISCONNECTING) {
754cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        boolean disconnectAll = false;
755cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (PhoneConstants.APN_TYPE_DUN.equals(apnContext.getApnType())) {
756cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            ApnSetting dunSetting = fetchDunApn();
757cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            if (dunSetting != null &&
758cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                    dunSetting.equals(apnContext.getApnSetting())) {
759cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                if (DBG) log("tearing down dedicated DUN connection");
760cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // we need to tear it down - we brought it up just for dun and
761cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // other people are camped on it and now dun is done.  We need
762cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // to stop using it and let the normal apn list get used to find
763cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // connections for the remaining desired connections
764cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                disconnectAll = true;
765cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            }
766cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
767cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (DBG) {
768cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            log("cleanUpConnection: tearing down" + (disconnectAll ? " all" :""));
769cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
770cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        Message msg = obtainMessage(DctConstants.EVENT_DISCONNECT_DONE, apnContext);
771cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (disconnectAll) {
772ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            apnContext.getDcAc().tearDownAll(apnContext.getReason(), msg);
773cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        } else {
774ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            apnContext.getDcAc()
775cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                .tearDown(apnContext, apnContext.getReason(), msg);
776cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
777cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.setState(DctConstants.State.DISCONNECTING);
778cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
779cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
780cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // apn is connected but no reference to dcac.
781cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // Should not be happen, but reset the state in case.
782cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setState(DctConstants.State.IDLE);
783cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mPhone.notifyDataConnection(apnContext.getReason(),
784cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                                apnContext.getApnType());
785cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
786cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
787cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
788cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // force clean up the data connection.
789ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac != null) dcac.reqReset();
790cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setState(DctConstants.State.IDLE);
791cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
792cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setDataConnectionAc(null);
793cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
794cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
795ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // Make sure reconnection alarm is cleaned up if there is no ApnContext
796cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // associated to the connection.
797cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (dcac != null) {
798ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            cancelReconnectAlarm(apnContext);
799c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
800cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
801cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("cleanUpConnection: X tearDown=" + tearDown + " reason=" + apnContext.getReason() +
802ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    " apnContext=" + apnContext + " dcac=" + apnContext.getDcAc());
803cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
804cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
805c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
806cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
807ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Cancels the alarm associated with apnContext.
808cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
809ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * @param apnContext on which the alarm should be stopped.
810cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
811ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void cancelReconnectAlarm(ApnContext apnContext) {
812ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnContext == null) return;
813cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
814ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        PendingIntent intent = apnContext.getReconnectIntent();
815cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
816cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (intent != null) {
817cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                AlarmManager am =
818cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
819cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                am.cancel(intent);
820ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setReconnectIntent(null);
821cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
822c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
823c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
824cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
825cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param types comma delimited list of APN types
826cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return array of APN types
827cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
828cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private String[] parseTypes(String types) {
829c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String[] result;
830cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // If unset, set to DEFAULT.
831cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (types == null || types.equals("")) {
832c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            result = new String[1];
833cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result[0] = PhoneConstants.APN_TYPE_ALL;
834cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
835cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result = types.split(",");
836c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
837c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
838c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
839c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
840fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi   private boolean imsiMatches(String imsiDB, String imsiSIM) {
841fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        // Note: imsiDB value has digit number or 'x' character for seperating USIM information
842fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        // for MVNO operator. And then digit number is matched at same order and 'x' character
843fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        // could replace by any digit number.
844fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        // ex) if imsiDB inserted '310260x10xxxxxx' for GG Operator,
845fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        //     that means first 6 digits, 8th and 9th digit
846fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        //     should be set in USIM for GG Operator.
847fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        int len = imsiDB.length();
848fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        int idxCompare = 0;
849fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
850fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        if (len <= 0) return false;
851fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        if (len > imsiSIM.length()) return false;
852fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
853fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        for (int idx=0; idx<len; idx++) {
854fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            char c = imsiDB.charAt(idx);
855fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            if ((c == 'x') || (c == 'X') || (c == imsiSIM.charAt(idx))) {
856fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                continue;
857fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            } else {
858fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                return false;
859fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            }
860fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        }
861fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        return true;
862fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    }
863fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
864fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    private boolean mvnoMatches(IccRecords r, String mvno_type, String mvno_match_data) {
865fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        if (mvno_type.equalsIgnoreCase("spn")) {
866fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            if ((r.getServiceProviderName() != null) &&
867fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    r.getServiceProviderName().equalsIgnoreCase(mvno_match_data)) {
868fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                return true;
869fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            }
870fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        } else if (mvno_type.equalsIgnoreCase("imsi")) {
871fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            String imsiSIM = r.getIMSI();
872fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            if ((imsiSIM != null) && imsiMatches(mvno_match_data, imsiSIM)) {
873fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                return true;
874fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            }
875fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        } else if (mvno_type.equalsIgnoreCase("gid")) {
876fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            String gid1 = r.getGid1();
877fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            if ((gid1 != null) && gid1.substring(0,
878fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    mvno_match_data.length()).equalsIgnoreCase(mvno_match_data)) {
879fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                return true;
880fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            }
881fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        }
882fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        return false;
883fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    }
884fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
885fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    private ApnSetting makeApnSetting(Cursor cursor) {
886fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        String[] types = parseTypes(
887fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.TYPE)));
888fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        ApnSetting apn = new ApnSetting(
889fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID)),
890fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NUMERIC)),
891fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NAME)),
892fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN)),
893fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
894fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
895fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY))),
896fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PORT)),
897fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
898fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
899fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC))),
900fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
901fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
902fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY))),
903fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPORT)),
904fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)),
905fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)),
906fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.AUTH_TYPE)),
907fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                types,
908fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROTOCOL)),
909fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(
910fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        Telephony.Carriers.ROAMING_PROTOCOL)),
911fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(
912fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        Telephony.Carriers.CARRIER_ENABLED)) == 1,
913fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.BEARER)));
914fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        return apn;
915fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    }
916fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
917cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ArrayList<ApnSetting> createApnList(Cursor cursor) {
918cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ArrayList<ApnSetting> result = new ArrayList<ApnSetting>();
919fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        IccRecords r = mIccRecords.get();
920fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
921cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor.moveToFirst()) {
922fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            String mvnoType = null;
923fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            String mvnoMatchData = null;
924cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            do {
925fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                String cursorMvnoType = cursor.getString(
926fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_TYPE));
927fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                String cursorMvnoMatchData = cursor.getString(
928fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_MATCH_DATA));
929fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                if (mvnoType != null) {
930fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    if (mvnoType.equals(cursorMvnoType) &&
931fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                            mvnoMatchData.equals(cursorMvnoMatchData)) {
932fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        result.add(makeApnSetting(cursor));
933fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    }
934fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                } else {
935fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    // no mvno match yet
936fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    if (mvnoMatches(r, cursorMvnoType, cursorMvnoMatchData)) {
937fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        // first match - toss out non-mvno data
938fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        result.clear();
939fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        mvnoType = cursorMvnoType;
940fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        mvnoMatchData = cursorMvnoMatchData;
941fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        result.add(makeApnSetting(cursor));
942fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    } else {
943fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        // add only non-mvno data
944fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        if (cursorMvnoType.equals("")) {
945fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                            result.add(makeApnSetting(cursor));
946fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        }
947fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    }
948fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                }
949cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } while (cursor.moveToNext());
950cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
951cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createApnList: X result=" + result);
952c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
953c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
954c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
955454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private boolean dataConnectionNotInUse(DcAsyncChannel dcac) {
956ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("dataConnectionNotInUse: check if dcac is inuse dcac=" + dcac);
957cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
958ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getDcAc() == dcac) {
959cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("dataConnectionNotInUse: in use by apnContext=" + apnContext);
960cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
961cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
962cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
963cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: Fix retry handling so free DataConnections have empty apnlists.
964cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Probably move retry handling into DataConnections and reduce complexity
965cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // of DCT.
966cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("dataConnectionNotInUse: tearDownAll");
967ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        dcac.tearDownAll("No connection", null);
968cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("dataConnectionNotInUse: not in use return true");
969cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
970cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
971cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
972454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel findFreeDataConnection() {
973454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
974cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac.isInactiveSync() && dataConnectionNotInUse(dcac)) {
975cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
976cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("findFreeDataConnection: found free DataConnection=" +
977ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        " dcac=" + dcac);
978cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
979ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                return dcac;
980cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
981cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
982cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("findFreeDataConnection: NO free DataConnection");
983cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
984cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
985cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
986cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean setupData(ApnContext apnContext) {
987cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setupData: apnContext=" + apnContext);
988ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnSetting apnSetting;
989454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac;
990cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
991cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int profileId = getApnProfileID(apnContext.getApnType());
992ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnSetting = apnContext.getNextWaitingApn();
993ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnSetting == null) {
994cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("setupData: return for no apn found!");
995cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
996cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
997cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
998ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        dcac = checkForCompatibleConnectedApnContext(apnContext);
999ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (dcac != null) {
1000ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // Get the dcacApnSetting for the connection we want to share.
1001ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            ApnSetting dcacApnSetting = dcac.getApnSettingSync();
1002ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcacApnSetting != null) {
1003ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                // Setting is good, so use it.
1004ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnSetting = dcacApnSetting;
1005ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1006ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
1007ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (dcac == null) {
1008ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            dcac = findFreeDataConnection();
1009cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1010ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac == null) {
1011ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                dcac = createDataConnection();
1012cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1013cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1014ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac == null) {
1015ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) log("setupData: No free DataConnection and couldn't create one, WEIRD");
1016cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
1017cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1018cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1019ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("setupData: dcac=" + dcac + " apnSetting=" + apnSetting);
1020cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1021cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setDataConnectionAc(dcac);
1022ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setApnSetting(apnSetting);
1023cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setState(DctConstants.State.CONNECTING);
1024cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1025cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1026cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Message msg = obtainMessage();
1027cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        msg.what = DctConstants.EVENT_DATA_SETUP_COMPLETE;
1028cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        msg.obj = apnContext;
1029ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        dcac.bringUp(apnContext, getInitialMaxRetry(), profileId, msg);
1030cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1031cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setupData: initing!");
1032cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
1033cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1034cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1035c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1036cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Handles changes to the APN database.
1037c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1038cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onApnChanged() {
1039cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        DctConstants.State overallState = getOverallState();
1040cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isDisconnected = (overallState == DctConstants.State.IDLE ||
1041cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                overallState == DctConstants.State.FAILED);
1042cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1043cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone instanceof GSMPhone) {
1044cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // The "current" may no longer be valid.  MMS depends on this to send properly. TBD
1045cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ((GSMPhone)mPhone).updateCurrentCarrierInProvider();
1046cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1047cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1048cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: It'd be nice to only do this if the changed entrie(s)
1049cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // match the current operator.
1050cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onApnChanged: createAllApnList and cleanUpAllConnections");
1051cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        createAllApnList();
1052cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(!isDisconnected, Phone.REASON_APN_CHANGED);
1053cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isDisconnected) {
1054ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_APN_CHANGED);
1055c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1056c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1057c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1058c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1059cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param cid Connection id provided from RIL.
1060cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return DataConnectionAc associated with specified cid.
1061c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1062454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel findDataConnectionAcByCid(int cid) {
1063454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
1064cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac.getCidSync() == cid) {
1065cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return dcac;
1066cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1067c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1068cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
1069c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1070c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1071cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1072cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param ar is the result of RIL_REQUEST_DATA_CALL_LIST
1073cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * or RIL_UNSOL_DATA_CALL_LIST_CHANGED
1074cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1075cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onDataStateChanged (AsyncResult ar) {
1076ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ArrayList<DataCallResponse> dataCallStates;
1077cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1078cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onDataStateChanged(ar): E");
1079ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        dataCallStates = (ArrayList<DataCallResponse>)(ar.result);
1080c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1081cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (ar.exception != null) {
1082cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // This is probably "radio not available" or something
1083cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // of that sort. If so, the whole connection is going
1084cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // to come down soon anyway
1085cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onDataStateChanged(ar): exception; likely radio not available, ignore");
1086cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
1087cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1088ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("onDataStateChanged(ar): DataCallResponse size=" + dataCallStates.size());
1089cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1090cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Create a hash map to store the dataCallState of each DataConnectionAc
1091454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        HashMap<DataCallResponse, DcAsyncChannel> dataCallStateToDcac;
1092454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        dataCallStateToDcac = new HashMap<DataCallResponse, DcAsyncChannel>();
1093ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        for (DataCallResponse dataCallState : dataCallStates) {
1094454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = findDataConnectionAcByCid(dataCallState.cid);
1095cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1096cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac != null) dataCallStateToDcac.put(dataCallState, dcac);
1097cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1098cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1099ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // Check if we should start or stop polling, by looking
1100ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // for dormant and active connections.
1101ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        boolean isAnyDataCallDormant = false;
1102ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        boolean isAnyDataCallActive = false;
1103ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        for (DataCallResponse newState : dataCallStates) {
1104cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (newState.active == DATA_CONNECTION_ACTIVE_PH_LINK_UP) isAnyDataCallActive = true;
1105cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (newState.active == DATA_CONNECTION_ACTIVE_PH_LINK_DOWN) isAnyDataCallDormant = true;
1106cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1107cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1108cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isAnyDataCallDormant && !isAnyDataCallActive) {
1109cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // There is no way to indicate link activity per APN right now. So
1110cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Link Activity will be considered dormant only when all data calls
1111cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // are dormant.
1112cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // If a single data call is in dormant state and none of the data
1113cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // calls are active broadcast overall link state as dormant.
1114cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mActivity = DctConstants.Activity.DORMANT;
1115cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
1116cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("onDataStateChanged: Data Activity updated to DORMANT. stopNetStatePoll");
1117cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1118cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            stopNetStatPoll();
1119cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1120cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mActivity = DctConstants.Activity.NONE;
1121cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
1122cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("onDataStateChanged: Data Activity updated to NONE. " +
1123cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                         "isAnyDataCallActive = " + isAnyDataCallActive +
1124cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                         " isAnyDataCallDormant = " + isAnyDataCallDormant);
1125cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1126cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (isAnyDataCallActive) startNetStatPoll();
1127cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1128cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1129cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onDataStateChanged(ar): X");
1130cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1131cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1132cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void notifyDefaultData(ApnContext apnContext) {
1133cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
1134cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("notifyDefaultData: type=" + apnContext.getApnType()
1135cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                + ", reason:" + apnContext.getReason());
1136cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1137cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setState(DctConstants.State.CONNECTED);
1138cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // setState(DctConstants.State.CONNECTED);
1139cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1140cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        startNetStatPoll();
1141cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
1142cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1143cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1144cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // TODO: For multiple Active APNs not exactly sure how to do this.
1145c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
1146cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void gotoIdleAndNotifyDataConnection(String reason) {
1147cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("gotoIdleAndNotifyDataConnection: reason=" + reason);
1148cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyDataConnection(reason);
1149cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mActiveApn = null;
1150cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1151cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1152cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1153cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void restartRadio() {
1154cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("restartRadio: ************TURN OFF RADIO**************");
1155cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, Phone.REASON_RADIO_TURNED_OFF);
1156cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().powerOffRadioSafely(this);
1157cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        /* Note: no need to call setRadioPower(true).  Assuming the desired
1158cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * radio power state is still ON (as tracked by ServiceStateTracker),
1159cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * ServiceStateTracker will call setRadioPower when it receives the
1160cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * RADIO_STATE_CHANGED notification for the power off.  And if the
1161cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * desired power state has changed in the interim, we don't want to
1162cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * override it with an unconditional power on.
1163cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         */
1164cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1165cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int reset = Integer.parseInt(SystemProperties.get("net.ppp.reset-by-timeout", "0"));
1166cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        SystemProperties.set("net.ppp.reset-by-timeout", String.valueOf(reset+1));
1167cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1168cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1169cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1170cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Return true if data connection need to be setup after disconnected due to
1171cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * reason.
1172cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1173cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param reason the reason why data is disconnected
1174cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return true if try setup data connection is need for this reason
1175cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1176cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean retryAfterDisconnected(String reason) {
1177cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean retry = true;
1178cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1179cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) ) {
1180cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            retry = false;
1181cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1182cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return retry;
1183cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1184cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1185cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void startAlarmForReconnect(int delay, ApnContext apnContext) {
1186454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac = apnContext.getDcAc();
1187cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1188ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (dcac == null) {
1189cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // should not happen, but just in case.
1190cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("startAlarmForReconnect: null dcac or dc.");
1191cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
1192cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1193cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1194cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Intent intent = new Intent(INTENT_RECONNECT_ALARM + '.' +
1195ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                   dcac.getDataConnectionIdSync());
1196cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String reason = apnContext.getReason();
1197cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, reason);
1198cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String apnType = apnContext.getApnType();
1199cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, apnType);
1200cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1201ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        PendingIntent alarmIntent = PendingIntent.getBroadcast (mPhone.getContext(), 0,
1202ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        intent, PendingIntent.FLAG_UPDATE_CURRENT);
1203ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setReconnectIntent(alarmIntent);
1204ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1205ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                SystemClock.elapsedRealtime() + delay, alarmIntent);
1206ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
1207cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1208ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void startAlarmForRestartTrySetup(int delay, ApnContext apnContext) {
1209ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        Intent intent = new Intent(INTENT_RESTART_TRYSETUP_ALARM);
1210ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        String apnType = apnContext.getApnType();
1211ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        intent.putExtra(INTENT_RESTART_TRYSETUP_ALARM_EXTRA_TYPE, apnType);
1212cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1213cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        PendingIntent alarmIntent = PendingIntent.getBroadcast (mPhone.getContext(), 0,
1214cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                        intent, PendingIntent.FLAG_UPDATE_CURRENT);
1215ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setReconnectIntent(alarmIntent);
1216ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1217cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                SystemClock.elapsedRealtime() + delay, alarmIntent);
1218cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1219cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1220ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void notifyNoData(DcFailCause lastFailCauseCode,
1221cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                              ApnContext apnContext) {
1222cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log( "notifyNoData: type=" + apnContext.getApnType());
1223cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (lastFailCauseCode.isPermanentFail()
1224cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            && (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT))) {
1225cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
1226cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1227cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1228cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1229cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onRecordsLoaded() {
1230cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onRecordsLoaded: createAllApnList");
1231cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        createAllApnList();
123222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPhone.mCi.getRadioState().isOn()) {
1233cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRecordsLoaded: notifying data availability");
1234cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_SIM_LOADED);
1235cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1236ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(Phone.REASON_SIM_LOADED);
1237cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1238cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1239cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1240cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onSetDependencyMet(String apnType, boolean met) {
1241cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // don't allow users to tweak hipri to work around default dependency not met
1242cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_HIPRI.equals(apnType)) return;
1243cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1244cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1245cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
1246cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onSetDependencyMet: ApnContext not found in onSetDependencyMet(" +
1247cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnType + ", " + met + ")");
1248cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
1249cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1250cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        applyNewState(apnContext, apnContext.isEnabled(), met);
1251cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_DEFAULT.equals(apnType)) {
1252cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // tie actions on default to similar actions on HIPRI regarding dependencyMet
1253cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext = mApnContexts.get(PhoneConstants.APN_TYPE_HIPRI);
1254cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext != null) applyNewState(apnContext, apnContext.isEnabled(), met);
1255cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1256cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1257c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1258cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void applyNewState(ApnContext apnContext, boolean enabled, boolean met) {
1259cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean cleanup = false;
1260cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean trySetup = false;
1261cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
1262cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("applyNewState(" + apnContext.getApnType() + ", " + enabled +
1263cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    "(" + apnContext.isEnabled() + "), " + met + "(" +
1264cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.getDependencyMet() +"))");
1265cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1266cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext.isReady()) {
1267cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (enabled && met) return;
1268cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!enabled) {
1269cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setReason(Phone.REASON_DATA_DISABLED);
1270cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1271cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_UNMET);
1272cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1273cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanup = true;
1274cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1275cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (enabled && met) {
1276cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apnContext.isEnabled()) {
1277cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_MET);
1278cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1279cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setReason(Phone.REASON_DATA_ENABLED);
1280c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1281cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apnContext.getState() == DctConstants.State.FAILED) {
1282cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setState(DctConstants.State.IDLE);
1283cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1284cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                trySetup = true;
1285cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1286cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1287cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setEnabled(enabled);
1288cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setDependencyMet(met);
1289cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cleanup) cleanUpConnection(true, apnContext);
1290cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (trySetup) trySetupData(apnContext);
1291cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1292c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1293454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel checkForCompatibleConnectedApnContext(ApnContext apnContext) {
1294cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String apnType = apnContext.getApnType();
1295cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnSetting dunSetting = null;
1296cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1297cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_DUN.equals(apnType)) {
1298cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            dunSetting = fetchDunApn();
1299cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1300ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) {
1301ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            log("checkForCompatibleConnectedApnContext: apnContext=" + apnContext );
1302ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
1303cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1304454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel potentialDcac = null;
1305ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnContext potentialApnCtx = null;
1306ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        for (ApnContext curApnCtx : mApnContexts.values()) {
1307454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel curDcac = curApnCtx.getDcAc();
1308ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (curDcac != null) {
1309ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                ApnSetting apnSetting = curApnCtx.getApnSetting();
1310cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (dunSetting != null) {
1311cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (dunSetting.equals(apnSetting)) {
1312ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        switch (curApnCtx.getState()) {
1313cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            case CONNECTED:
1314cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                if (DBG) {
1315ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                    log("checkForCompatibleConnectedApnContext:"
1316ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                            + " found dun conn=" + curDcac
1317ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                            + " curApnCtx=" + curApnCtx);
1318cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                }
1319ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                return curDcac;
1320ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            case RETRYING:
1321cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            case CONNECTING:
1322ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                potentialDcac = curDcac;
1323ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                potentialApnCtx = curApnCtx;
1324cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            default:
1325cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // Not connected, potential unchanged
1326cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                break;
1327cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
1328cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1329cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else if (apnSetting != null && apnSetting.canHandleType(apnType)) {
1330ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    switch (curApnCtx.getState()) {
1331cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        case CONNECTED:
1332cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            if (DBG) {
1333ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                log("checkForCompatibleConnectedApnContext:"
1334ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        + " found canHandle conn=" + curDcac
1335ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        + " curApnCtx=" + curApnCtx);
1336cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            }
1337ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            return curDcac;
1338ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        case RETRYING:
1339cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        case CONNECTING:
1340ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            potentialDcac = curDcac;
1341ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            potentialApnCtx = curApnCtx;
1342cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        default:
1343cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            // Not connected, potential unchanged
1344cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            break;
1345cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1346cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1347ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            } else {
1348ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) {
1349ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    log("checkForCompatibleConnectedApnContext: not conn curApnCtx=" + curApnCtx);
1350ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                }
1351cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1352cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1353ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (potentialDcac != null) {
1354cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
1355ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                log("checkForCompatibleConnectedApnContext: found potential conn=" + potentialDcac
1356ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        + " curApnCtx=" + potentialApnCtx);
1357cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1358ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            return potentialDcac;
1359cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1360c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1361ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("checkForCompatibleConnectedApnContext: NO conn apnContext=" + apnContext);
1362cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
1363cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1364c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1365cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1366cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onEnableApn(int apnId, int enabled) {
1367cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnIdToType(apnId));
1368cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
1369cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onEnableApn(" + apnId + ", " + enabled + "): NO ApnContext");
1370cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
1371cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1372cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO change our retry manager to use the appropriate numbers for the new APN
1373cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onEnableApn: apnContext=" + apnContext + " call applyNewState");
1374cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        applyNewState(apnContext, enabled == DctConstants.ENABLED, apnContext.getDependencyMet());
1375cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1376c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1377cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1378cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // TODO: We shouldnt need this.
1379cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean onTrySetupData(String reason) {
1380cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onTrySetupData: reason=" + reason);
1381ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(reason);
1382cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
1383cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1384c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1385cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean onTrySetupData(ApnContext apnContext) {
1386cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onTrySetupData: apnContext=" + apnContext);
1387cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return trySetupData(apnContext);
1388cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1389c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1390cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1391cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onRoamingOff() {
1392cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onRoamingOff");
1393c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1394cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mUserDataEnabled == false) return;
1395c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1396cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getDataOnRoamingEnabled() == false) {
1397cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_OFF);
1398ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_ROAMING_OFF);
1399cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1400cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_ROAMING_OFF);
1401cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1402cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1403cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1404cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1405cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onRoamingOn() {
1406cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mUserDataEnabled == false) return;
1407cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1408cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getDataOnRoamingEnabled()) {
1409cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRoamingOn: setup data on roaming");
1410ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_ROAMING_ON);
1411cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_ROAMING_ON);
1412cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1413cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRoamingOn: Tear down data connection on roaming.");
1414cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpAllConnections(true, Phone.REASON_ROAMING_ON);
1415cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
1416cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1417cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1418cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1419cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1420cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onRadioAvailable() {
1421cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onRadioAvailable");
1422cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
1423cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
1424cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
1425cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // setState(DctConstants.State.CONNECTED);
1426cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(null);
1427cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1428cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("onRadioAvailable: We're on the simulator; assuming data is connected");
1429cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1430cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1431cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
1432cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (r != null && r.getRecordsLoaded()) {
1433cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(null);
1434cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1435cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1436cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getOverallState() != DctConstants.State.IDLE) {
1437cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpConnection(true, null);
1438cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1439cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1440cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1441cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1442cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onRadioOffOrNotAvailable() {
1443cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Make sure our reconnect delay starts at the initial value
1444cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // next time the radio comes on
1445cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1446cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mReregisterOnReconnectFailure = false;
1447cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1448cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
1449cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
1450cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
1451cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("We're on the simulator; assuming radio off is meaningless");
1452cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1453cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRadioOffOrNotAvailable: is off and clean up all connections");
1454cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpAllConnections(false, Phone.REASON_RADIO_TURNED_OFF);
1455cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1456cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyOffApnsOfAvailability(null);
1457cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1458cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1459ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
1460ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * A SETUP (aka bringUp) has completed, possibly with an error. If
1461ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * there is an error this method will call {@link #onDataSetupCompleteError}.
1462ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
1463cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1464cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onDataSetupComplete(AsyncResult ar) {
1465cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1466ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        DcFailCause cause = DcFailCause.UNKNOWN;
1467cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean handleError = false;
1468cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = null;
1469cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1470cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(ar.userObj instanceof ApnContext){
1471cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext = (ApnContext)ar.userObj;
1472cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1473cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            throw new RuntimeException("onDataSetupComplete: No apnContext");
1474cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1475cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1476cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (ar.exception == null) {
1477454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = apnContext.getDcAc();
1478cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1479cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (RADIO_TESTS) {
1480cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Note: To change radio.test.onDSC.null.dcac from command line you need to
1481cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // adb root and adb remount and from the command line you can only change the
1482cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // value to 1 once. To change it a second time you can reboot or execute
1483cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // adb shell stop and then adb shell start. The command line to set the value is:
1484ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink 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');"
1485cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ContentResolver cr = mPhone.getContext().getContentResolver();
1486cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                String radioTestProperty = "radio.test.onDSC.null.dcac";
1487cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (Settings.System.getInt(cr, radioTestProperty, 0) == 1) {
1488cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: " + radioTestProperty +
1489cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            " is true, set dcac to null and reset property to false");
1490cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    dcac = null;
1491cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    Settings.System.putInt(cr, radioTestProperty, 0);
1492cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: " + radioTestProperty + "=" +
1493cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            Settings.System.getInt(mPhone.getContext().getContentResolver(),
1494cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                    radioTestProperty, -1));
1495cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1496c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1497cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac == null) {
1498cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("onDataSetupComplete: no connection to DC, handle as error");
1499ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                cause = DcFailCause.CONNECTION_TO_DATACONNECTIONAC_BROKEN;
1500cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                handleError = true;
1501cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1502cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ApnSetting apn = apnContext.getApnSetting();
1503cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
1504cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: success apn=" + (apn == null ? "unknown" : apn.apn));
1505cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1506cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn != null && apn.proxy != null && apn.proxy.length() != 0) {
1507cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    try {
1508cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        String port = apn.port;
1509cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (TextUtils.isEmpty(port)) port = "8080";
1510cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        ProxyProperties proxy = new ProxyProperties(apn.proxy,
1511cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                Integer.parseInt(port), null);
1512cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        dcac.setLinkPropertiesHttpProxySync(proxy);
1513cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    } catch (NumberFormatException e) {
1514cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        loge("onDataSetupComplete: NumberFormatException making ProxyProperties (" +
1515cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                apn.port + "): " + e);
1516cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1517cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1518cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1519cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // everything is setup
1520cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if(TextUtils.equals(apnContext.getApnType(),PhoneConstants.APN_TYPE_DEFAULT)) {
1521ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "true");
152222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mCanSetPreferApn && mPreferredApn == null) {
1523cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (DBG) log("onDataSetupComplete: PREFERED APN is null");
1524cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mPreferredApn = apn;
1525cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (mPreferredApn != null) {
1526cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            setPreferredApn(mPreferredApn.id);
1527cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
1528cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1529cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1530ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
1531cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1532cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                notifyDefaultData(apnContext);
1533c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1534cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1535ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            cause = (DcFailCause) (ar.result);
1536cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
1537cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ApnSetting apn = apnContext.getApnSetting();
1538cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log(String.format("onDataSetupComplete: error apn=%s cause=%s",
1539cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        (apn == null ? "unknown" : apn.apn), cause));
1540c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1541cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cause.isEventLoggable()) {
1542cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Log this failure to the Event Logs.
1543cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                int cid = getCellLocationId();
1544cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                EventLog.writeEvent(EventLogTags.PDP_SETUP_FAIL,
1545cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        cause.ordinal(), cid, TelephonyManager.getDefault().getNetworkType());
1546c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1547cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1548cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Count permanent failures and remove the APN we just tried
1549cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cause.isPermanentFail()) apnContext.decWaitingApnsPermFailCount();
1550cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1551cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.removeWaitingApn(apnContext.getApnSetting());
1552cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
1553cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log(String.format("onDataSetupComplete: WaitingApns.size=%d" +
1554cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        " WaitingApnsPermFailureCountDown=%d",
1555cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.getWaitingApns().size(),
1556cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.getWaitingApnsPermFailCount()));
1557c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1558cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            handleError = true;
1559cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1560cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1561cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (handleError) {
1562ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            onDataSetupCompleteError(ar);
1563ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
1564ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
1565cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1566ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
1567ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Error has occurred during the SETUP {aka bringUP} request and the DCT
1568ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * should either try the next waiting APN or start over from the
1569ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * beginning if the list is empty. Between each SETUP request there will
1570ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * be a delay defined by {@link #APN_DELAY_MILLIS}.
1571ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
1572ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    @Override
1573ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    protected void onDataSetupCompleteError(AsyncResult ar) {
1574ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        String reason = "";
1575ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnContext apnContext = null;
1576ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
1577ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if(ar.userObj instanceof ApnContext){
1578ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext = (ApnContext)ar.userObj;
1579ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        } else {
1580ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            throw new RuntimeException("onDataSetupCompleteError: No apnContext");
1581ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
1582ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
1583ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // See if there are more APN's to try
1584ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnContext.getWaitingApns().isEmpty()) {
1585ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext.setState(DctConstants.State.FAILED);
1586ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType());
1587ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
1588ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext.setDataConnectionAc(null);
1589ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
1590ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getWaitingApnsPermFailCount() == 0) {
1591ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) {
1592ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    log("onDataSetupComplete: All APN's had permanent failures, stop retrying");
1593c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1594cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1595ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) {
1596ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    log("onDataSetupComplete: Not all APN's had permanent failures, retry");
1597ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                }
1598ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                startAlarmForRestartTrySetup(APN_DELAY_MILLIS, apnContext);
1599c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1600ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        } else {
1601ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (DBG) log("onDataSetupComplete: Try next APN");
1602ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext.setState(DctConstants.State.SCANNING);
1603ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // Wait a bit before trying the next APN, so that
1604ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // we're not tying up the RIL command channel
1605ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            startAlarmForReconnect(APN_DELAY_MILLIS, apnContext);
1606c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1607c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1608c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1609c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1610cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Called when EVENT_DISCONNECT_DONE is received.
1611c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1612cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1613cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onDisconnectDone(int connId, AsyncResult ar) {
1614cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = null;
1615cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1616cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (ar.userObj instanceof ApnContext) {
1617cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext = (ApnContext) ar.userObj;
1618cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1619cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onDisconnectDone: Invalid ar in onDisconnectDone, ignore");
1620cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
1621c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1622c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1623cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE apnContext=" + apnContext);
1624cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setState(DctConstants.State.IDLE);
1625cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1626cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1627cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1628cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // if all data connection are gone, check whether Airplane mode request was
1629cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // pending.
1630cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isDisconnected()) {
1631cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPhone.getServiceStateTracker().processPendingRadioPowerOffAfterDataOff()) {
1632cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Radio will be turned off. No need to retry data setup
1633cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setApnSetting(null);
1634cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setDataConnectionAc(null);
1635cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return;
1636cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1637c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1638c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1639cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // If APN is still enabled, try to bring it back up automatically
1640cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext.isReady() && retryAfterDisconnected(apnContext.getReason())) {
1641ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
1642cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Wait a bit before trying the next APN, so that
1643cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // we're not tying up the RIL command channel.
1644cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // This also helps in any external dependency to turn off the context.
1645cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            startAlarmForReconnect(APN_DELAY_MILLIS, apnContext);
1646c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
1647cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setApnSetting(null);
1648cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setDataConnectionAc(null);
1649c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1650c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1651c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1652ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
1653ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Called when EVENT_DISCONNECT_DC_RETRYING is received.
1654ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
1655ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    @Override
1656ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    protected void onDisconnectDcRetrying(int connId, AsyncResult ar) {
1657ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // We could just do this in DC!!!
1658ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnContext apnContext = null;
1659ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
1660ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (ar.userObj instanceof ApnContext) {
1661ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext = (ApnContext) ar.userObj;
1662ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        } else {
1663ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            loge("onDisconnectDcRetrying: Invalid ar in onDisconnectDone, ignore");
1664ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            return;
1665ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
1666ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
1667ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setState(DctConstants.State.RETRYING);
1668ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if(DBG) log("onDisconnectDcRetrying: apnContext=" + apnContext);
1669ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
1670ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1671ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
1672ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
1673cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onPollPdp() {
1674cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getOverallState() == DctConstants.State.CONNECTED) {
1675cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // only poll when connected
167622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.mCi.getDataCallList(obtainMessage(DctConstants.EVENT_DATA_STATE_CHANGED));
1677cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            sendMessageDelayed(obtainMessage(DctConstants.EVENT_POLL_PDP), POLL_PDP_MILLIS);
1678c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1679c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1680c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1681cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1682cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onVoiceCallStarted() {
1683cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onVoiceCallStarted");
1684cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnected() && ! mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
1685cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onVoiceCallStarted stop polling");
1686cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            stopNetStatPoll();
1687cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            stopDataStallAlarm();
1688cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
1689c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1690c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1691c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1692cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1693cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onVoiceCallEnded() {
1694cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onVoiceCallEnded");
1695cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnected()) {
1696cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
1697cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                startNetStatPoll();
1698cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
1699cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
1700cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1701cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // clean slate after call end.
1702cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                resetPollStats();
1703c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1704c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1705cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // reset reconnect timer
1706ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(Phone.REASON_VOICE_CALL_ENDED);
1707c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1708c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1709cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1710cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onCleanUpConnection(boolean tearDown, int apnId, String reason) {
1711cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onCleanUpConnection");
1712cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnIdToType(apnId));
1713cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
1714cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setReason(reason);
1715cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpConnection(tearDown, apnContext);
1716c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1717c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1718c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1719cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1720cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean isConnected() {
1721cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1722ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getState() == DctConstants.State.CONNECTED) {
1723cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // At least one context is connected, return true
1724cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return true;
1725c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1726c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1727cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // There are not any contexts connected, return false
1728cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return false;
1729c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1730c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1731cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1732cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isDisconnected() {
1733cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1734cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!apnContext.isDisconnected()) {
1735cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // At least one context was not disconnected return false
1736cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
1737cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1738c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1739cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // All contexts were disconnected so return true
1740cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
1741c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1742c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1743cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1744cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void notifyDataConnection(String reason) {
1745cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("notifyDataConnection: reason=" + reason);
1746cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1747cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.isReady()) {
1748cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("notifyDataConnection: type:"+apnContext.getApnType());
1749cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
1750cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.getApnType());
1751cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1752c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1753cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyOffApnsOfAvailability(reason);
1754c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1755c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1756c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1757cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Based on the sim operator numeric, create a list for all possible
1758cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Data Connections and setup the preferredApn.
1759c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1760cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void createAllApnList() {
1761ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mAllApnSettings = new ArrayList<ApnSetting>();
1762cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
1763cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String operator = (r != null) ? r.getOperatorNumeric() : "";
1764cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (operator != null) {
1765cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            String selection = "numeric = '" + operator + "'";
1766cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // query only enabled apn.
1767cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // carrier_enabled : 1 means enabled apn, 0 disabled apn.
1768cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            selection += " and carrier_enabled = 1";
1769cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: selection=" + selection);
1770cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1771cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            Cursor cursor = mPhone.getContext().getContentResolver().query(
1772cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    Telephony.Carriers.CONTENT_URI, null, selection, null, null);
1773cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1774cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cursor != null) {
1775cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (cursor.getCount() > 0) {
1776ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    mAllApnSettings = createApnList(cursor);
1777cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1778cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cursor.close();
1779cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1780c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1781c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1782ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings.isEmpty()) {
1783cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: No APN found for carrier: " + operator);
1784cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPreferredApn = null;
1785ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // TODO: What is the right behavior?
1786cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            //notifyNoData(DataConnection.FailCause.MISSING_UNKNOWN_APN);
1787c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
1788cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPreferredApn = getPreferredApn();
1789cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator)) {
1790cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn = null;
1791cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                setPreferredApn(-1);
1792cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1793cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: mPreferredApn=" + mPreferredApn);
1794c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1795ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("createAllApnList: X mAllApnSettings=" + mAllApnSettings);
1796c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1797c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1798ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /** Return the DC AsyncChannel for the new data connection */
1799454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel createDataConnection() {
1800cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createDataConnection E");
1801cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1802cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int id = mUniqueIdGenerator.getAndIncrement();
1803ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        DataConnection conn = DataConnection.makeDataConnection(mPhone, id,
1804ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                                this, mDcTesterFailBringUpAll, mDcc);
1805cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mDataConnections.put(id, conn);
1806454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac = new DcAsyncChannel(conn, LOG_TAG);
1807cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int status = dcac.fullyConnectSync(mPhone.getContext(), this, conn.getHandler());
1808cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (status == AsyncChannel.STATUS_SUCCESSFUL) {
1809ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            mDataConnectionAcHashMap.put(dcac.getDataConnectionIdSync(), dcac);
1810c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
1811ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            loge("createDataConnection: Could not connect to dcac=" + dcac + " status=" + status);
1812c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1813cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1814cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // install reconnect intent filter for this data connection.
1815cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IntentFilter filter = new IntentFilter();
1816cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        filter.addAction(INTENT_RECONNECT_ALARM + '.' + id);
1817ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        filter.addAction(INTENT_RESTART_TRYSETUP_ALARM);
1818cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
1819cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1820cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createDataConnection() X id=" + id + " dc=" + conn);
1821ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        return dcac;
1822c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1823c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1824cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void destroyDataConnections() {
1825cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(mDataConnections != null) {
1826cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("destroyDataConnections: clear mDataConnectionList");
1827cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mDataConnections.clear();
1828cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1829cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("destroyDataConnections: mDataConnecitonList is empty, ignore");
1830c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1831c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1832c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1833c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1834cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Build a list of APNs to be used to create PDP's.
1835c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
1836cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param requestedApnType
1837cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return waitingApns list to be used to create PDP
1838cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *          error when waitingApns.isEmpty()
1839c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1840cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ArrayList<ApnSetting> buildWaitingApns(String requestedApnType) {
1841cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("buildWaitingApns: E requestedApnType=" + requestedApnType);
1842cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ArrayList<ApnSetting> apnList = new ArrayList<ApnSetting>();
1843cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1844cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (requestedApnType.equals(PhoneConstants.APN_TYPE_DUN)) {
1845cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ApnSetting dun = fetchDunApn();
1846cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dun != null) {
1847cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnList.add(dun);
1848cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: X added APN_TYPE_DUN apnList=" + apnList);
1849cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return apnList;
1850c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1851c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1852c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1853cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
1854cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String operator = (r != null) ? r.getOperatorNumeric() : "";
1855cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
1856c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1857cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // This is a workaround for a bug (7305641) where we don't failover to other
1858cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // suitable APNs if our preferred APN fails.  On prepaid ATT sims we need to
1859cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // failover to a provisioning APN, but once we've used their default data
1860cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // connection we are locked to it for life.  This change allows ATT devices
1861cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // to say they don't want to use preferred at all.
1862cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean usePreferred = true;
1863cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        try {
1864cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            usePreferred = ! mPhone.getContext().getResources().getBoolean(com.android.
1865cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    internal.R.bool.config_dontPreferApn);
1866cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } catch (Resources.NotFoundException e) {
1867cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("buildWaitingApns: usePreferred NotFoundException set to true");
1868cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            usePreferred = true;
1869cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1870cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
1871cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("buildWaitingApns: usePreferred=" + usePreferred
187222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    + " canSetPreferApn=" + mCanSetPreferApn
1873cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " mPreferredApn=" + mPreferredApn
1874cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " operator=" + operator + " radioTech=" + radioTech
1875cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " IccRecords r=" + r);
1876cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1877c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
187822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (usePreferred && mCanSetPreferApn && mPreferredApn != null &&
1879cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn.canHandleType(requestedApnType)) {
1880cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
1881cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("buildWaitingApns: Preferred APN:" + operator + ":"
1882cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        + mPreferredApn.numeric + ":" + mPreferredApn);
1883cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1884cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPreferredApn.numeric.equals(operator)) {
1885cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (mPreferredApn.bearer == 0 || mPreferredApn.bearer == radioTech) {
1886cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnList.add(mPreferredApn);
1887cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
1888cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return apnList;
1889cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1890cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("buildWaitingApns: no preferred APN");
1891cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    setPreferredApn(-1);
1892cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mPreferredApn = null;
1893c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1894cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1895cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: no preferred APN");
1896cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                setPreferredApn(-1);
1897cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn = null;
1898c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1899c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1900ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings != null) {
1901ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (DBG) log("buildWaitingApns: mAllApnSettings=" + mAllApnSettings);
1902ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for (ApnSetting apn : mAllApnSettings) {
1903cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: apn=" + apn);
1904cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn.canHandleType(requestedApnType)) {
1905cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (apn.bearer == 0 || apn.bearer == radioTech) {
1906cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (DBG) log("buildWaitingApns: adding apn=" + apn.toString());
1907cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnList.add(apn);
1908c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else {
1909cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (DBG) {
1910cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            log("buildWaitingApns: bearer:" + apn.bearer + " != "
1911cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                    + "radioTech:" + radioTech);
1912cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
1913c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
1914cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1915cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
1916cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("buildWaitingApns: couldn't handle requesedApnType="
1917cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            + requestedApnType);
1918c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1919c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1920c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1921cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1922ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            loge("mAllApnSettings is empty!");
1923c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1924cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("buildWaitingApns: X apnList=" + apnList);
1925cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return apnList;
1926c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1927c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1928cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private String apnListToString (ArrayList<ApnSetting> apns) {
1929cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        StringBuilder result = new StringBuilder();
1930cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (int i = 0, size = apns.size(); i < size; i++) {
1931cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result.append('[')
1932cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                  .append(apns.get(i).toString())
1933cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                  .append(']');
1934c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1935cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result.toString();
1936c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1937c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1938cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void setPreferredApn(int pos) {
193922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (!mCanSetPreferApn) {
1940cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("setPreferredApn: X !canSEtPreferApn");
1941cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
1942cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1943cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1944cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("setPreferredApn: delete");
1945cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ContentResolver resolver = mPhone.getContext().getContentResolver();
1946cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        resolver.delete(PREFERAPN_NO_UPDATE_URI, null, null);
1947cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1948cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (pos >= 0) {
1949cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("setPreferredApn: insert");
1950cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ContentValues values = new ContentValues();
1951cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            values.put(APN_ID, pos);
1952cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            resolver.insert(PREFERAPN_NO_UPDATE_URI, values);
1953cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1954cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1955cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1956cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ApnSetting getPreferredApn() {
1957ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings.isEmpty()) {
1958ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            log("getPreferredApn: X not found mAllApnSettings.isEmpty");
1959cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return null;
1960cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1961cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1962cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Cursor cursor = mPhone.getContext().getContentResolver().query(
1963cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                PREFERAPN_NO_UPDATE_URI, new String[] { "_id", "name", "apn" },
1964cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
1965cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1966cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor != null) {
196722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCanSetPreferApn = true;
1968cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
196922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCanSetPreferApn = false;
1970cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1971cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("getPreferredApn: mRequestedApnType=" + mRequestedApnType + " cursor=" + cursor
1972cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                + " cursor.count=" + ((cursor != null) ? cursor.getCount() : 0));
1973cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
197422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mCanSetPreferApn && cursor.getCount() > 0) {
1975cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            int pos;
1976cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cursor.moveToFirst();
1977cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            pos = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID));
1978ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for(ApnSetting p : mAllApnSettings) {
1979cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("getPreferredApn: apnSetting=" + p);
1980cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (p.id == pos && p.canHandleType(mRequestedApnType)) {
1981cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("getPreferredApn: X found apnSetting" + p);
1982cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    cursor.close();
1983cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return p;
1984cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1985cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
1986cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1987cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1988cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor != null) {
1989cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cursor.close();
1990cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1991cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1992cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("getPreferredApn: X not found");
1993cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
1994cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
1995cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1996cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1997cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void handleMessage (Message msg) {
1998cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("handleMessage msg=" + msg);
1999cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2000cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (!mPhone.mIsTheCurrentActivePhone || mIsDisposed) {
2001cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("handleMessage: Ignore GSM msgs since GSM phone is inactive");
2002cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
2003cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2004cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2005cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        switch (msg.what) {
2006cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_RECORDS_LOADED:
2007cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onRecordsLoaded();
2008cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2009cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2010cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_CONNECTION_DETACHED:
2011cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onDataConnectionDetached();
2012cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2013cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2014cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_CONNECTION_ATTACHED:
2015cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onDataConnectionAttached();
2016cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2017cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2018cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_STATE_CHANGED:
2019cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onDataStateChanged((AsyncResult) msg.obj);
2020cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2021cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2022cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_POLL_PDP:
2023cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onPollPdp();
2024cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
2025cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2026cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DO_RECOVERY:
2027cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                doRecovery();
2028cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2029cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2030cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_APN_CHANGED:
2031cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onApnChanged();
2032cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2033cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2034cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_PS_RESTRICT_ENABLED:
2035cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                /**
2036cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * We don't need to explicitly to tear down the PDP context
2037cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * when PS restricted is enabled. The base band will deactive
2038cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * PDP context and notify us with PDP_CONTEXT_CHANGED.
2039cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * But we should stop the network polling and prevent reset PDP.
2040cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 */
2041cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
2042cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                stopNetStatPoll();
2043cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                stopDataStallAlarm();
2044cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsPsRestricted = true;
2045cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
2046cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2047cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_PS_RESTRICT_DISABLED:
2048cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                /**
2049cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * When PS restrict is removed, we need setup PDP connection if
2050cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * PDP connection is down.
2051cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 */
2052cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_PS_RESTRICT_DISABLED " + mIsPsRestricted);
2053cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsPsRestricted  = false;
2054cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (isConnected()) {
2055cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    startNetStatPoll();
2056cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
2057cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2058cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // TODO: Should all PDN states be checked to fail?
2059ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    if (mState == DctConstants.State.FAILED) {
2060cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        cleanUpAllConnections(false, Phone.REASON_PS_RESTRICT_ENABLED);
2061cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mReregisterOnReconnectFailure = false;
2062cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2063cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    trySetupData(Phone.REASON_PS_RESTRICT_ENABLED, PhoneConstants.APN_TYPE_DEFAULT);
2064cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2065cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
2066ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
2067cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_TRY_SETUP_DATA:
2068cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (msg.obj instanceof ApnContext) {
2069cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    onTrySetupData((ApnContext)msg.obj);
2070cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else if (msg.obj instanceof String) {
2071cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    onTrySetupData((String)msg.obj);
2072cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2073cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    loge("EVENT_TRY_SETUP request w/o apnContext or String");
2074cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2075cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
2076cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2077cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_CLEAN_UP_CONNECTION:
2078cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                boolean tearDown = (msg.arg1 == 0) ? false : true;
2079cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_CLEAN_UP_CONNECTION tearDown=" + tearDown);
2080cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (msg.obj instanceof ApnContext) {
2081cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    cleanUpConnection(tearDown, (ApnContext)msg.obj);
2082cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2083ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    loge("EVENT_CLEAN_UP_CONNECTION request w/o apn context, call super");
2084ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    super.handleMessage(msg);
2085cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2086cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
2087ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
2088cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            default:
2089cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // handle the message in the super class DataConnectionTracker
2090cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                super.handleMessage(msg);
2091cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2092cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2093cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
2094cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2095cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected int getApnProfileID(String apnType) {
2096cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IMS)) {
2097cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_IMS;
2098cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_FOTA)) {
2099cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_FOTA;
2100cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_CBS)) {
2101cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_CBS;
2102cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2103cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_DEFAULT;
2104cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2105cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2106cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2107cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private int getCellLocationId() {
2108cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int cid = -1;
2109cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        CellLocation loc = mPhone.getCellLocation();
2110cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2111cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (loc != null) {
2112cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (loc instanceof GsmCellLocation) {
2113cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cid = ((GsmCellLocation)loc).getCid();
2114cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else if (loc instanceof CdmaCellLocation) {
2115cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cid = ((CdmaCellLocation)loc).getBaseStationId();
2116cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
2117cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2118cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return cid;
2119cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
2120cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2121cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2122cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onUpdateIcc() {
2123cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mUiccController == null ) {
2124cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            return;
2125cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2126cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2127cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords newIccRecords = mUiccController.getIccRecords(UiccController.APP_FAM_3GPP);
2128cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2129cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
2130cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (r != newIccRecords) {
2131cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (r != null) {
2132cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("Removing stale icc objects.");
2133cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                r.unregisterForRecordsLoaded(this);
2134cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIccRecords.set(null);
21359aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan            }
2136cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (newIccRecords != null) {
2137cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("New records found");
2138cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIccRecords.set(newIccRecords);
2139cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                newIccRecords.registerForRecordsLoaded(
2140cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        this, DctConstants.EVENT_RECORDS_LOADED, null);
21419aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan            }
21429aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan        }
2143cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
2144cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2145cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2146cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void log(String s) {
2147ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        Rlog.d(LOG_TAG, s);
2148cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
2149cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2150cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2151cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void loge(String s) {
2152ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        Rlog.e(LOG_TAG, s);
2153cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
2154cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2155cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2156c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2157cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println("DataConnectionTracker extends:");
2158cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        super.dump(fd, pw, args);
2159cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mReregisterOnReconnectFailure=" + mReregisterOnReconnectFailure);
216022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" canSetPreferApn=" + mCanSetPreferApn);
2161cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mApnObserver=" + mApnObserver);
2162cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" getOverallState=" + getOverallState());
2163ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        pw.println(" mDataConnectionAsyncChannels=%s\n" + mDataConnectionAcHashMap);
2164c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2165c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville}
2166