DcTracker.java revision 231c3c6271a27b5f03444f4d24b52c41c46566ab
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;
21c9b81a0c05128694c617fcdd67e73821895822feWink Savilleimport android.content.ActivityNotFoundException;
22c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.ContentResolver;
23cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.content.ContentValues;
24c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Context;
25c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Intent;
26c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.IntentFilter;
27cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.content.res.Resources;
28c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.database.ContentObserver;
29cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.database.Cursor;
30cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.ConnectivityManager;
31c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.net.LinkProperties;
3296cce86cf08e37e0f09ed5057b1196e26b302743Robert Greenwaltimport android.net.NetworkCapabilities;
33cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.NetworkConfig;
34071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwaltimport android.net.NetworkFactory;
35071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwaltimport android.net.NetworkRequest;
36cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.NetworkUtils;
379c180aedfc9f0d20525c0128487d3500e6c0a715Jason Monkimport android.net.ProxyInfo;
38cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.Uri;
39c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.AsyncResult;
403fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwaltimport android.os.Build;
41a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.Handler;
42071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwaltimport android.os.Looper;
43c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Message;
441f2a2323572b2f3ab18234726cc1b048c670fbabRobert Greenwaltimport android.os.Messenger;
45a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.RegistrantList;
46c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemClock;
47c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemProperties;
48c9b81a0c05128694c617fcdd67e73821895822feWink Savilleimport android.os.UserHandle;
49c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.provider.Settings;
50cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.provider.Telephony;
51cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.CellLocation;
52c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.telephony.ServiceState;
53c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.telephony.TelephonyManager;
54a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.SubscriptionManager;
55cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.cdma.CdmaCellLocation;
56cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.gsm.GsmCellLocation;
57c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.text.TextUtils;
58cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kallaimport android.util.EventLog;
5999c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Savilleimport android.telephony.Rlog;
60c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
61a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.cdma.CDMALTEPhone;
624918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savilleimport com.android.internal.telephony.Phone;
634918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savilleimport com.android.internal.telephony.PhoneBase;
64cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.DctConstants;
65cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.EventLogTags;
66c9b81a0c05128694c617fcdd67e73821895822feWink Savilleimport com.android.internal.telephony.TelephonyIntents;
67cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.gsm.GSMPhone;
684918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savilleimport com.android.internal.telephony.PhoneConstants;
69cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.RILConstants;
70d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccRecords;
71bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenkaimport com.android.internal.telephony.uicc.UiccController;
72c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.util.AsyncChannel;
7376f43316a5a6082d601bffd4b6898d0bd81e11fcramimport com.android.internal.util.ArrayUtils;
74c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
75c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.io.FileDescriptor;
76c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.io.PrintWriter;
77c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.ArrayList;
78187a39f896f88eb6c5e4306d9595546654825976Wink Savilleimport java.util.concurrent.atomic.AtomicBoolean;
79c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.HashMap;
80c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
81a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.provider.Settings;
82a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
83a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.ServiceStateTracker;
84c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/**
85c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * {@hide}
86c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
87454b1dfd508844b42eb775e4ab2359be74d3672bWink Savillepublic final class DcTracker extends DcTrackerBase {
88cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected final String LOG_TAG = "DCT";
89c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
90b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla    /**
91a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * List of messages that are waiting to be posted, when data call disconnect
92a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * is complete
93a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
94a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ArrayList<Message> mDisconnectAllCompleteMsgList = new ArrayList<Message>();
95a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
96a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private RegistrantList mAllDataDisconnectedRegistrants = new RegistrantList();
97a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
98a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected int mDisconnectPendingCount = 0;
99a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
100a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
101cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Handles changes to the APN db.
102b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla     */
103cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private class ApnChangeObserver extends ContentObserver {
104cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public ApnChangeObserver () {
105cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            super(mDataConnectionTracker);
106cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
107c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
108cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
109cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public void onChange(boolean selfChange) {
110cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            sendMessage(obtainMessage(DctConstants.EVENT_APN_CHANGED));
111cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
112cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
113c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
114cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Instance Variables
115c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
116cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean mReregisterOnReconnectFailure = false;
117c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
118c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
119cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Constants
120c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
121ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    // Used by puppetmaster/*/radio_stress.py
122ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private static final String PUPPET_MASTER_RADIO_STRESS_TEST = "gsm.defaultpdpcontext.active";
123c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
124ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private static final int POLL_PDP_MILLIS = 5 * 1000;
125c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
126cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final Uri PREFERAPN_NO_UPDATE_URI =
127cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        Uri.parse("content://telephony/carriers/preferapn_no_update");
128cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final String APN_ID = "apn_id";
129cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
130ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private boolean mCanSetPreferApn = false;
131c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
132187a39f896f88eb6c5e4306d9595546654825976Wink Saville    private AtomicBoolean mAttached = new AtomicBoolean(false);
133187a39f896f88eb6c5e4306d9595546654825976Wink Saville
134cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** Watches for changes to the APN db. */
135cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ApnChangeObserver mApnObserver;
136cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1374dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt    /** Used to send us NetworkRequests from ConnectivityService.  Remeber it so we can
1384dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt     * unregister on dispose. */
1394dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt    private Messenger mNetworkFactoryMessenger;
140071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt    private NetworkFactory mNetworkFactory;
141071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt    private NetworkCapabilities mNetworkFilter;
1424dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt
143a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean mImsRegistrationState = false;
144a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ApnContext mWaitCleanUpApnContext = null;
145a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private boolean mDeregistrationAlarmState = false;
146a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private PendingIntent mImsDeregistrationDelayIntent = null;
147a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
148cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Constructor
149454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    public DcTracker(PhoneBase p) {
150cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        super(p);
151cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("GsmDCT.constructor");
152cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
153cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mDataConnectionTracker = this;
154a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        update();
155cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mApnObserver = new ApnChangeObserver();
156cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        p.getContext().getContentResolver().registerContentObserver(
157cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                Telephony.Carriers.CONTENT_URI, true, mApnObserver);
158cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
159d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        initApnContexts();
160d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
161d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        for (ApnContext apnContext : mApnContexts.values()) {
162d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            // Register the reconnect and restart actions.
163d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            IntentFilter filter = new IntentFilter();
164d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            filter.addAction(INTENT_RECONNECT_ALARM + '.' + apnContext.getApnType());
165d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            filter.addAction(INTENT_RESTART_TRYSETUP_ALARM + '.' + apnContext.getApnType());
166d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
167d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        }
168d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
1691f2a2323572b2f3ab18234726cc1b048c670fbabRobert Greenwalt        ConnectivityManager cm = (ConnectivityManager)p.getContext().getSystemService(
1701f2a2323572b2f3ab18234726cc1b048c670fbabRobert Greenwalt                Context.CONNECTIVITY_SERVICE);
171071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
172071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        mNetworkFilter = new NetworkCapabilities();
173071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        mNetworkFilter.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
174fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
175fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL);
176fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
177fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_FOTA);
178fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
179fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_CBS);
180fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_IA);
181fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_RCS);
182fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_XCAP);
183fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS);
184fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
185fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
186071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
187071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        mNetworkFactory = new TelephonyNetworkFactory(this.getLooper(), p.getContext(),
188071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt                "TelephonyNetworkFactory", mNetworkFilter);
189071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        mNetworkFactory.setScoreFilter(50);
190071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        mNetworkFactoryMessenger = new Messenger(mNetworkFactory);
191071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        cm.registerNetworkFactory(mNetworkFactoryMessenger, "Telephony");
19276f43316a5a6082d601bffd4b6898d0bd81e11fcram
19376f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Add Emergency APN to APN setting list by default to support EPDN in sim absent cases
19476f43316a5a6082d601bffd4b6898d0bd81e11fcram        initEmergencyApnSetting();
19576f43316a5a6082d601bffd4b6898d0bd81e11fcram        addEmergencyApnSetting();
196cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
197c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
198a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void registerForAllEvents() {
199a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.mCi.registerForAvailable(this, DctConstants.EVENT_RADIO_AVAILABLE, null);
200a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.mCi.registerForOffOrNotAvailable(this,
201a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville               DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
202a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.mCi.registerForDataNetworkStateChanged(this,
203a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville               DctConstants.EVENT_DATA_STATE_CHANGED, null);
204a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getCallTracker().registerForVoiceCallEnded (this,
205a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville               DctConstants.EVENT_VOICE_CALL_ENDED, null);
206a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getCallTracker().registerForVoiceCallStarted (this,
207a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville               DctConstants.EVENT_VOICE_CALL_STARTED, null);
208a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getServiceStateTracker().registerForDataConnectionAttached(this,
209a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville               DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null);
210a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getServiceStateTracker().registerForDataConnectionDetached(this,
211a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville               DctConstants.EVENT_DATA_CONNECTION_DETACHED, null);
212a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getServiceStateTracker().registerForRoamingOn(this,
213a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville               DctConstants.EVENT_ROAMING_ON, null);
214a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getServiceStateTracker().registerForRoamingOff(this,
215a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville               DctConstants.EVENT_ROAMING_OFF, null);
216a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getServiceStateTracker().registerForPsRestrictedEnabled(this,
217a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                DctConstants.EVENT_PS_RESTRICT_ENABLED, null);
218a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getServiceStateTracker().registerForPsRestrictedDisabled(this,
219a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                DctConstants.EVENT_PS_RESTRICT_DISABLED, null);
220a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     //   SubscriptionManager.registerForDdsSwitch(this,
221a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     //          DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS, null);
222a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(this,
223a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                DctConstants.EVENT_DATA_RAT_CHANGED, null);
224a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
225cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
226cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void dispose() {
227cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("GsmDCT.dispose");
2284dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt
2294dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt        ConnectivityManager cm = (ConnectivityManager)mPhone.getContext().getSystemService(
2304dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt                Context.CONNECTIVITY_SERVICE);
2314dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt        cm.unregisterNetworkFactory(mNetworkFactoryMessenger);
2324dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt        mNetworkFactoryMessenger = null;
2334dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt
234cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, null);
235cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
236cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        super.dispose();
237cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
238a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getContext().getContentResolver().unregisterContentObserver(mApnObserver);
239a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mApnContexts.clear();
240a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPrioritySortedApnContexts.clear();
241a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
242a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        destroyDataConnections();
243a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
244a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void unregisterForAllEvents() {
245a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         //Unregister for all events
24622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.unregisterForAvailable(this);
24722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.unregisterForOffOrNotAvailable(this);
248cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
249a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (r != null) {
250a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            r.unregisterForRecordsLoaded(this);
251a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mIccRecords.set(null);
252a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
25322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.unregisterForDataNetworkStateChanged(this);
254cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getCallTracker().unregisterForVoiceCallEnded(this);
255cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getCallTracker().unregisterForVoiceCallStarted(this);
256cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().unregisterForDataConnectionAttached(this);
257cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().unregisterForDataConnectionDetached(this);
258cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().unregisterForRoamingOn(this);
259cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().unregisterForRoamingOff(this);
260cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().unregisterForPsRestrictedEnabled(this);
261cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().unregisterForPsRestrictedDisabled(this);
262a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        //SubscriptionManager.unregisterForDdsSwitch(this);
263cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
264cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
265071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt    private class TelephonyNetworkFactory extends NetworkFactory {
266071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        public TelephonyNetworkFactory(Looper l, Context c, String TAG, NetworkCapabilities nc) {
267071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            super(l, c, TAG, nc);
268071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
269071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
270071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        @Override
271071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        protected void needNetworkFor(NetworkRequest networkRequest, int score) {
272071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            // figure out the apn type and enable it
273071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (DBG) log("Cellular needs Network for " + networkRequest);
274071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            ApnContext apnContext = apnContextForNetworkRequest(networkRequest);
275071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (apnContext != null) apnContext.incRefCount();
276071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
277071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
278071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        @Override
279071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        protected void releaseNetworkFor(NetworkRequest networkRequest) {
280071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (DBG) log("Cellular releasing Network for " + networkRequest);
281071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            ApnContext apnContext = apnContextForNetworkRequest(networkRequest);
282071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (apnContext != null) apnContext.decRefCount();
283071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
284071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt    }
285071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
286071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt    private ApnContext apnContextForNetworkRequest(NetworkRequest nr) {
287071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        NetworkCapabilities nc = nr.networkCapabilities;
288071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        // for now, ignore the bandwidth stuff
289fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        if (nc.getTransportTypes().length > 0 &&
290071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt                nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == false) {
291071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            return null;
292071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
293071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
294071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        // in the near term just do 1-1 matches.
295071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        // TODO - actually try to match the set of capabilities
296071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        int type = -1;
297071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        String name = null;
298071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
299071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        boolean error = false;
300071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
301071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (name != null) error = true;
302071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            name = PhoneConstants.APN_TYPE_DEFAULT;
303071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            type = ConnectivityManager.TYPE_MOBILE;
304071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
305071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
306071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (name != null) error = true;
307071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            name = PhoneConstants.APN_TYPE_MMS;
308071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            type = ConnectivityManager.TYPE_MOBILE_MMS;
309071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
310071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
311071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (name != null) error = true;
312071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            name = PhoneConstants.APN_TYPE_SUPL;
313071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            type = ConnectivityManager.TYPE_MOBILE_SUPL;
314071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
315071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
316071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (name != null) error = true;
317071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            name = PhoneConstants.APN_TYPE_DUN;
318071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            type = ConnectivityManager.TYPE_MOBILE_DUN;
319071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
320071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
321071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (name != null) error = true;
322071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            name = PhoneConstants.APN_TYPE_FOTA;
323071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            type = ConnectivityManager.TYPE_MOBILE_FOTA;
324071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
325071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
326071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (name != null) error = true;
327071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            name = PhoneConstants.APN_TYPE_IMS;
328071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            type = ConnectivityManager.TYPE_MOBILE_IMS;
329071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
330071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
331071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (name != null) error = true;
332071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            name = PhoneConstants.APN_TYPE_CBS;
333071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            type = ConnectivityManager.TYPE_MOBILE_CBS;
334071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
335071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IA)) {
336071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (name != null) error = true;
337071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            name = PhoneConstants.APN_TYPE_IA;
338071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            type = ConnectivityManager.TYPE_MOBILE_IA;
339071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
340071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_RCS)) {
341071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (name != null) error = true;
342071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            name = null;
343071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            loge("RCS APN type not yet supported");
344071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
345071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_XCAP)) {
346071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (name != null) error = true;
347071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            name = null;
348071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            loge("XCAP APN type not yet supported");
349071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
350071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)) {
351071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (name != null) error = true;
352071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            name = null;
353071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            loge("EIMS APN type not yet supported");
354071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
355071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (error) {
356071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            loge("Multiple apn types specified in request - result is unspecified!");
357071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
358071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (type == -1 || name == null) {
359071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            loge("Unsupported NetworkRequest in Telephony: " + nr);
360071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            return null;
361071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
362071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        ApnContext apnContext = mApnContexts.get(name);
363071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (apnContext == null) {
364d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            loge("Request for unsupported mobile type: " + type);
365071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
366071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        return apnContext;
367071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt    }
368071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
369cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
370cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isApnTypeActive(String type) {
371cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(type);
372cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) return false;
373cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
374ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        return (apnContext.getDcAc() != null);
375cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
376cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
377cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
378cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isDataPossible(String apnType) {
379cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
380cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
381cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
382cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
383cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean apnContextIsEnabled = apnContext.isEnabled();
384cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        DctConstants.State apnContextState = apnContext.getState();
385cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean apnTypePossible = !(apnContextIsEnabled &&
386cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                (apnContextState == DctConstants.State.FAILED));
387cf5205f70eb1eac497164124187a088ecb03fff5Ram        boolean isEmergencyApn = apnContext.getApnType().equals(PhoneConstants.APN_TYPE_EMERGENCY);
388cf5205f70eb1eac497164124187a088ecb03fff5Ram        // Set the emergency APN availability status as TRUE irrespective of conditions checked in
389cf5205f70eb1eac497164124187a088ecb03fff5Ram        // isDataAllowed() like IN_SERVICE, MOBILE DATA status etc.
390cf5205f70eb1eac497164124187a088ecb03fff5Ram        boolean dataAllowed = isEmergencyApn || isDataAllowed();
391cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean possible = dataAllowed && apnTypePossible;
392cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
393ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (VDBG) {
394cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log(String.format("isDataPossible(%s): possible=%b isDataAllowed=%b " +
395cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    "apnTypePossible=%b apnContextisEnabled=%b apnContextState()=%s",
396cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnType, possible, dataAllowed, apnTypePossible,
397cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContextIsEnabled, apnContextState));
398cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
399cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return possible;
400cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
401cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
402cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
403cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void finalize() {
404cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(DBG) log("finalize");
405cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
406cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
407a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void supplyMessenger() {
408a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville       // Supply the data connection tracker messenger only if
409a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville       // this is corresponding to the current DDS.
410a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville       if (!isActiveDataSubscription()) {
411a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville           return;
412a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville       }
413a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
414a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ConnectivityManager cm = (ConnectivityManager)mPhone.getContext().getSystemService(
415a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                Context.CONNECTIVITY_SERVICE);
416a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE, new Messenger(this));
417a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE_MMS, new Messenger(this));
418a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE_SUPL, new Messenger(this));
419a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE_DUN, new Messenger(this));
420a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE_HIPRI, new Messenger(this));
421a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE_FOTA, new Messenger(this));
422a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE_IMS, new Messenger(this));
423a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE_CBS, new Messenger(this));
424cf5205f70eb1eac497164124187a088ecb03fff5Ram        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE_EMERGENCY, new Messenger(this));
425a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
426a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4274a9b3afeb2ec4d573eca335a3706392ecf9f281eWink Saville    private ApnContext addApnContext(String type, NetworkConfig networkConfig) {
428071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        ApnContext apnContext = new ApnContext(mPhone.getContext(), type, LOG_TAG, networkConfig,
429071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt                this);
430cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mApnContexts.put(type, apnContext);
4313fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        mPrioritySortedApnContexts.add(apnContext);
432bce3d2575122929bb27ec8a37d56e96da39a3ca2Robert Greenwalt        return apnContext;
433cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
434c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
435d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt    protected void initApnContexts() {
436d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        log("initApnContexts: E");
437d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        // Load device network attributes from resources
438d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        String[] networkConfigStrings = mPhone.getContext().getResources().getStringArray(
439d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                com.android.internal.R.array.networkAttributes);
440d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        for (String networkConfigString : networkConfigStrings) {
441d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            NetworkConfig networkConfig = new NetworkConfig(networkConfigString);
442d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            ApnContext apnContext = null;
443d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
444d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            switch (networkConfig.type) {
445d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE:
446d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_DEFAULT, networkConfig);
447d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
448d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_MMS:
449d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_MMS, networkConfig);
450d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
451d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_SUPL:
452d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_SUPL, networkConfig);
453d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
454d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_DUN:
455d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_DUN, networkConfig);
456d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
457d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_HIPRI:
458d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_HIPRI, networkConfig);
459d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
460d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_FOTA:
461d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_FOTA, networkConfig);
462d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
463d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_IMS:
464d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_IMS, networkConfig);
465d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
466d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_CBS:
467d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_CBS, networkConfig);
468d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
469d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_IA:
470d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_IA, networkConfig);
471d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
472cf5205f70eb1eac497164124187a088ecb03fff5Ram            case ConnectivityManager.TYPE_MOBILE_EMERGENCY:
473cf5205f70eb1eac497164124187a088ecb03fff5Ram                apnContext = addApnContext(PhoneConstants.APN_TYPE_EMERGENCY, networkConfig);
474cf5205f70eb1eac497164124187a088ecb03fff5Ram                break;
475d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            default:
476d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                log("initApnContexts: skipping unknown type=" + networkConfig.type);
477d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                continue;
478d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            }
479d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            log("initApnContexts: apnContext=" + apnContext);
480d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        }
481d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        log("initApnContexts: X mApnContexts=" + mApnContexts);
482d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt    }
483d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
484cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
485cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public LinkProperties getLinkProperties(String apnType) {
486cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
487cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
488454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = apnContext.getDcAc();
489cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac != null) {
490cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("return link properites for " + apnType);
491cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return dcac.getLinkPropertiesSync();
492cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
493cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
494cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("return new LinkProperties");
495cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return new LinkProperties();
496cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
497cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
498608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt    @Override
499608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt    public NetworkCapabilities getNetworkCapabilities(String apnType) {
500608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        ApnContext apnContext = mApnContexts.get(apnType);
501608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        if (apnContext!=null) {
502608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            DcAsyncChannel dataConnectionAc = apnContext.getDcAc();
503608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            if (dataConnectionAc != null) {
504608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                if (DBG) {
505608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                    log("get active pdp is not null, return NetworkCapabilities for " + apnType);
506608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                }
507608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                return dataConnectionAc.getNetworkCapabilitiesSync();
508608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            }
509608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        }
510608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        if (DBG) log("return new NetworkCapabilities");
511608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        return new NetworkCapabilities();
512608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt    }
513cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
514cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
515cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return all active apn types
516cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public String[] getActiveApnTypes() {
517cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("get all active apn types");
518cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ArrayList<String> result = new ArrayList<String>();
519cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
520cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
521187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (mAttached.get() && apnContext.isReady()) {
522cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                result.add(apnContext.getApnType());
523cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
524cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
525c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
526cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result.toArray(new String[0]);
527cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
528cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
529cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
530cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return active apn of specific apn type
531cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public String getActiveApnString(String apnType) {
532ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (VDBG) log( "get active apn string for type:" + apnType);
533cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
534cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
535cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ApnSetting apnSetting = apnContext.getApnSetting();
536cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnSetting != null) {
537cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return apnSetting.apn;
538cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
539cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
540cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
541cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
542cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
543cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
544cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isApnTypeEnabled(String apnType) {
545cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
546cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
547cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
548cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
549cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return apnContext.isEnabled();
550cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
551cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
552cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
553cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void setState(DctConstants.State s) {
554cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setState should not be used in GSM" + s);
555cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
556cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
557cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return state of specific apn type
558cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
559cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public DctConstants.State getState(String apnType) {
560cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
561cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
562cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return apnContext.getState();
563c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
564cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return DctConstants.State.FAILED;
565cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
566c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
567c9b81a0c05128694c617fcdd67e73821895822feWink Saville    // Return if apn type is a provisioning apn.
568c9b81a0c05128694c617fcdd67e73821895822feWink Saville    @Override
569c9b81a0c05128694c617fcdd67e73821895822feWink Saville    protected boolean isProvisioningApn(String apnType) {
570c9b81a0c05128694c617fcdd67e73821895822feWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
571c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (apnContext != null) {
572c9b81a0c05128694c617fcdd67e73821895822feWink Saville            return apnContext.isProvisioningApn();
573c9b81a0c05128694c617fcdd67e73821895822feWink Saville        }
574c9b81a0c05128694c617fcdd67e73821895822feWink Saville        return false;
575c9b81a0c05128694c617fcdd67e73821895822feWink Saville    }
576c9b81a0c05128694c617fcdd67e73821895822feWink Saville
577cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return state of overall
578cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
579cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public DctConstants.State getOverallState() {
580cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isConnecting = false;
581cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isFailed = true; // All enabled Apns should be FAILED.
582cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isAnyEnabled = false;
583cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
584cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
585cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.isEnabled()) {
586cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                isAnyEnabled = true;
587cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                switch (apnContext.getState()) {
588cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case CONNECTED:
589cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case DISCONNECTING:
590cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("overall state is CONNECTED");
591cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return DctConstants.State.CONNECTED;
592ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                case RETRYING:
593cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case CONNECTING:
594cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isConnecting = true;
595cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isFailed = false;
596cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
597cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case IDLE:
598cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case SCANNING:
599cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isFailed = false;
600cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
601cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                default:
602cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isAnyEnabled = true;
603cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
604cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
605cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
606c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
607c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
608cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (!isAnyEnabled) { // Nothing enabled. return IDLE.
609cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log( "overall state is IDLE");
610cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.IDLE;
611c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
612c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
613cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnecting) {
614cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log( "overall state is CONNECTING");
615cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.CONNECTING;
616cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (!isFailed) {
617cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log( "overall state is IDLE");
618cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.IDLE;
619cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
620cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log( "overall state is FAILED");
621cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.FAILED;
622c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
623c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
624c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
625cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
626cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean isApnTypeAvailable(String type) {
627cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (type.equals(PhoneConstants.APN_TYPE_DUN) && fetchDunApn() != null) {
628cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return true;
629c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
630c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
631ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings != null) {
632ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for (ApnSetting apn : mAllApnSettings) {
633cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn.canHandleType(type)) {
634cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return true;
635cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
636cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
637c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
638cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return false;
639c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
640c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
641cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
642cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Report on whether data connectivity is enabled for any APN.
643cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return {@code false} if data connectivity has been explicitly disabled,
644cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * {@code true} otherwise.
645cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
646cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
647cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean getAnyDataEnabled() {
648cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        synchronized (mDataEnabledLock) {
649cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!(mInternalDataEnabled && mUserDataEnabled && sPolicyDataEnabled)) return false;
650cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            for (ApnContext apnContext : mApnContexts.values()) {
651cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Make sure we don't have a context that is going down
652cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // and is explicitly disabled.
653cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (isDataAllowed(apnContext)) {
654cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return true;
655cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
656cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
657cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
658c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
659c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
660c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
661a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean getAnyDataEnabled(boolean checkUserDataEnabled) {
662a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        synchronized (mDataEnabledLock) {
663a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (!(mInternalDataEnabled && (!checkUserDataEnabled || mUserDataEnabled)
664a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        && (!checkUserDataEnabled || sPolicyDataEnabled)))
665a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return false;
666a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
667a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            for (ApnContext apnContext : mApnContexts.values()) {
668a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // Make sure we dont have a context that going down
669a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // and is explicitly disabled.
670a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (isDataAllowed(apnContext)) {
671a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    return true;
672a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
673a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
674a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return false;
675a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
676a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
677a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
678cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean isDataAllowed(ApnContext apnContext) {
679cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return apnContext.isReady() && isDataAllowed();
680c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
681c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
682cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //****** Called from ServiceStateTracker
683c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
684cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Invoked when ServiceStateTracker observes a transition from GPRS
685cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * attach to detach.
686c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
687cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onDataConnectionDetached() {
688cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        /*
689cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * We presently believe it is unnecessary to tear down the PDP context
690cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * when GPRS detaches, but we should stop the network polling.
691cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         */
692cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log ("onDataConnectionDetached: stop polling and notify detached");
693cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopNetStatPoll();
694cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopDataStallAlarm();
695cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyDataConnection(Phone.REASON_DATA_DETACHED);
696187a39f896f88eb6c5e4306d9595546654825976Wink Saville        mAttached.set(false);
697cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
698c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
699cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onDataConnectionAttached() {
700cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onDataConnectionAttached");
7017ab10e4710bdb54c6d9a5ee01cd443a42a2689f5Sungmin Choi        mAttached.set(true);
702cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getOverallState() == DctConstants.State.CONNECTED) {
703cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onDataConnectionAttached: start polling notify attached");
704cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            startNetStatPoll();
705cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
706cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_DATA_ATTACHED);
707cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
708cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // update APN availability so that APN can be enabled.
709cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_DATA_ATTACHED);
710cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
71112fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        if (mAutoAttachOnCreationConfig) {
71212fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao            mAutoAttachOnCreation = true;
71312fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        }
714ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(Phone.REASON_DATA_ATTACHED);
715cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
716c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
717cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
718cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean isDataAllowed() {
719cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        final boolean internalDataEnabled;
720cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        synchronized (mDataEnabledLock) {
721cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            internalDataEnabled = mInternalDataEnabled;
722cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
723cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
7249894b3fb2f35e21d9cfd45f233ed093589e14c26sy.yun        boolean attachedState = mAttached.get();
725cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
726cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
727cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean recordsLoaded = (r != null) ? r.getRecordsLoaded() : false;
728cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
729a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        //FIXME always attach
730a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean psRestricted = mIsPsRestricted;
731a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        int phoneNum = TelephonyManager.getDefault().getPhoneCount();
732a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (phoneNum > 1) {
733a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            attachedState = true;
734a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            psRestricted = false;
735a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
736a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
737cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean allowed =
7389894b3fb2f35e21d9cfd45f233ed093589e14c26sy.yun                    (attachedState || mAutoAttachOnCreation) &&
739cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    recordsLoaded &&
740cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    (mPhone.getState() == PhoneConstants.State.IDLE ||
741cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                     mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) &&
742cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    internalDataEnabled &&
743cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    (!mPhone.getServiceState().getRoaming() || getDataOnRoamingEnabled()) &&
744a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    //!mIsPsRestricted &&
745a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    !psRestricted &&
746cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    desiredPowerState;
747cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (!allowed && DBG) {
748cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            String reason = "";
7499894b3fb2f35e21d9cfd45f233ed093589e14c26sy.yun            if (!(attachedState || mAutoAttachOnCreation)) {
7509894b3fb2f35e21d9cfd45f233ed093589e14c26sy.yun                reason += " - Attached= " + attachedState;
751cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
752cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!recordsLoaded) reason += " - SIM not loaded";
753cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPhone.getState() != PhoneConstants.State.IDLE &&
754cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
755cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                reason += " - PhoneState= " + mPhone.getState();
756cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                reason += " - Concurrent voice and data not allowed";
757cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
758cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!internalDataEnabled) reason += " - mInternalDataEnabled= false";
759cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPhone.getServiceState().getRoaming() && !getDataOnRoamingEnabled()) {
760cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                reason += " - Roaming and data roaming not enabled";
761cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
762cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mIsPsRestricted) reason += " - mIsPsRestricted= true";
763cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!desiredPowerState) reason += " - desiredPowerState= false";
764cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("isDataAllowed: not allowed due to" + reason);
765c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
766cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return allowed;
767cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
768c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
769ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void setupDataOnConnectableApns(String reason) {
7703fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (DBG) log("setupDataOnConnectableApns: " + reason);
7713fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
7723fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        for (ApnContext apnContext : mPrioritySortedApnContexts) {
7733fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (DBG) log("setupDataOnConnectableApns: apnContext " + apnContext);
774cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.getState() == DctConstants.State.FAILED) {
775cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setState(DctConstants.State.IDLE);
776cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
777ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.isConnectable()) {
778ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                log("setupDataOnConnectableApns: isConnectable() call trySetupData");
779ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setReason(reason);
780ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                trySetupData(apnContext);
781cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
782cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
783c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
784c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
785cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean trySetupData(ApnContext apnContext) {
786cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
787cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("trySetupData for type:" + apnContext.getApnType() +
788cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    " due to " + apnContext.getReason() + " apnContext=" + apnContext);
789cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("trySetupData with mIsPsRestricted=" + mIsPsRestricted);
790cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
791cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
792cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
793cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
794cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
795cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setState(DctConstants.State.CONNECTED);
796cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
797cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
798cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("trySetupData: X We're on the simulator; assuming connected retValue=true");
799cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return true;
800cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
801cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
802cf5205f70eb1eac497164124187a088ecb03fff5Ram        // Allow SETUP_DATA request for E-APN to be completed during emergency call
803cf5205f70eb1eac497164124187a088ecb03fff5Ram        // and MOBILE DATA On/Off cases as well.
804cf5205f70eb1eac497164124187a088ecb03fff5Ram        boolean isEmergencyApn = apnContext.getApnType().equals(PhoneConstants.APN_TYPE_EMERGENCY);
805cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
806a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean checkUserDataEnabled =
807a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    !(apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IMS));
808cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
809cf5205f70eb1eac497164124187a088ecb03fff5Ram        if (apnContext.isConnectable() && (isEmergencyApn ||
810cf5205f70eb1eac497164124187a088ecb03fff5Ram                (isDataAllowed(apnContext) &&
811cf5205f70eb1eac497164124187a088ecb03fff5Ram                getAnyDataEnabled(checkUserDataEnabled) && !isEmergency()))) {
812ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getState() == DctConstants.State.FAILED) {
813ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) log("trySetupData: make a FAILED ApnContext IDLE so its reusable");
814ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setState(DctConstants.State.IDLE);
815ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
816203e588e3c42a81aa8a56f595119c181a63b12caWink Saville            int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
817cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.getState() == DctConstants.State.IDLE) {
818203e588e3c42a81aa8a56f595119c181a63b12caWink Saville
819203e588e3c42a81aa8a56f595119c181a63b12caWink Saville                ArrayList<ApnSetting> waitingApns = buildWaitingApns(apnContext.getApnType(),
820203e588e3c42a81aa8a56f595119c181a63b12caWink Saville                        radioTech);
821cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (waitingApns.isEmpty()) {
822ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    notifyNoData(DcFailCause.MISSING_UNKNOWN_APN, apnContext);
823cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    notifyOffApnsOfAvailability(apnContext.getReason());
824cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("trySetupData: X No APN found retValue=false");
825cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return false;
826cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
827cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setWaitingApns(waitingApns);
828cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) {
829ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        log ("trySetupData: Create from mAllApnSettings : "
830ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                    + apnListToString(mAllApnSettings));
831cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
832cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
833cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
834cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
835cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
836cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("trySetupData: call setupData, waitingApns : "
837cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        + apnListToString(apnContext.getWaitingApns()));
838cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
839203e588e3c42a81aa8a56f595119c181a63b12caWink Saville            boolean retValue = setupData(apnContext, radioTech);
840cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(apnContext.getReason());
841cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
842cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("trySetupData: X retValue=" + retValue);
843cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return retValue;
844cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
845cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
846ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    && apnContext.isConnectable()) {
847cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
848ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
849cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(apnContext.getReason());
850cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log ("trySetupData: X apnContext not 'ready' retValue=false");
851cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
852cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
853c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
854c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
855cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
856cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Disabled apn's still need avail/unavail notificiations - send them out
857cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void notifyOffApnsOfAvailability(String reason) {
858cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
859187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (!mAttached.get() || !apnContext.isReady()) {
860ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) log("notifyOffApnOfAvailability type:" + apnContext.getApnType());
861cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
862cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                            apnContext.getApnType(),
863cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                            PhoneConstants.DataState.DISCONNECTED);
864cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
865ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) {
866187a39f896f88eb6c5e4306d9595546654825976Wink Saville                    log("notifyOffApnsOfAvailability skipped apn due to attached && isReady " +
867cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            apnContext.toString());
868cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
869c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
870c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
871c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
872c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
873cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
874cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * If tearDown is true, this only tears down a CONNECTED session. Presently,
875cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * there is no mechanism for abandoning an CONNECTING session,
876cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * but would likely involve cancelling pending async requests or
877cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * setting a flag or new state to ignore them when they came in
878cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param tearDown true if the underlying DataConnection should be
879cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * disconnected.
880cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param reason reason for the clean up.
8813fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return boolean - true if we did cleanup any connections, false if they
8823fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     *                   were already all disconnected.
883cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
8843fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    protected boolean cleanUpAllConnections(boolean tearDown, String reason) {
885cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("cleanUpAllConnections: tearDown=" + tearDown + " reason=" + reason);
8863fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        boolean didDisconnect = false;
887a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean specificdisable = false;
888a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
889a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (!TextUtils.isEmpty(reason)) {
890a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            specificdisable = reason.equals(Phone.REASON_DATA_SPECIFIC_DISABLED);
891a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
892cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
893cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
8943fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (apnContext.isDisconnected() == false) didDisconnect = true;
895a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (specificdisable) {
896a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IMS)) {
897a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    if (DBG) log("ApnConextType: " + apnContext.getApnType());
898a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    apnContext.setReason(reason);
899a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    cleanUpConnection(tearDown, apnContext);
900a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
901a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
902a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // TODO - only do cleanup if not disconnected
903a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                apnContext.setReason(reason);
904a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                cleanUpConnection(tearDown, apnContext);
905a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
906c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
907cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
908cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopNetStatPoll();
909cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopDataStallAlarm();
910cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
911cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: Do we need mRequestedApnType?
912cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
913a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
914a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("cleanUpConnection: mDisconnectPendingCount = " + mDisconnectPendingCount);
915a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (tearDown && mDisconnectPendingCount == 0) {
916a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyDataDisconnectComplete();
917a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
918a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
919a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
9203fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return didDisconnect;
921cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
922cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
923cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
924cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Cleanup all connections.
925cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
926cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * TODO: Cleanup only a specified connection passed as a parameter.
927cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *       Also, make sure when you clean up a conn, if it is last apply
928cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *       logic as though it is cleanupAllConnections
929cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
930cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param cause for the clean up.
931cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
932cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
933cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
934cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onCleanUpAllConnections(String cause) {
935cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, cause);
936cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
937cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
938a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void cleanUpConnection(boolean tearDown, ApnContext apnContext) {
939cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
940cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
941cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("cleanUpConnection: apn context is null");
942cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
943cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
944cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
945454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac = apnContext.getDcAc();
946cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
947cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("cleanUpConnection: E tearDown=" + tearDown + " reason=" + apnContext.getReason() +
948cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    " apnContext=" + apnContext);
949cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
950cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (tearDown) {
951cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.isDisconnected()) {
952cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // The request is tearDown and but ApnContext is not connected.
953cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // If apnContext is not enabled anymore, break the linkage to the DCAC/DC.
954cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setState(DctConstants.State.IDLE);
955cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (!apnContext.isReady()) {
9564750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                    if (dcac != null) {
9574750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                        dcac.tearDown(apnContext, "", null);
9584750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                    }
959cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setDataConnectionAc(null);
960cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
961cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
962cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Connection is still there. Try to clean up.
963cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (dcac != null) {
964cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (apnContext.getState() != DctConstants.State.DISCONNECTING) {
965cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        boolean disconnectAll = false;
966cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (PhoneConstants.APN_TYPE_DUN.equals(apnContext.getApnType())) {
967a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            // CAF_MSIM is this below condition required.
968a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            // if (PhoneConstants.APN_TYPE_DUN.equals(PhoneConstants.APN_TYPE_DEFAULT)) {
969cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            ApnSetting dunSetting = fetchDunApn();
970cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            if (dunSetting != null &&
971cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                    dunSetting.equals(apnContext.getApnSetting())) {
972cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                if (DBG) log("tearing down dedicated DUN connection");
973cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // we need to tear it down - we brought it up just for dun and
974cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // other people are camped on it and now dun is done.  We need
975cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // to stop using it and let the normal apn list get used to find
976cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // connections for the remaining desired connections
977cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                disconnectAll = true;
978cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            }
979cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
980cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (DBG) {
981cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            log("cleanUpConnection: tearing down" + (disconnectAll ? " all" :""));
982cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
983cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        Message msg = obtainMessage(DctConstants.EVENT_DISCONNECT_DONE, apnContext);
984cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (disconnectAll) {
985ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            apnContext.getDcAc().tearDownAll(apnContext.getReason(), msg);
986cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        } else {
987ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            apnContext.getDcAc()
988cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                .tearDown(apnContext, apnContext.getReason(), msg);
989cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
990cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.setState(DctConstants.State.DISCONNECTING);
991a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        mDisconnectPendingCount++;
992cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
993cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
994cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // apn is connected but no reference to dcac.
995cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // Should not be happen, but reset the state in case.
996cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setState(DctConstants.State.IDLE);
997cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mPhone.notifyDataConnection(apnContext.getReason(),
998cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                                apnContext.getApnType());
999cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1000cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1001cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1002cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // force clean up the data connection.
1003ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac != null) dcac.reqReset();
1004cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setState(DctConstants.State.IDLE);
1005cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1006cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setDataConnectionAc(null);
1007cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1008cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1009ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // Make sure reconnection alarm is cleaned up if there is no ApnContext
1010cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // associated to the connection.
1011cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (dcac != null) {
1012ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            cancelReconnectAlarm(apnContext);
1013c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1014cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
1015cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("cleanUpConnection: X tearDown=" + tearDown + " reason=" + apnContext.getReason() +
1016ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    " apnContext=" + apnContext + " dcac=" + apnContext.getDcAc());
1017cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1018cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1019c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1020cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1021ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Cancels the alarm associated with apnContext.
1022cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1023ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * @param apnContext on which the alarm should be stopped.
1024cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1025ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void cancelReconnectAlarm(ApnContext apnContext) {
1026ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnContext == null) return;
1027cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1028ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        PendingIntent intent = apnContext.getReconnectIntent();
1029cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1030cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (intent != null) {
1031cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                AlarmManager am =
1032cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
1033cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                am.cancel(intent);
1034ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setReconnectIntent(null);
1035cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1036c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1037c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1038cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1039cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param types comma delimited list of APN types
1040cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return array of APN types
1041cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1042cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private String[] parseTypes(String types) {
1043c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String[] result;
1044cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // If unset, set to DEFAULT.
1045cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (types == null || types.equals("")) {
1046c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            result = new String[1];
1047cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result[0] = PhoneConstants.APN_TYPE_ALL;
1048cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1049cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result = types.split(",");
1050c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1051c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
1052c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1053c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1054fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi   private boolean imsiMatches(String imsiDB, String imsiSIM) {
1055fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        // Note: imsiDB value has digit number or 'x' character for seperating USIM information
1056fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        // for MVNO operator. And then digit number is matched at same order and 'x' character
1057fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        // could replace by any digit number.
1058fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        // ex) if imsiDB inserted '310260x10xxxxxx' for GG Operator,
1059fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        //     that means first 6 digits, 8th and 9th digit
1060fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        //     should be set in USIM for GG Operator.
1061fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        int len = imsiDB.length();
1062fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        int idxCompare = 0;
1063fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
1064fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        if (len <= 0) return false;
1065fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        if (len > imsiSIM.length()) return false;
1066fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
1067fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        for (int idx=0; idx<len; idx++) {
1068fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            char c = imsiDB.charAt(idx);
1069fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            if ((c == 'x') || (c == 'X') || (c == imsiSIM.charAt(idx))) {
1070fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                continue;
1071fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            } else {
1072fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                return false;
1073fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            }
1074fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        }
1075fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        return true;
1076fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    }
1077fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
10783262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal    @Override
10793262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal    protected boolean mvnoMatches(IccRecords r, String mvnoType, String mvnoMatchData) {
10803262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        if (mvnoType.equalsIgnoreCase("spn")) {
1081fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            if ((r.getServiceProviderName() != null) &&
10823262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                    r.getServiceProviderName().equalsIgnoreCase(mvnoMatchData)) {
1083fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                return true;
1084fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            }
10853262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        } else if (mvnoType.equalsIgnoreCase("imsi")) {
1086fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            String imsiSIM = r.getIMSI();
10873262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal            if ((imsiSIM != null) && imsiMatches(mvnoMatchData, imsiSIM)) {
1088fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                return true;
1089fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            }
10903262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        } else if (mvnoType.equalsIgnoreCase("gid")) {
1091fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            String gid1 = r.getGid1();
10923262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal            int mvno_match_data_length = mvnoMatchData.length();
109359a71354e0169c7877ffd56d476ddd65ecf5a88dRobert Greenwalt            if ((gid1 != null) && (gid1.length() >= mvno_match_data_length) &&
10943262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                    gid1.substring(0, mvno_match_data_length).equalsIgnoreCase(mvnoMatchData)) {
1095fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                return true;
1096fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            }
1097fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        }
1098fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        return false;
1099fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    }
1100fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
1101fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    private ApnSetting makeApnSetting(Cursor cursor) {
1102fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        String[] types = parseTypes(
1103fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.TYPE)));
1104fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        ApnSetting apn = new ApnSetting(
1105fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID)),
1106fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NUMERIC)),
1107fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NAME)),
1108fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN)),
1109fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1110fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1111fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY))),
1112fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PORT)),
1113fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1114fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1115fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC))),
1116fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1117fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1118fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY))),
1119fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPORT)),
1120fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)),
1121fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)),
1122fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.AUTH_TYPE)),
1123fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                types,
1124fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROTOCOL)),
1125fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(
1126fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        Telephony.Carriers.ROAMING_PROTOCOL)),
1127fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(
1128fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        Telephony.Carriers.CARRIER_ENABLED)) == 1,
11299d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.BEARER)),
11309d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROFILE_ID)),
11319d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(
11329d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                        Telephony.Carriers.MODEM_COGNITIVE)) == 1,
11339d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MAX_CONNS)),
11349d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(
11359d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                        Telephony.Carriers.WAIT_TIME)),
1136e9701717e43cc5aacbcf624f77a53be92350662cw                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MAX_CONNS_TIME)),
11373262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MTU)),
11383262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_TYPE)),
11393262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_MATCH_DATA)));
1140fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        return apn;
1141fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    }
1142fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
1143cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ArrayList<ApnSetting> createApnList(Cursor cursor) {
11443262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        ArrayList<ApnSetting> mnoApns = new ArrayList<ApnSetting>();
11453262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        ArrayList<ApnSetting> mvnoApns = new ArrayList<ApnSetting>();
1146fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        IccRecords r = mIccRecords.get();
1147fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
1148cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor.moveToFirst()) {
1149cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            do {
11503262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                ApnSetting apn = makeApnSetting(cursor);
11513262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                if (apn == null) {
11523262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                    continue;
11533262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                }
11543262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
11553262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                if (apn.hasMvnoParams()) {
11563262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                    if (r != null && mvnoMatches(r, apn.mvnoType, apn.mvnoMatchData)) {
11573262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                        mvnoApns.add(apn);
1158fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    }
1159fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                } else {
11603262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                    mnoApns.add(apn);
1161fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                }
1162cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } while (cursor.moveToNext());
1163cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
11643262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
11653262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        ArrayList<ApnSetting> result = mvnoApns.isEmpty() ? mnoApns : mvnoApns;
1166cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createApnList: X result=" + result);
1167c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
1168c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1169c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1170454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private boolean dataConnectionNotInUse(DcAsyncChannel dcac) {
1171ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("dataConnectionNotInUse: check if dcac is inuse dcac=" + dcac);
1172cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1173ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getDcAc() == dcac) {
1174cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("dataConnectionNotInUse: in use by apnContext=" + apnContext);
1175cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
1176cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1177cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1178cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: Fix retry handling so free DataConnections have empty apnlists.
1179cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Probably move retry handling into DataConnections and reduce complexity
1180cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // of DCT.
1181cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("dataConnectionNotInUse: tearDownAll");
1182ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        dcac.tearDownAll("No connection", null);
1183cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("dataConnectionNotInUse: not in use return true");
1184cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
1185cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1186cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1187454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel findFreeDataConnection() {
1188454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
1189cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac.isInactiveSync() && dataConnectionNotInUse(dcac)) {
1190cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
1191cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("findFreeDataConnection: found free DataConnection=" +
1192ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        " dcac=" + dcac);
1193cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1194ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                return dcac;
1195cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1196cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1197cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("findFreeDataConnection: NO free DataConnection");
1198cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
1199cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1200cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1201203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    private boolean setupData(ApnContext apnContext, int radioTech) {
1202cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setupData: apnContext=" + apnContext);
1203ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnSetting apnSetting;
1204454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac;
1205cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1206ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnSetting = apnContext.getNextWaitingApn();
1207ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnSetting == null) {
1208cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("setupData: return for no apn found!");
1209cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
1210cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1211cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1212231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        int profileId = apnSetting.profileId;
1213231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        if (profileId == 0) {
1214231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen            profileId = getApnProfileID(apnContext.getApnType());
1215231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        }
1216231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen
1217ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        dcac = checkForCompatibleConnectedApnContext(apnContext);
1218ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (dcac != null) {
1219ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // Get the dcacApnSetting for the connection we want to share.
1220ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            ApnSetting dcacApnSetting = dcac.getApnSettingSync();
1221ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcacApnSetting != null) {
1222ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                // Setting is good, so use it.
1223ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnSetting = dcacApnSetting;
1224ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1225ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
1226ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (dcac == null) {
12273fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (isOnlySingleDcAllowed(radioTech)) {
12283fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (isHigherPriorityApnContextActive(apnContext)) {
12293fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (DBG) {
12303fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        log("setupData: Higher priority ApnContext active.  Ignoring call");
12313fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    }
12323fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    return false;
12333fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                }
12343fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
12353fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // Only lower priority calls left.  Disconnect them all in this single PDP case
12363fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // so that we can bring up the requested higher priority call (once we receive
12373fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // repsonse for deactivate request for the calls we are about to disconnect
12383fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (cleanUpAllConnections(true, Phone.REASON_SINGLE_PDN_ARBITRATION)) {
12393fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // If any call actually requested to be disconnected, means we can't
12403fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // bring up this connection yet as we need to wait for those data calls
12413fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // to be disconnected.
12423fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (DBG) log("setupData: Some calls are disconnecting first.  Wait and retry");
12433fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    return false;
12443fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                }
12453fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
12463fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // No other calls are active, so proceed
12473fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (DBG) log("setupData: Single pdp. Continue setting up data call.");
12483fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
12493fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
1250ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            dcac = findFreeDataConnection();
1251cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1252ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac == null) {
1253ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                dcac = createDataConnection();
1254cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1255cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1256ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac == null) {
1257ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) log("setupData: No free DataConnection and couldn't create one, WEIRD");
1258cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
1259cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1260cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1261ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("setupData: dcac=" + dcac + " apnSetting=" + apnSetting);
1262cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1263cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setDataConnectionAc(dcac);
1264ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setApnSetting(apnSetting);
1265cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setState(DctConstants.State.CONNECTING);
1266cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1267cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1268cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Message msg = obtainMessage();
1269cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        msg.what = DctConstants.EVENT_DATA_SETUP_COMPLETE;
1270cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        msg.obj = apnContext;
127112fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        dcac.bringUp(apnContext, getInitialMaxRetry(), profileId, radioTech, mAutoAttachOnCreation,
127212fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao                msg);
1273cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1274cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setupData: initing!");
1275cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
1276cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1277cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1278c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1279cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Handles changes to the APN database.
1280c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1281cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onApnChanged() {
1282cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        DctConstants.State overallState = getOverallState();
1283cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isDisconnected = (overallState == DctConstants.State.IDLE ||
1284cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                overallState == DctConstants.State.FAILED);
1285cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1286cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone instanceof GSMPhone) {
1287cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // The "current" may no longer be valid.  MMS depends on this to send properly. TBD
1288cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ((GSMPhone)mPhone).updateCurrentCarrierInProvider();
1289cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1290cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1291cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: It'd be nice to only do this if the changed entrie(s)
1292cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // match the current operator.
1293cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onApnChanged: createAllApnList and cleanUpAllConnections");
1294cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        createAllApnList();
12955d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi        setInitialAttachApn();
1296cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(!isDisconnected, Phone.REASON_APN_CHANGED);
1297cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isDisconnected) {
1298ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_APN_CHANGED);
1299c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1300c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1301c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1302c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1303cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param cid Connection id provided from RIL.
1304cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return DataConnectionAc associated with specified cid.
1305c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1306454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel findDataConnectionAcByCid(int cid) {
1307454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
1308cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac.getCidSync() == cid) {
1309cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return dcac;
1310cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1311c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1312cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
1313c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1314c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1315cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // TODO: For multiple Active APNs not exactly sure how to do this.
1316c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
1317cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void gotoIdleAndNotifyDataConnection(String reason) {
1318cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("gotoIdleAndNotifyDataConnection: reason=" + reason);
1319cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyDataConnection(reason);
1320cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mActiveApn = null;
1321cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1322cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
13233fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    /**
13243fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * "Active" here means ApnContext isEnabled() and not in FAILED state
13253fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @param apnContext to compare with
13263fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return true if higher priority active apn found
13273fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     */
13283fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean isHigherPriorityApnContextActive(ApnContext apnContext) {
13293fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        for (ApnContext otherContext : mPrioritySortedApnContexts) {
13303fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (apnContext.getApnType().equalsIgnoreCase(otherContext.getApnType())) return false;
13313fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (otherContext.isEnabled() && otherContext.getState() != DctConstants.State.FAILED) {
13323fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                return true;
13333fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
13343fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
13353fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return false;
13363fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    }
13373fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
13383fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    /**
13393fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * Reports if we support multiple connections or not.
13403fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * This is a combination of factors, based on carrier and RAT.
13413fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @param rilRadioTech the RIL Radio Tech currently in use
13423fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return true if only single DataConnection is allowed
13433fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     */
13443fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean isOnlySingleDcAllowed(int rilRadioTech) {
13453fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        int[] singleDcRats = mPhone.getContext().getResources().getIntArray(
13463fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                com.android.internal.R.array.config_onlySingleDcAllowed);
13473fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        boolean onlySingleDcAllowed = false;
13483fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (Build.IS_DEBUGGABLE &&
13493fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                SystemProperties.getBoolean("persist.telephony.test.singleDc", false)) {
13503fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            onlySingleDcAllowed = true;
13513fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
13523fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (singleDcRats != null) {
13533fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            for (int i=0; i < singleDcRats.length && onlySingleDcAllowed == false; i++) {
13543fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (rilRadioTech == singleDcRats[i]) onlySingleDcAllowed = true;
13553fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
13563fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
13573fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
13583fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (DBG) log("isOnlySingleDcAllowed(" + rilRadioTech + "): " + onlySingleDcAllowed);
13593fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return onlySingleDcAllowed;
13603fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    }
13613fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
1362cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1363cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void restartRadio() {
1364cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("restartRadio: ************TURN OFF RADIO**************");
1365cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, Phone.REASON_RADIO_TURNED_OFF);
1366cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().powerOffRadioSafely(this);
1367cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        /* Note: no need to call setRadioPower(true).  Assuming the desired
1368cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * radio power state is still ON (as tracked by ServiceStateTracker),
1369cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * ServiceStateTracker will call setRadioPower when it receives the
1370cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * RADIO_STATE_CHANGED notification for the power off.  And if the
1371cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * desired power state has changed in the interim, we don't want to
1372cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * override it with an unconditional power on.
1373cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         */
1374cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1375cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int reset = Integer.parseInt(SystemProperties.get("net.ppp.reset-by-timeout", "0"));
1376cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        SystemProperties.set("net.ppp.reset-by-timeout", String.valueOf(reset+1));
1377cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1378cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1379cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1380cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Return true if data connection need to be setup after disconnected due to
1381cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * reason.
1382cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1383cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param reason the reason why data is disconnected
1384cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return true if try setup data connection is need for this reason
1385cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
13863fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean retryAfterDisconnected(ApnContext apnContext) {
1387cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean retry = true;
13883fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        String reason = apnContext.getReason();
1389cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
13903fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) ||
13913fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())
13923fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                 && isHigherPriorityApnContextActive(apnContext))) {
1393cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            retry = false;
1394cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1395cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return retry;
1396cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1397cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1398cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void startAlarmForReconnect(int delay, ApnContext apnContext) {
1399cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String apnType = apnContext.getApnType();
140074672e8ee972f12406b72551261b4cc7e0651933Wink Saville
140174672e8ee972f12406b72551261b4cc7e0651933Wink Saville        Intent intent = new Intent(INTENT_RECONNECT_ALARM + "." + apnType);
140274672e8ee972f12406b72551261b4cc7e0651933Wink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, apnContext.getReason());
1403cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, apnType);
1404cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1405a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // Get current sub id.
1406a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        long subId = SubscriptionManager.getDefaultDataSubId();
1407a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
1408a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
140974672e8ee972f12406b72551261b4cc7e0651933Wink Saville        if (DBG) {
141074672e8ee972f12406b72551261b4cc7e0651933Wink Saville            log("startAlarmForReconnect: delay=" + delay + " action=" + intent.getAction()
141174672e8ee972f12406b72551261b4cc7e0651933Wink Saville                    + " apn=" + apnContext);
141274672e8ee972f12406b72551261b4cc7e0651933Wink Saville        }
141374672e8ee972f12406b72551261b4cc7e0651933Wink Saville
1414ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        PendingIntent alarmIntent = PendingIntent.getBroadcast (mPhone.getContext(), 0,
1415ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        intent, PendingIntent.FLAG_UPDATE_CURRENT);
1416ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setReconnectIntent(alarmIntent);
1417ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1418ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                SystemClock.elapsedRealtime() + delay, alarmIntent);
1419ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
1420cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1421ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void startAlarmForRestartTrySetup(int delay, ApnContext apnContext) {
1422ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        String apnType = apnContext.getApnType();
142374672e8ee972f12406b72551261b4cc7e0651933Wink Saville        Intent intent = new Intent(INTENT_RESTART_TRYSETUP_ALARM + "." + apnType);
1424ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        intent.putExtra(INTENT_RESTART_TRYSETUP_ALARM_EXTRA_TYPE, apnType);
1425cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
142674672e8ee972f12406b72551261b4cc7e0651933Wink Saville        if (DBG) {
142774672e8ee972f12406b72551261b4cc7e0651933Wink Saville            log("startAlarmForRestartTrySetup: delay=" + delay + " action=" + intent.getAction()
142874672e8ee972f12406b72551261b4cc7e0651933Wink Saville                    + " apn=" + apnContext);
142974672e8ee972f12406b72551261b4cc7e0651933Wink Saville        }
1430cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        PendingIntent alarmIntent = PendingIntent.getBroadcast (mPhone.getContext(), 0,
1431cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                        intent, PendingIntent.FLAG_UPDATE_CURRENT);
1432ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setReconnectIntent(alarmIntent);
1433ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1434cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                SystemClock.elapsedRealtime() + delay, alarmIntent);
1435cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1436cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1437ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void notifyNoData(DcFailCause lastFailCauseCode,
1438cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                              ApnContext apnContext) {
1439cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log( "notifyNoData: type=" + apnContext.getApnType());
1440cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (lastFailCauseCode.isPermanentFail()
1441cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            && (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT))) {
1442cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
1443cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1444cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1445cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1446cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onRecordsLoaded() {
1447cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onRecordsLoaded: createAllApnList");
144812fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        mAutoAttachOnCreationConfig = mPhone.getContext().getResources()
144912fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao                .getBoolean(com.android.internal.R.bool.config_auto_attach_data_on_creation);
1450cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        createAllApnList();
14515d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi        setInitialAttachApn();
145222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPhone.mCi.getRadioState().isOn()) {
1453cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRecordsLoaded: notifying data availability");
1454cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_SIM_LOADED);
1455cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1456ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(Phone.REASON_SIM_LOADED);
1457cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1458cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1459cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1460cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onSetDependencyMet(String apnType, boolean met) {
1461cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // don't allow users to tweak hipri to work around default dependency not met
1462cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_HIPRI.equals(apnType)) return;
1463cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1464cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1465cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
1466cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onSetDependencyMet: ApnContext not found in onSetDependencyMet(" +
1467cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnType + ", " + met + ")");
1468cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
1469cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1470cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        applyNewState(apnContext, apnContext.isEnabled(), met);
1471cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_DEFAULT.equals(apnType)) {
1472cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // tie actions on default to similar actions on HIPRI regarding dependencyMet
1473cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext = mApnContexts.get(PhoneConstants.APN_TYPE_HIPRI);
1474cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext != null) applyNewState(apnContext, apnContext.isEnabled(), met);
1475cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1476cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1477c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1478cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void applyNewState(ApnContext apnContext, boolean enabled, boolean met) {
1479cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean cleanup = false;
1480cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean trySetup = false;
1481cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
1482cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("applyNewState(" + apnContext.getApnType() + ", " + enabled +
1483cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    "(" + apnContext.isEnabled() + "), " + met + "(" +
1484cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.getDependencyMet() +"))");
1485cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1486cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext.isReady()) {
1487305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt            cleanup = true;
14882428693913ae731d4ace3414429f5e91af24ea36Wink Saville            if (enabled && met) {
14892428693913ae731d4ace3414429f5e91af24ea36Wink Saville                DctConstants.State state = apnContext.getState();
14902428693913ae731d4ace3414429f5e91af24ea36Wink Saville                switch(state) {
14912428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case CONNECTING:
14922428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case SCANNING:
14932428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case CONNECTED:
14942428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case DISCONNECTING:
14952428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // We're "READY" and active so just return
14962428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        if (DBG) log("applyNewState: 'ready' so return");
14972428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        return;
14982428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case IDLE:
14992428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // fall through: this is unexpected but if it happens cleanup and try setup
15002428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case FAILED:
15012428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case RETRYING: {
15022428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // We're "READY" but not active so disconnect (cleanup = true) and
15032428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // connect (trySetup = true) to be sure we retry the connection.
15042428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        trySetup = true;
15052428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        apnContext.setReason(Phone.REASON_DATA_ENABLED);
15062428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        break;
15072428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    }
15082428693913ae731d4ace3414429f5e91af24ea36Wink Saville                }
1509305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt            } else if (met) {
1510cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setReason(Phone.REASON_DATA_DISABLED);
1511305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // If ConnectivityService has disabled this network, stop trying to bring
1512305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // it up, but do not tear it down - ConnectivityService will do that
1513305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // directly by talking with the DataConnection.
1514305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                cleanup = false;
1515cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1516cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_UNMET);
1517cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1518cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1519cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (enabled && met) {
1520cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apnContext.isEnabled()) {
1521cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_MET);
1522cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1523cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setReason(Phone.REASON_DATA_ENABLED);
1524c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1525cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apnContext.getState() == DctConstants.State.FAILED) {
1526cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setState(DctConstants.State.IDLE);
1527cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1528cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                trySetup = true;
1529cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1530cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1531cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setEnabled(enabled);
1532cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setDependencyMet(met);
1533cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cleanup) cleanUpConnection(true, apnContext);
1534cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (trySetup) trySetupData(apnContext);
1535cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1536c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1537454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel checkForCompatibleConnectedApnContext(ApnContext apnContext) {
1538cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String apnType = apnContext.getApnType();
1539cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnSetting dunSetting = null;
1540cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1541cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_DUN.equals(apnType)) {
1542cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            dunSetting = fetchDunApn();
1543cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1544ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) {
1545ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            log("checkForCompatibleConnectedApnContext: apnContext=" + apnContext );
1546ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
1547cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1548454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel potentialDcac = null;
1549ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnContext potentialApnCtx = null;
1550ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        for (ApnContext curApnCtx : mApnContexts.values()) {
1551454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel curDcac = curApnCtx.getDcAc();
1552a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("curDcac: " + curDcac);
1553ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (curDcac != null) {
1554ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                ApnSetting apnSetting = curApnCtx.getApnSetting();
1555a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("apnSetting: " + apnSetting);
1556cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (dunSetting != null) {
1557cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (dunSetting.equals(apnSetting)) {
1558ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        switch (curApnCtx.getState()) {
1559cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            case CONNECTED:
1560cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                if (DBG) {
1561ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                    log("checkForCompatibleConnectedApnContext:"
1562ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                            + " found dun conn=" + curDcac
1563ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                            + " curApnCtx=" + curApnCtx);
1564cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                }
1565ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                return curDcac;
1566ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            case RETRYING:
1567cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            case CONNECTING:
1568ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                potentialDcac = curDcac;
1569ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                potentialApnCtx = curApnCtx;
1570cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            default:
1571cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // Not connected, potential unchanged
1572cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                break;
1573cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
1574cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1575cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else if (apnSetting != null && apnSetting.canHandleType(apnType)) {
1576ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    switch (curApnCtx.getState()) {
1577cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        case CONNECTED:
1578cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            if (DBG) {
1579ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                log("checkForCompatibleConnectedApnContext:"
1580ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        + " found canHandle conn=" + curDcac
1581ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        + " curApnCtx=" + curApnCtx);
1582cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            }
1583ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            return curDcac;
1584ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        case RETRYING:
1585cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        case CONNECTING:
1586ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            potentialDcac = curDcac;
1587ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            potentialApnCtx = curApnCtx;
1588cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        default:
1589cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            // Not connected, potential unchanged
1590cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            break;
1591cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1592cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1593ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            } else {
1594ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) {
1595ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    log("checkForCompatibleConnectedApnContext: not conn curApnCtx=" + curApnCtx);
1596ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                }
1597cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1598cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1599ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (potentialDcac != null) {
1600cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
1601ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                log("checkForCompatibleConnectedApnContext: found potential conn=" + potentialDcac
1602ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        + " curApnCtx=" + potentialApnCtx);
1603cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1604ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            return potentialDcac;
1605cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1606c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1607ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("checkForCompatibleConnectedApnContext: NO conn apnContext=" + apnContext);
1608cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
1609cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1610c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1611cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1612cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onEnableApn(int apnId, int enabled) {
1613cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnIdToType(apnId));
1614cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
1615cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onEnableApn(" + apnId + ", " + enabled + "): NO ApnContext");
1616cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
1617cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1618cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO change our retry manager to use the appropriate numbers for the new APN
1619cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onEnableApn: apnContext=" + apnContext + " call applyNewState");
1620cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        applyNewState(apnContext, enabled == DctConstants.ENABLED, apnContext.getDependencyMet());
1621cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1622c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1623cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1624cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // TODO: We shouldnt need this.
1625cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean onTrySetupData(String reason) {
1626cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onTrySetupData: reason=" + reason);
1627ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(reason);
1628cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
1629cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1630c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1631cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean onTrySetupData(ApnContext apnContext) {
1632cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onTrySetupData: apnContext=" + apnContext);
1633cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return trySetupData(apnContext);
1634cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1635c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1636cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1637cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onRoamingOff() {
1638cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onRoamingOff");
1639c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1640cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mUserDataEnabled == false) return;
1641c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1642cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getDataOnRoamingEnabled() == false) {
1643cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_OFF);
1644ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_ROAMING_OFF);
1645cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1646cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_ROAMING_OFF);
1647cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1648cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1649cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1650cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1651cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onRoamingOn() {
1652cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mUserDataEnabled == false) return;
1653cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1654cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getDataOnRoamingEnabled()) {
1655cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRoamingOn: setup data on roaming");
1656ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_ROAMING_ON);
1657cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_ROAMING_ON);
1658cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1659cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRoamingOn: Tear down data connection on roaming.");
1660cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpAllConnections(true, Phone.REASON_ROAMING_ON);
1661cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
1662cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1663cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1664cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1665cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1666cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onRadioAvailable() {
1667cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onRadioAvailable");
1668cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
1669cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
1670cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
1671cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // setState(DctConstants.State.CONNECTED);
1672cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(null);
1673cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1674cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("onRadioAvailable: We're on the simulator; assuming data is connected");
1675cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1676cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1677cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
1678cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (r != null && r.getRecordsLoaded()) {
1679cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(null);
1680cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1681cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1682cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getOverallState() != DctConstants.State.IDLE) {
1683cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpConnection(true, null);
1684cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1685cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1686cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1687cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1688cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onRadioOffOrNotAvailable() {
1689cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Make sure our reconnect delay starts at the initial value
1690cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // next time the radio comes on
1691cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1692cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mReregisterOnReconnectFailure = false;
1693cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1694cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
1695cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
1696cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
1697cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("We're on the simulator; assuming radio off is meaningless");
1698cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1699cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRadioOffOrNotAvailable: is off and clean up all connections");
1700cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpAllConnections(false, Phone.REASON_RADIO_TURNED_OFF);
1701cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1702cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyOffApnsOfAvailability(null);
1703cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1704cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1705c9b81a0c05128694c617fcdd67e73821895822feWink Saville    @Override
1706c9b81a0c05128694c617fcdd67e73821895822feWink Saville    protected void completeConnection(ApnContext apnContext) {
1707c9b81a0c05128694c617fcdd67e73821895822feWink Saville        boolean isProvApn = apnContext.isProvisioningApn();
1708c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1709c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (DBG) log("completeConnection: successful, notify the world apnContext=" + apnContext);
1710c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1711c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (mIsProvisioning && !TextUtils.isEmpty(mProvisioningUrl)) {
1712c9b81a0c05128694c617fcdd67e73821895822feWink Saville            if (DBG) {
1713c9b81a0c05128694c617fcdd67e73821895822feWink Saville                log("completeConnection: MOBILE_PROVISIONING_ACTION url="
1714c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        + mProvisioningUrl);
1715c9b81a0c05128694c617fcdd67e73821895822feWink Saville            }
1716c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt            Intent newIntent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN,
1717c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt                    Intent.CATEGORY_APP_BROWSER);
1718c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt            newIntent.setData(Uri.parse(mProvisioningUrl));
1719c9b81a0c05128694c617fcdd67e73821895822feWink Saville            newIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
1720c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    Intent.FLAG_ACTIVITY_NEW_TASK);
1721c9b81a0c05128694c617fcdd67e73821895822feWink Saville            try {
1722c9b81a0c05128694c617fcdd67e73821895822feWink Saville                mPhone.getContext().startActivity(newIntent);
1723c9b81a0c05128694c617fcdd67e73821895822feWink Saville            } catch (ActivityNotFoundException e) {
1724c9b81a0c05128694c617fcdd67e73821895822feWink Saville                loge("completeConnection: startActivityAsUser failed" + e);
1725c9b81a0c05128694c617fcdd67e73821895822feWink Saville            }
1726c9b81a0c05128694c617fcdd67e73821895822feWink Saville        }
1727c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mIsProvisioning = false;
1728c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mProvisioningUrl = null;
1729c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1730c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1731c9b81a0c05128694c617fcdd67e73821895822feWink Saville        startNetStatPoll();
1732c9b81a0c05128694c617fcdd67e73821895822feWink Saville        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
1733c9b81a0c05128694c617fcdd67e73821895822feWink Saville    }
1734c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1735ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
1736ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * A SETUP (aka bringUp) has completed, possibly with an error. If
1737ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * there is an error this method will call {@link #onDataSetupCompleteError}.
1738ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
1739cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1740cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onDataSetupComplete(AsyncResult ar) {
1741608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt
1742ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        DcFailCause cause = DcFailCause.UNKNOWN;
1743cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean handleError = false;
1744cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = null;
1745cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1746cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(ar.userObj instanceof ApnContext){
1747cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext = (ApnContext)ar.userObj;
1748cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1749cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            throw new RuntimeException("onDataSetupComplete: No apnContext");
1750cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1751cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1752cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (ar.exception == null) {
1753454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = apnContext.getDcAc();
1754cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1755cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (RADIO_TESTS) {
1756cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Note: To change radio.test.onDSC.null.dcac from command line you need to
1757cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // adb root and adb remount and from the command line you can only change the
1758cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // value to 1 once. To change it a second time you can reboot or execute
1759cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // adb shell stop and then adb shell start. The command line to set the value is:
1760ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink 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');"
1761cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ContentResolver cr = mPhone.getContext().getContentResolver();
1762cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                String radioTestProperty = "radio.test.onDSC.null.dcac";
1763cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (Settings.System.getInt(cr, radioTestProperty, 0) == 1) {
1764cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: " + radioTestProperty +
1765cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            " is true, set dcac to null and reset property to false");
1766cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    dcac = null;
1767cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    Settings.System.putInt(cr, radioTestProperty, 0);
1768cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: " + radioTestProperty + "=" +
1769cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            Settings.System.getInt(mPhone.getContext().getContentResolver(),
1770cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                    radioTestProperty, -1));
1771cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1772c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1773cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac == null) {
1774cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("onDataSetupComplete: no connection to DC, handle as error");
1775ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                cause = DcFailCause.CONNECTION_TO_DATACONNECTIONAC_BROKEN;
1776cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                handleError = true;
1777cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1778cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ApnSetting apn = apnContext.getApnSetting();
1779cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
1780cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: success apn=" + (apn == null ? "unknown" : apn.apn));
1781cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1782cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn != null && apn.proxy != null && apn.proxy.length() != 0) {
1783cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    try {
1784cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        String port = apn.port;
1785cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (TextUtils.isEmpty(port)) port = "8080";
17869c180aedfc9f0d20525c0128487d3500e6c0a715Jason Monk                        ProxyInfo proxy = new ProxyInfo(apn.proxy,
1787cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                Integer.parseInt(port), null);
1788cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        dcac.setLinkPropertiesHttpProxySync(proxy);
1789cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    } catch (NumberFormatException e) {
1790cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        loge("onDataSetupComplete: NumberFormatException making ProxyProperties (" +
1791cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                apn.port + "): " + e);
1792cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1793cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1794cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1795cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // everything is setup
1796cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if(TextUtils.equals(apnContext.getApnType(),PhoneConstants.APN_TYPE_DEFAULT)) {
1797ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "true");
179822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mCanSetPreferApn && mPreferredApn == null) {
1799cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (DBG) log("onDataSetupComplete: PREFERED APN is null");
1800cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mPreferredApn = apn;
1801cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (mPreferredApn != null) {
1802cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            setPreferredApn(mPreferredApn.id);
1803cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
1804cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1805cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1806ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
1807cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1808c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1809c9b81a0c05128694c617fcdd67e73821895822feWink Saville                // A connection is setup
1810c9b81a0c05128694c617fcdd67e73821895822feWink Saville                apnContext.setState(DctConstants.State.CONNECTED);
1811c9b81a0c05128694c617fcdd67e73821895822feWink Saville                boolean isProvApn = apnContext.isProvisioningApn();
1812c9b81a0c05128694c617fcdd67e73821895822feWink Saville                if ((!isProvApn) || mIsProvisioning) {
1813c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // Complete the connection normally notifying the world we're connected.
1814c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // We do this if this isn't a special provisioning apn or if we've been
1815c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // told its time to provision.
1816c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    completeConnection(apnContext);
1817c9b81a0c05128694c617fcdd67e73821895822feWink Saville                } else {
1818c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // This is a provisioning APN that we're reporting as connected. Later
1819c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // when the user desires to upgrade this to a "default" connection,
1820c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // mIsProvisioning == true, we'll go through the code path above.
1821c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // mIsProvisioning becomes true when CMD_ENABLE_MOBILE_PROVISIONING
1822c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // is sent to the DCT.
1823c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    if (DBG) {
1824c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        log("onDataSetupComplete: successful, BUT send connected to prov apn as"
1825c9b81a0c05128694c617fcdd67e73821895822feWink Saville                                + " mIsProvisioning:" + mIsProvisioning + " == false"
1826c9b81a0c05128694c617fcdd67e73821895822feWink Saville                                + " && (isProvisioningApn:" + isProvApn + " == true");
1827c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    }
1828c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1829c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    Intent intent = new Intent(
1830c9b81a0c05128694c617fcdd67e73821895822feWink Saville                            TelephonyIntents.ACTION_DATA_CONNECTION_CONNECTED_TO_PROVISIONING_APN);
1831c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    intent.putExtra(PhoneConstants.DATA_APN_KEY, apnContext.getApnSetting().apn);
1832c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnContext.getApnType());
1833c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1834c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    String apnType = apnContext.getApnType();
1835c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    LinkProperties linkProperties = getLinkProperties(apnType);
1836c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    if (linkProperties != null) {
1837c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties);
1838c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        String iface = linkProperties.getInterfaceName();
1839c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        if (iface != null) {
1840c9b81a0c05128694c617fcdd67e73821895822feWink Saville                            intent.putExtra(PhoneConstants.DATA_IFACE_NAME_KEY, iface);
1841c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        }
1842c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    }
1843608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                    NetworkCapabilities networkCapabilities = getNetworkCapabilities(apnType);
184496cce86cf08e37e0f09ed5057b1196e26b302743Robert Greenwalt                    if (networkCapabilities != null) {
184596cce86cf08e37e0f09ed5057b1196e26b302743Robert Greenwalt                        intent.putExtra(PhoneConstants.DATA_NETWORK_CAPABILITIES_KEY,
184696cce86cf08e37e0f09ed5057b1196e26b302743Robert Greenwalt                                networkCapabilities);
1847c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    }
1848c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1849c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    mPhone.getContext().sendBroadcastAsUser(intent, UserHandle.ALL);
1850c9b81a0c05128694c617fcdd67e73821895822feWink Saville                }
1851c9b81a0c05128694c617fcdd67e73821895822feWink Saville                if (DBG) {
1852c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    log("onDataSetupComplete: SETUP complete type=" + apnContext.getApnType()
1853c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        + ", reason:" + apnContext.getReason());
1854c9b81a0c05128694c617fcdd67e73821895822feWink Saville                }
1855c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1856cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1857ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            cause = (DcFailCause) (ar.result);
1858cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
1859cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ApnSetting apn = apnContext.getApnSetting();
1860cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log(String.format("onDataSetupComplete: error apn=%s cause=%s",
1861cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        (apn == null ? "unknown" : apn.apn), cause));
1862c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1863cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cause.isEventLoggable()) {
1864cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Log this failure to the Event Logs.
1865cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                int cid = getCellLocationId();
1866cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                EventLog.writeEvent(EventLogTags.PDP_SETUP_FAIL,
1867cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        cause.ordinal(), cid, TelephonyManager.getDefault().getNetworkType());
1868c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
18690742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela            ApnSetting apn = apnContext.getApnSetting();
18700742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela            mPhone.notifyPreciseDataConnectionFailed(apnContext.getReason(),
18710742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela                    apnContext.getApnType(), apn != null ? apn.apn : "unknown", cause.toString());
1872cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1873cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Count permanent failures and remove the APN we just tried
1874cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cause.isPermanentFail()) apnContext.decWaitingApnsPermFailCount();
1875cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1876cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.removeWaitingApn(apnContext.getApnSetting());
1877cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
1878cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log(String.format("onDataSetupComplete: WaitingApns.size=%d" +
1879cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        " WaitingApnsPermFailureCountDown=%d",
1880cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.getWaitingApns().size(),
1881cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.getWaitingApnsPermFailCount()));
1882c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1883cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            handleError = true;
1884cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1885cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1886cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (handleError) {
1887ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            onDataSetupCompleteError(ar);
1888ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
1889a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1890a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        /* If flag is set to false after SETUP_DATA_CALL is invoked, we need
1891a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         * to clean data connections.
1892a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         */
1893a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (!mInternalDataEnabled) {
1894a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            cleanUpAllConnections(null);
1895a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1896a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1897ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
1898cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1899ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
1900ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville     * @return number of milli-seconds to delay between trying apns'
1901ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville     */
1902ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville    private int getApnDelay() {
1903ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        if (mFailFast) {
1904ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville            return SystemProperties.getInt("persist.radio.apn_ff_delay",
1905ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville                    APN_FAIL_FAST_DELAY_DEFAULT_MILLIS);
1906ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        } else {
1907ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville            return SystemProperties.getInt("persist.radio.apn_delay", APN_DELAY_DEFAULT_MILLIS);
1908ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        }
1909ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville    }
1910ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville
1911ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville    /**
1912ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Error has occurred during the SETUP {aka bringUP} request and the DCT
1913ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * should either try the next waiting APN or start over from the
1914ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * beginning if the list is empty. Between each SETUP request there will
1915ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville     * be a delay defined by {@link #getApnDelay()}.
1916ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
1917ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    @Override
1918ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    protected void onDataSetupCompleteError(AsyncResult ar) {
1919ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        String reason = "";
1920ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnContext apnContext = null;
1921ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
1922ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if(ar.userObj instanceof ApnContext){
1923ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext = (ApnContext)ar.userObj;
1924ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        } else {
1925ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            throw new RuntimeException("onDataSetupCompleteError: No apnContext");
1926ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
1927ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
1928ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // See if there are more APN's to try
1929ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnContext.getWaitingApns().isEmpty()) {
1930ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext.setState(DctConstants.State.FAILED);
1931ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType());
1932ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
1933ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext.setDataConnectionAc(null);
1934ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
1935ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getWaitingApnsPermFailCount() == 0) {
1936ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) {
1937017166876a51eda9ae6b3254119023604e249bc5Wink Saville                    log("onDataSetupCompleteError: All APN's had permanent failures, stop retrying");
1938c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1939cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1940e056c8263473f67dc78630f5535c3664fabacd23Wink Saville                int delay = getApnDelay();
1941ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) {
1942da1dd2e1bccb6141109a65d4e40253f39c405537Wink Saville                    log("onDataSetupCompleteError: Not all APN's had permanent failures delay="
1943da1dd2e1bccb6141109a65d4e40253f39c405537Wink Saville                            + delay);
1944ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                }
1945017166876a51eda9ae6b3254119023604e249bc5Wink Saville                startAlarmForRestartTrySetup(delay, apnContext);
1946c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1947ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        } else {
1948da1dd2e1bccb6141109a65d4e40253f39c405537Wink Saville            if (DBG) log("onDataSetupCompleteError: Try next APN");
1949ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext.setState(DctConstants.State.SCANNING);
1950ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // Wait a bit before trying the next APN, so that
1951ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // we're not tying up the RIL command channel
1952ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville            startAlarmForReconnect(getApnDelay(), apnContext);
1953c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1954c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1955c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1956c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1957cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Called when EVENT_DISCONNECT_DONE is received.
1958c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1959cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1960cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onDisconnectDone(int connId, AsyncResult ar) {
1961cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = null;
1962cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1963cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (ar.userObj instanceof ApnContext) {
1964cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext = (ApnContext) ar.userObj;
1965cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1966cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onDisconnectDone: Invalid ar in onDisconnectDone, ignore");
1967cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
1968c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1969c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1970cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE apnContext=" + apnContext);
1971cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setState(DctConstants.State.IDLE);
1972cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1973cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1974cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1975cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // if all data connection are gone, check whether Airplane mode request was
1976cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // pending.
1977cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isDisconnected()) {
1978cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPhone.getServiceStateTracker().processPendingRadioPowerOffAfterDataOff()) {
1979449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                if(DBG) log("onDisconnectDone: radio will be turned off, no retries");
1980cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Radio will be turned off. No need to retry data setup
1981cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setApnSetting(null);
1982cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setDataConnectionAc(null);
1983a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1984a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // Need to notify disconnect as well, in the case of switching Airplane mode.
1985a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // Otherwise, it would cause 30s delayed to turn on Airplane mode.
1986a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mDisconnectPendingCount > 0)
1987a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mDisconnectPendingCount--;
1988a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1989a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mDisconnectPendingCount == 0) {
1990a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    notifyDataDisconnectComplete();
1991a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    notifyAllDataDisconnected();
1992a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1993cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return;
1994cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1995c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1996c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1997cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // If APN is still enabled, try to bring it back up automatically
19983fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (mAttached.get() && apnContext.isReady() && retryAfterDisconnected(apnContext)) {
1999ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
2000cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Wait a bit before trying the next APN, so that
2001cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // we're not tying up the RIL command channel.
2002cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // This also helps in any external dependency to turn off the context.
2003449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            if(DBG) log("onDisconnectDone: attached, ready and retry after disconnect");
2004ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville            startAlarmForReconnect(getApnDelay(), apnContext);
2005c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
2006449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            boolean restartRadioAfterProvisioning = mPhone.getContext().getResources().getBoolean(
2007449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                    com.android.internal.R.bool.config_restartRadioAfterProvisioning);
2008449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville
2009449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            if (apnContext.isProvisioningApn() && restartRadioAfterProvisioning) {
2010449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                log("onDisconnectDone: restartRadio after provisioning");
2011449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                restartRadio();
2012449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            }
2013cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setApnSetting(null);
2014cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setDataConnectionAc(null);
20153fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())) {
2016449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                if(DBG) log("onDisconnectDone: isOnlySigneDcAllowed true so setup single apn");
20173fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                setupDataOnConnectableApns(Phone.REASON_SINGLE_PDN_ARBITRATION);
2018449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            } else {
2019449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                if(DBG) log("onDisconnectDone: not retrying");
20203fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
2021c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2022a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2023a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mDisconnectPendingCount > 0)
2024a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mDisconnectPendingCount--;
2025a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2026a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mDisconnectPendingCount == 0) {
2027a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyDataDisconnectComplete();
2028a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
2029a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2030a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2031c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2032c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2033ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
2034ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Called when EVENT_DISCONNECT_DC_RETRYING is received.
2035ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
2036ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    @Override
2037ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    protected void onDisconnectDcRetrying(int connId, AsyncResult ar) {
2038ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // We could just do this in DC!!!
2039ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnContext apnContext = null;
2040ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
2041ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (ar.userObj instanceof ApnContext) {
2042ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext = (ApnContext) ar.userObj;
2043ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        } else {
2044ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            loge("onDisconnectDcRetrying: Invalid ar in onDisconnectDone, ignore");
2045ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            return;
2046ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
2047ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
2048ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setState(DctConstants.State.RETRYING);
2049ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if(DBG) log("onDisconnectDcRetrying: apnContext=" + apnContext);
2050ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
2051ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
2052ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
2053ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
2054c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2055cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2056cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onVoiceCallStarted() {
2057cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onVoiceCallStarted");
2058ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        mInVoiceCall = true;
2059cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnected() && ! mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
2060cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onVoiceCallStarted stop polling");
2061cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            stopNetStatPoll();
2062cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            stopDataStallAlarm();
2063cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
2064c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2065c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2066c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2067cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2068cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onVoiceCallEnded() {
2069cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onVoiceCallEnded");
2070ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        mInVoiceCall = false;
2071cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnected()) {
2072cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
2073cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                startNetStatPoll();
2074cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
2075cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
2076cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
2077cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // clean slate after call end.
2078cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                resetPollStats();
2079c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2080c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2081cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // reset reconnect timer
2082ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(Phone.REASON_VOICE_CALL_ENDED);
2083c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2084c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2085cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2086cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onCleanUpConnection(boolean tearDown, int apnId, String reason) {
2087cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onCleanUpConnection");
2088cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnIdToType(apnId));
2089cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
2090cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setReason(reason);
2091cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpConnection(tearDown, apnContext);
2092c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2093c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2094c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2095cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2096cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean isConnected() {
2097cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
2098ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getState() == DctConstants.State.CONNECTED) {
2099cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // At least one context is connected, return true
2100cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return true;
2101c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2102c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2103cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // There are not any contexts connected, return false
2104cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return false;
2105c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2106c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2107cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2108cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isDisconnected() {
2109cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
2110cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!apnContext.isDisconnected()) {
2111cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // At least one context was not disconnected return false
2112cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
2113cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2114c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2115cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // All contexts were disconnected so return true
2116cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
2117c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2118c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2119cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2120cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void notifyDataConnection(String reason) {
2121cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("notifyDataConnection: reason=" + reason);
2122cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
2123187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (mAttached.get() && apnContext.isReady()) {
2124187a39f896f88eb6c5e4306d9595546654825976Wink Saville                if (DBG) log("notifyDataConnection: type:" + apnContext.getApnType());
2125cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
2126cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.getApnType());
2127cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2128c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2129cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyOffApnsOfAvailability(reason);
2130c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2131c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2132c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
2133cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Based on the sim operator numeric, create a list for all possible
2134cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Data Connections and setup the preferredApn.
2135c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
2136cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void createAllApnList() {
2137ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mAllApnSettings = new ArrayList<ApnSetting>();
2138cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
2139cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String operator = (r != null) ? r.getOperatorNumeric() : "";
2140cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (operator != null) {
2141cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            String selection = "numeric = '" + operator + "'";
2142cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // query only enabled apn.
2143cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // carrier_enabled : 1 means enabled apn, 0 disabled apn.
21449d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan            // selection += " and carrier_enabled = 1";
2145cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: selection=" + selection);
2146cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2147cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            Cursor cursor = mPhone.getContext().getContentResolver().query(
2148cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    Telephony.Carriers.CONTENT_URI, null, selection, null, null);
2149cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2150cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cursor != null) {
2151cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (cursor.getCount() > 0) {
2152ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    mAllApnSettings = createApnList(cursor);
2153cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2154cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cursor.close();
2155cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2156c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2157c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
215876f43316a5a6082d601bffd4b6898d0bd81e11fcram        addEmergencyApnSetting();
215976f43316a5a6082d601bffd4b6898d0bd81e11fcram
2160ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings.isEmpty()) {
2161cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: No APN found for carrier: " + operator);
2162cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPreferredApn = null;
2163ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // TODO: What is the right behavior?
2164cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            //notifyNoData(DataConnection.FailCause.MISSING_UNKNOWN_APN);
2165c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
2166cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPreferredApn = getPreferredApn();
2167cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator)) {
2168cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn = null;
2169cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                setPreferredApn(-1);
2170cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2171cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: mPreferredApn=" + mPreferredApn);
2172c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2173ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("createAllApnList: X mAllApnSettings=" + mAllApnSettings);
21749d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan
21759d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        setDataProfilesAsNeeded();
2176c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2177c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2178ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /** Return the DC AsyncChannel for the new data connection */
2179454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel createDataConnection() {
2180cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createDataConnection E");
2181cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2182cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int id = mUniqueIdGenerator.getAndIncrement();
2183ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        DataConnection conn = DataConnection.makeDataConnection(mPhone, id,
2184ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                                this, mDcTesterFailBringUpAll, mDcc);
2185cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mDataConnections.put(id, conn);
2186454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac = new DcAsyncChannel(conn, LOG_TAG);
2187cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int status = dcac.fullyConnectSync(mPhone.getContext(), this, conn.getHandler());
2188cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (status == AsyncChannel.STATUS_SUCCESSFUL) {
2189ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            mDataConnectionAcHashMap.put(dcac.getDataConnectionIdSync(), dcac);
2190c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
2191ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            loge("createDataConnection: Could not connect to dcac=" + dcac + " status=" + status);
2192c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2193cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2194cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createDataConnection() X id=" + id + " dc=" + conn);
2195ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        return dcac;
2196c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2197c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2198cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void destroyDataConnections() {
2199cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(mDataConnections != null) {
2200cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("destroyDataConnections: clear mDataConnectionList");
2201cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mDataConnections.clear();
2202cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2203cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("destroyDataConnections: mDataConnecitonList is empty, ignore");
2204c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2205c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2206c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2207c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
2208cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Build a list of APNs to be used to create PDP's.
2209c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
2210cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param requestedApnType
2211cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return waitingApns list to be used to create PDP
2212cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *          error when waitingApns.isEmpty()
2213c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
2214203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    private ArrayList<ApnSetting> buildWaitingApns(String requestedApnType, int radioTech) {
2215cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("buildWaitingApns: E requestedApnType=" + requestedApnType);
2216cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ArrayList<ApnSetting> apnList = new ArrayList<ApnSetting>();
2217cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2218cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (requestedApnType.equals(PhoneConstants.APN_TYPE_DUN)) {
2219cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ApnSetting dun = fetchDunApn();
2220cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dun != null) {
2221cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnList.add(dun);
2222cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: X added APN_TYPE_DUN apnList=" + apnList);
2223cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return apnList;
2224c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2225c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2226c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2227cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
2228cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String operator = (r != null) ? r.getOperatorNumeric() : "";
2229c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2230cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // This is a workaround for a bug (7305641) where we don't failover to other
2231cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // suitable APNs if our preferred APN fails.  On prepaid ATT sims we need to
2232cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // failover to a provisioning APN, but once we've used their default data
2233cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // connection we are locked to it for life.  This change allows ATT devices
2234cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // to say they don't want to use preferred at all.
2235cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean usePreferred = true;
2236cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        try {
2237cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            usePreferred = ! mPhone.getContext().getResources().getBoolean(com.android.
2238cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    internal.R.bool.config_dontPreferApn);
2239cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } catch (Resources.NotFoundException e) {
2240cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("buildWaitingApns: usePreferred NotFoundException set to true");
2241cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            usePreferred = true;
2242cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2243cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
2244cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("buildWaitingApns: usePreferred=" + usePreferred
224522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    + " canSetPreferApn=" + mCanSetPreferApn
2246cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " mPreferredApn=" + mPreferredApn
2247cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " operator=" + operator + " radioTech=" + radioTech
2248cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " IccRecords r=" + r);
2249cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2250c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
225122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (usePreferred && mCanSetPreferApn && mPreferredApn != null &&
2252cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn.canHandleType(requestedApnType)) {
2253cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
2254cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("buildWaitingApns: Preferred APN:" + operator + ":"
2255cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        + mPreferredApn.numeric + ":" + mPreferredApn);
2256cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2257cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPreferredApn.numeric.equals(operator)) {
2258cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (mPreferredApn.bearer == 0 || mPreferredApn.bearer == radioTech) {
2259cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnList.add(mPreferredApn);
2260cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
2261cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return apnList;
2262cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2263cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("buildWaitingApns: no preferred APN");
2264cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    setPreferredApn(-1);
2265cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mPreferredApn = null;
2266c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
2267cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
2268cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: no preferred APN");
2269cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                setPreferredApn(-1);
2270cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn = null;
2271c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2272c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2273ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings != null) {
2274ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (DBG) log("buildWaitingApns: mAllApnSettings=" + mAllApnSettings);
2275ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for (ApnSetting apn : mAllApnSettings) {
2276cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: apn=" + apn);
2277cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn.canHandleType(requestedApnType)) {
2278cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (apn.bearer == 0 || apn.bearer == radioTech) {
2279cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (DBG) log("buildWaitingApns: adding apn=" + apn.toString());
2280cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnList.add(apn);
2281c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else {
2282cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (DBG) {
2283cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            log("buildWaitingApns: bearer:" + apn.bearer + " != "
2284cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                    + "radioTech:" + radioTech);
2285cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
2286c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
2287cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2288cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
2289cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("buildWaitingApns: couldn't handle requesedApnType="
2290cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            + requestedApnType);
2291c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
2292c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2293c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2294cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2295ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            loge("mAllApnSettings is empty!");
2296c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2297cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("buildWaitingApns: X apnList=" + apnList);
2298cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return apnList;
2299c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2300c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2301cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private String apnListToString (ArrayList<ApnSetting> apns) {
2302cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        StringBuilder result = new StringBuilder();
2303cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (int i = 0, size = apns.size(); i < size; i++) {
2304cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result.append('[')
2305cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                  .append(apns.get(i).toString())
2306cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                  .append(']');
2307c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2308cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result.toString();
2309c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2310c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2311cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void setPreferredApn(int pos) {
231222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (!mCanSetPreferApn) {
2313cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("setPreferredApn: X !canSEtPreferApn");
2314cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
2315cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2316cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2317cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("setPreferredApn: delete");
2318cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ContentResolver resolver = mPhone.getContext().getContentResolver();
2319cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        resolver.delete(PREFERAPN_NO_UPDATE_URI, null, null);
2320cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2321cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (pos >= 0) {
2322cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("setPreferredApn: insert");
2323cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ContentValues values = new ContentValues();
2324cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            values.put(APN_ID, pos);
2325cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            resolver.insert(PREFERAPN_NO_UPDATE_URI, values);
2326cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2327cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2328cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2329cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ApnSetting getPreferredApn() {
2330ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings.isEmpty()) {
2331ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            log("getPreferredApn: X not found mAllApnSettings.isEmpty");
2332cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return null;
2333cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2334cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2335cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Cursor cursor = mPhone.getContext().getContentResolver().query(
2336cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                PREFERAPN_NO_UPDATE_URI, new String[] { "_id", "name", "apn" },
2337cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
2338cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2339cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor != null) {
234022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCanSetPreferApn = true;
2341cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
234222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCanSetPreferApn = false;
2343cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2344cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("getPreferredApn: mRequestedApnType=" + mRequestedApnType + " cursor=" + cursor
2345cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                + " cursor.count=" + ((cursor != null) ? cursor.getCount() : 0));
2346cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
234722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mCanSetPreferApn && cursor.getCount() > 0) {
2348cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            int pos;
2349cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cursor.moveToFirst();
2350cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            pos = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID));
2351ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for(ApnSetting p : mAllApnSettings) {
2352cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("getPreferredApn: apnSetting=" + p);
2353cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (p.id == pos && p.canHandleType(mRequestedApnType)) {
2354cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("getPreferredApn: X found apnSetting" + p);
2355cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    cursor.close();
2356cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return p;
2357cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2358cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
2359cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2360cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2361cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor != null) {
2362cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cursor.close();
2363cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2364cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2365cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("getPreferredApn: X not found");
2366cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
2367cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
2368cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2369cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2370cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void handleMessage (Message msg) {
2371cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("handleMessage msg=" + msg);
2372cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2373cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (!mPhone.mIsTheCurrentActivePhone || mIsDisposed) {
2374cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("handleMessage: Ignore GSM msgs since GSM phone is inactive");
2375cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
2376cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2377cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2378a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (!isActiveDataSubscription()) {
2379a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            loge("Ignore msgs since phone is not the current DDS");
2380a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return;
2381a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2382a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2383cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        switch (msg.what) {
2384cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_RECORDS_LOADED:
2385cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onRecordsLoaded();
2386cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2387cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2388cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_CONNECTION_DETACHED:
2389cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onDataConnectionDetached();
2390cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2391cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2392cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_CONNECTION_ATTACHED:
2393cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onDataConnectionAttached();
2394cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2395cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2396cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DO_RECOVERY:
2397cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                doRecovery();
2398cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2399cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2400cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_APN_CHANGED:
2401cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onApnChanged();
2402cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2403cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2404cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_PS_RESTRICT_ENABLED:
2405cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                /**
2406cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * We don't need to explicitly to tear down the PDP context
2407cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * when PS restricted is enabled. The base band will deactive
2408cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * PDP context and notify us with PDP_CONTEXT_CHANGED.
2409cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * But we should stop the network polling and prevent reset PDP.
2410cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 */
2411cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
2412cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                stopNetStatPoll();
2413cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                stopDataStallAlarm();
2414cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsPsRestricted = true;
2415cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
2416cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2417cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_PS_RESTRICT_DISABLED:
2418cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                /**
2419cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * When PS restrict is removed, we need setup PDP connection if
2420cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * PDP connection is down.
2421cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 */
2422cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_PS_RESTRICT_DISABLED " + mIsPsRestricted);
2423cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsPsRestricted  = false;
2424cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (isConnected()) {
2425cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    startNetStatPoll();
2426cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
2427cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2428cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // TODO: Should all PDN states be checked to fail?
2429ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    if (mState == DctConstants.State.FAILED) {
2430cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        cleanUpAllConnections(false, Phone.REASON_PS_RESTRICT_ENABLED);
2431cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mReregisterOnReconnectFailure = false;
2432cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
24333fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    ApnContext apnContext = mApnContexts.get(PhoneConstants.APN_TYPE_DEFAULT);
24343fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (apnContext != null) {
24353fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        apnContext.setReason(Phone.REASON_PS_RESTRICT_ENABLED);
24363fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        trySetupData(apnContext);
24373fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    } else {
24383fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        loge("**** Default ApnContext not found ****");
24393fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        if (Build.IS_DEBUGGABLE) {
24403fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                            throw new RuntimeException("Default ApnContext not found");
24413fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        }
24423fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    }
2443cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2444cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
2445ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
2446cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_TRY_SETUP_DATA:
2447cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (msg.obj instanceof ApnContext) {
2448cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    onTrySetupData((ApnContext)msg.obj);
2449cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else if (msg.obj instanceof String) {
2450cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    onTrySetupData((String)msg.obj);
2451cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2452cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    loge("EVENT_TRY_SETUP request w/o apnContext or String");
2453cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2454cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
2455cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2456cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_CLEAN_UP_CONNECTION:
2457cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                boolean tearDown = (msg.arg1 == 0) ? false : true;
2458cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_CLEAN_UP_CONNECTION tearDown=" + tearDown);
2459cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (msg.obj instanceof ApnContext) {
2460cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    cleanUpConnection(tearDown, (ApnContext)msg.obj);
2461cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2462ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    loge("EVENT_CLEAN_UP_CONNECTION request w/o apn context, call super");
2463ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    super.handleMessage(msg);
2464cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2465cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
2466a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE:
2467a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
2468a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                onSetInternalDataEnabled(enabled, (Message) msg.obj);
2469a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
2470a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2471a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS:
2472a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                Message mCause = obtainMessage(DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS, null);
2473a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if ((msg.obj != null) && (msg.obj instanceof String)) {
2474a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mCause.obj = msg.obj;
2475a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
2476a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                super.handleMessage(mCause);
2477a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
2478ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
2479220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville            case DctConstants.EVENT_DATA_RAT_CHANGED:
2480220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville                //May new Network allow setupData, so try it here
2481220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville                setupDataOnConnectableApns(Phone.REASON_NW_TYPE_CHANGED);
2482220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville                break;
2483220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville
2484cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            default:
2485cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // handle the message in the super class DataConnectionTracker
2486cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                super.handleMessage(msg);
2487cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2488cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2489cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
2490cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2491cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected int getApnProfileID(String apnType) {
2492cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IMS)) {
2493cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_IMS;
2494cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_FOTA)) {
2495cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_FOTA;
2496cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_CBS)) {
2497cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_CBS;
24981b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IA)) {
24991b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            return RILConstants.DATA_PROFILE_DEFAULT; // DEFAULT for now
250045df26444864daad60afdd4d121ab4043da3834bSungmin Choi        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_DUN)) {
250145df26444864daad60afdd4d121ab4043da3834bSungmin Choi            return RILConstants.DATA_PROFILE_TETHERED;
2502cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2503cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_DEFAULT;
2504cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2505cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2506cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2507cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private int getCellLocationId() {
2508cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int cid = -1;
2509cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        CellLocation loc = mPhone.getCellLocation();
2510cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2511cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (loc != null) {
2512cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (loc instanceof GsmCellLocation) {
2513cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cid = ((GsmCellLocation)loc).getCid();
2514cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else if (loc instanceof CdmaCellLocation) {
2515cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cid = ((CdmaCellLocation)loc).getBaseStationId();
2516cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
2517cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2518cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return cid;
2519cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
2520cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2521a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private IccRecords getUiccRecords(int appFamily) {
2522a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return mUiccController.getIccRecords(mPhone.getPhoneId(), appFamily);
2523a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2524a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2525a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2526cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2527cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onUpdateIcc() {
2528cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mUiccController == null ) {
2529cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            return;
2530cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2531cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2532a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        IccRecords newIccRecords = getUiccRecords(UiccController.APP_FAM_3GPP);
2533cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2534cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
2535cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (r != newIccRecords) {
2536cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (r != null) {
2537cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("Removing stale icc objects.");
2538cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                r.unregisterForRecordsLoaded(this);
2539cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIccRecords.set(null);
25409aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan            }
2541cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (newIccRecords != null) {
2542cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("New records found");
2543cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIccRecords.set(newIccRecords);
2544cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                newIccRecords.registerForRecordsLoaded(
2545cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        this, DctConstants.EVENT_RECORDS_LOADED, null);
25469aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan            }
25479aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan        }
2548cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
2549cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2550a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    // setAsCurrentDataConnectionTracker
2551a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void update() {
2552a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("update sub = " + mPhone.getSubId());
2553a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (isActiveDataSubscription()) {
2554a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("update(): Active DDS, register for all events now!");
2555a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            registerForAllEvents();
2556a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            onUpdateIcc();
2557a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2558a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mUserDataEnabled = Settings.Global.getInt(mPhone.getContext().getContentResolver(),
2559a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    Settings.Global.MOBILE_DATA, 1) == 1;
2560a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2561a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (mPhone instanceof CDMALTEPhone) {
2562a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ((CDMALTEPhone)mPhone).updateCurrentCarrierInProvider();
2563a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                supplyMessenger();
2564a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else if (mPhone instanceof GSMPhone) {
2565a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ((GSMPhone)mPhone).updateCurrentCarrierInProvider();
2566a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                supplyMessenger();
2567a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
2568a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("Phone object is not MultiSim. This should not hit!!!!");
2569a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
2570a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2571a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else {
2572a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            unregisterForAllEvents();
2573a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("update(): NOT the active DDS, unregister for all events!");
2574a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2575a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2576a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2577a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
2578a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void cleanUpAllConnections(String cause) {
2579a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cleanUpAllConnections(cause, null);
2580a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2581a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2582a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void updateRecords() {
2583a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (isActiveDataSubscription()) {
2584a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            onUpdateIcc();
2585a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2586a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2587a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2588a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void cleanUpAllConnections(String cause, Message disconnectAllCompleteMsg) {
2589a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("cleanUpAllConnections");
2590a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (disconnectAllCompleteMsg != null) {
2591a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mDisconnectAllCompleteMsgList.add(disconnectAllCompleteMsg);
2592a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2593a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2594a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Message msg = obtainMessage(DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS);
2595a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        msg.obj = cause;
2596a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sendMessage(msg);
2597a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2598a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2599a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void notifyDataDisconnectComplete() {
2600a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("notifyDataDisconnectComplete");
2601a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        for (Message m: mDisconnectAllCompleteMsgList) {
2602a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            m.sendToTarget();
2603a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2604a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mDisconnectAllCompleteMsgList.clear();
2605a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2606a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2607a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2608a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void notifyAllDataDisconnected() {
2609a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sEnableFailFastRefCounter = 0;
2610a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mFailFast = false;
2611a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.notifyRegistrants();
2612a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2613a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2614a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void registerForAllDataDisconnected(Handler h, int what, Object obj) {
2615a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.addUnique(h, what, obj);
2616a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2617a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (isDisconnected()) {
2618a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("notify All Data Disconnected");
2619a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
2620a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2621a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2622a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2623a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void unregisterForAllDataDisconnected(Handler h) {
2624a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.remove(h);
2625a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2626a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2627a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2628a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
2629a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void onSetInternalDataEnabled(boolean enable) {
2630a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        onSetInternalDataEnabled(enable, null);
2631a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2632a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2633a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void onSetInternalDataEnabled(boolean enabled, Message onCompleteMsg) {
2634a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean sendOnComplete = true;
2635a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2636a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        synchronized (mDataEnabledLock) {
2637a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mInternalDataEnabled = enabled;
2638a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (enabled) {
2639a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("onSetInternalDataEnabled: changed to enabled, try to setup data call");
2640a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                onTrySetupData(Phone.REASON_DATA_ENABLED);
2641a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
2642a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                sendOnComplete = false;
2643a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("onSetInternalDataEnabled: changed to disabled, cleanUpAllConnections");
2644a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                cleanUpAllConnections(null, onCompleteMsg);
2645a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
2646a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2647a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2648a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (sendOnComplete) {
2649a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (onCompleteMsg != null) {
2650a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                onCompleteMsg.sendToTarget();
2651a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
2652a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2653a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2654a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2655a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean setInternalDataEnabledFlag(boolean enable) {
2656a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG)
2657a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("setInternalDataEnabledFlag(" + enable + ")");
2658a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2659a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mInternalDataEnabled != enable) {
2660a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mInternalDataEnabled = enable;
2661a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2662a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return true;
2663a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2664a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2665a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
2666a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean setInternalDataEnabled(boolean enable) {
2667a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return setInternalDataEnabled(enable, null);
2668a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2669a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2670a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean setInternalDataEnabled(boolean enable, Message onCompleteMsg) {
2671a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG)
2672a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("setInternalDataEnabled(" + enable + ")");
2673a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2674a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Message msg = obtainMessage(DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE, onCompleteMsg);
2675a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        msg.arg1 = (enable ? DctConstants.ENABLED : DctConstants.DISABLED);
2676a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sendMessage(msg);
2677a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return true;
2678a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2679a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2680a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /** Returns true if this is current DDS. */
2681a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected boolean isActiveDataSubscription() {
2682a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // FIXME This should have code like
2683a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // return (mPhone.getSubId() == SubscriptionManager.getDefaultDataSubId());
2684a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return true;
2685a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2686a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2687a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void setDataAllowed(boolean enable, Message response) {
2688a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         mIsCleanupRequired = !enable;
2689a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         mPhone.mCi.setDataAllowed(enable, response);
2690a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         mInternalDataEnabled = enable;
2691a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2692a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2693cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2694cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void log(String s) {
2695a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Rlog.d(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s);
2696cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
2697cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2698cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2699cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void loge(String s) {
2700a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Rlog.e(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s);
2701cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
2702cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2703cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2704c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2705cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println("DataConnectionTracker extends:");
2706cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        super.dump(fd, pw, args);
2707cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mReregisterOnReconnectFailure=" + mReregisterOnReconnectFailure);
270822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" canSetPreferApn=" + mCanSetPreferApn);
2709cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mApnObserver=" + mApnObserver);
2710cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" getOverallState=" + getOverallState());
2711ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        pw.println(" mDataConnectionAsyncChannels=%s\n" + mDataConnectionAcHashMap);
2712187a39f896f88eb6c5e4306d9595546654825976Wink Saville        pw.println(" mAttached=" + mAttached.get());
2713c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2714a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2715a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
2716bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram    public String[] getPcscfAddress(String apnType) {
2717a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("getPcscfAddress()");
2718bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        ApnContext apnContext = null;
2719bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram
2720bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        if(apnType == null){
2721bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            log("apnType is null, return null");
2722bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            return null;
2723bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        }
2724a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2725bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_EMERGENCY)) {
2726bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            apnContext = mApnContexts.get(PhoneConstants.APN_TYPE_EMERGENCY);
2727bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IMS)) {
2728bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            apnContext = mApnContexts.get(PhoneConstants.APN_TYPE_IMS);
2729bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        } else {
2730bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            log("apnType is invalid, return null");
2731bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            return null;
2732bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        }
2733a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2734a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (apnContext == null) {
2735a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("apnContext is null, return null");
2736a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return null;
2737a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2738a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2739a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        DcAsyncChannel dcac = apnContext.getDcAc();
2740a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        String[] result = null;
2741a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2742a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (dcac != null) {
2743a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            result = dcac.getPcscfAddr();
2744a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2745a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            for (int i = 0; i < result.length; i++) {
2746a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("Pcscf[" + i + "]: " + result[i]);
2747a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
2748a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return result;
2749a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2750a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return null;
2751a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2752a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2753a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
2754a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void setImsRegistrationState(boolean registered) {
2755a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("setImsRegistrationState - mImsRegistrationState(before): "+ mImsRegistrationState
2756a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                + ", registered(current) : " + registered);
2757a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2758a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mPhone == null) return;
2759a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2760a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ServiceStateTracker sst = mPhone.getServiceStateTracker();
2761a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (sst == null) return;
2762a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2763a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sst.setImsRegistrationState(registered);
2764a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
276576f43316a5a6082d601bffd4b6898d0bd81e11fcram
276676f43316a5a6082d601bffd4b6898d0bd81e11fcram    /**
276776f43316a5a6082d601bffd4b6898d0bd81e11fcram     * Read APN configuration from Telephony.db for Emergency APN
276876f43316a5a6082d601bffd4b6898d0bd81e11fcram     * All opertors recognize the connection request for EPDN based on APN type
276976f43316a5a6082d601bffd4b6898d0bd81e11fcram     * PLMN name,APN name are not mandatory parameters
277076f43316a5a6082d601bffd4b6898d0bd81e11fcram     */
277176f43316a5a6082d601bffd4b6898d0bd81e11fcram    private void initEmergencyApnSetting() {
277276f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Operator Numeric is not available when sim records are not loaded.
277376f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Query Telephony.db with APN type as EPDN request does not
277476f43316a5a6082d601bffd4b6898d0bd81e11fcram        // require APN name, plmn and all operators support same APN config.
277576f43316a5a6082d601bffd4b6898d0bd81e11fcram        // DB will contain only one entry for Emergency APN
277676f43316a5a6082d601bffd4b6898d0bd81e11fcram        String selection = "type=\"emergency\"";
277776f43316a5a6082d601bffd4b6898d0bd81e11fcram        Cursor cursor = mPhone.getContext().getContentResolver().query(
277876f43316a5a6082d601bffd4b6898d0bd81e11fcram                Telephony.Carriers.CONTENT_URI, null, selection, null, null);
277976f43316a5a6082d601bffd4b6898d0bd81e11fcram
278076f43316a5a6082d601bffd4b6898d0bd81e11fcram        if (cursor != null) {
278176f43316a5a6082d601bffd4b6898d0bd81e11fcram            if (cursor.getCount() > 0) {
278276f43316a5a6082d601bffd4b6898d0bd81e11fcram                if (cursor.moveToFirst()) {
278376f43316a5a6082d601bffd4b6898d0bd81e11fcram                    mEmergencyApn = makeApnSetting(cursor);
278476f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
278576f43316a5a6082d601bffd4b6898d0bd81e11fcram            }
278676f43316a5a6082d601bffd4b6898d0bd81e11fcram            cursor.close();
278776f43316a5a6082d601bffd4b6898d0bd81e11fcram        }
278876f43316a5a6082d601bffd4b6898d0bd81e11fcram    }
278976f43316a5a6082d601bffd4b6898d0bd81e11fcram
279076f43316a5a6082d601bffd4b6898d0bd81e11fcram    /**
279176f43316a5a6082d601bffd4b6898d0bd81e11fcram     * Add the Emergency APN settings to APN settings list
279276f43316a5a6082d601bffd4b6898d0bd81e11fcram     */
279376f43316a5a6082d601bffd4b6898d0bd81e11fcram    private void addEmergencyApnSetting() {
279476f43316a5a6082d601bffd4b6898d0bd81e11fcram        if(mEmergencyApn != null) {
279576f43316a5a6082d601bffd4b6898d0bd81e11fcram            if(mAllApnSettings == null) {
279676f43316a5a6082d601bffd4b6898d0bd81e11fcram                mAllApnSettings = new ArrayList<ApnSetting>();
279776f43316a5a6082d601bffd4b6898d0bd81e11fcram            } else {
279876f43316a5a6082d601bffd4b6898d0bd81e11fcram                boolean hasEmergencyApn = false;
279976f43316a5a6082d601bffd4b6898d0bd81e11fcram                for (ApnSetting apn : mAllApnSettings) {
280076f43316a5a6082d601bffd4b6898d0bd81e11fcram                    if (ArrayUtils.contains(apn.types, PhoneConstants.APN_TYPE_EMERGENCY)) {
280176f43316a5a6082d601bffd4b6898d0bd81e11fcram                        hasEmergencyApn = true;
280276f43316a5a6082d601bffd4b6898d0bd81e11fcram                        break;
280376f43316a5a6082d601bffd4b6898d0bd81e11fcram                    }
280476f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
280576f43316a5a6082d601bffd4b6898d0bd81e11fcram
280676f43316a5a6082d601bffd4b6898d0bd81e11fcram                if(hasEmergencyApn == false) {
280776f43316a5a6082d601bffd4b6898d0bd81e11fcram                    mAllApnSettings.add(mEmergencyApn);
280876f43316a5a6082d601bffd4b6898d0bd81e11fcram                } else {
280976f43316a5a6082d601bffd4b6898d0bd81e11fcram                    log("addEmergencyApnSetting - E-APN setting is already present");
281076f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
281176f43316a5a6082d601bffd4b6898d0bd81e11fcram            }
281276f43316a5a6082d601bffd4b6898d0bd81e11fcram        }
281376f43316a5a6082d601bffd4b6898d0bd81e11fcram    }
2814c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville}
2815