DcTracker.java revision 796d3c22f21041116110735c92d7e2c3a7c8f60d
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;
212b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensenimport android.app.ProgressDialog;
22c9b81a0c05128694c617fcdd67e73821895822feWink Savilleimport android.content.ActivityNotFoundException;
23b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensenimport android.content.BroadcastReceiver;
24c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.ContentResolver;
25cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.content.ContentValues;
26c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Context;
27c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Intent;
28c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.IntentFilter;
29cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.content.res.Resources;
30c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.database.ContentObserver;
31cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.database.Cursor;
32cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.ConnectivityManager;
33c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.net.LinkProperties;
3496cce86cf08e37e0f09ed5057b1196e26b302743Robert Greenwaltimport android.net.NetworkCapabilities;
35cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.NetworkConfig;
36071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwaltimport android.net.NetworkFactory;
37071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwaltimport android.net.NetworkRequest;
38cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.NetworkUtils;
399c180aedfc9f0d20525c0128487d3500e6c0a715Jason Monkimport android.net.ProxyInfo;
40cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.Uri;
41c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.AsyncResult;
423fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwaltimport android.os.Build;
43b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensenimport android.os.Bundle;
44a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.Handler;
45071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwaltimport android.os.Looper;
46c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Message;
471f2a2323572b2f3ab18234726cc1b048c670fbabRobert Greenwaltimport android.os.Messenger;
48a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.RegistrantList;
49b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensenimport android.os.ServiceManager;
50c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemClock;
51c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemProperties;
52c9b81a0c05128694c617fcdd67e73821895822feWink Savilleimport android.os.UserHandle;
53c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.provider.Settings;
54cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.provider.Telephony;
55cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.CellLocation;
56c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.telephony.ServiceState;
57c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.telephony.TelephonyManager;
58a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.SubscriptionManager;
59cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.cdma.CdmaCellLocation;
60cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.gsm.GsmCellLocation;
61c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.text.TextUtils;
62cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kallaimport android.util.EventLog;
632b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensenimport android.view.WindowManager;
6499c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Savilleimport android.telephony.Rlog;
65c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
66a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.cdma.CDMALTEPhone;
674918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savilleimport com.android.internal.telephony.Phone;
684918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savilleimport com.android.internal.telephony.PhoneBase;
69cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.DctConstants;
70cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.EventLogTags;
71b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensenimport com.android.internal.telephony.ITelephony;
72c9b81a0c05128694c617fcdd67e73821895822feWink Savilleimport com.android.internal.telephony.TelephonyIntents;
73cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.gsm.GSMPhone;
744918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savilleimport com.android.internal.telephony.PhoneConstants;
75cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.RILConstants;
76d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccRecords;
77bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenkaimport com.android.internal.telephony.uicc.UiccController;
78c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.util.AsyncChannel;
7976f43316a5a6082d601bffd4b6898d0bd81e11fcramimport com.android.internal.util.ArrayUtils;
80c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
81c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.io.FileDescriptor;
82c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.io.PrintWriter;
83c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.ArrayList;
8429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwaltimport java.util.Arrays;
85187a39f896f88eb6c5e4306d9595546654825976Wink Savilleimport java.util.concurrent.atomic.AtomicBoolean;
86c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.HashMap;
8729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwaltimport java.util.Objects;
88d86df358b8fe07160caa12147b6e4ad34d378ce6xinheimport java.lang.StringBuilder;
89c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
90a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.provider.Settings;
91a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
92a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.ServiceStateTracker;
93c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/**
94c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * {@hide}
95c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
96454b1dfd508844b42eb775e4ab2359be74d3672bWink Savillepublic final class DcTracker extends DcTrackerBase {
97cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected final String LOG_TAG = "DCT";
98c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
99b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla    /**
100a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * List of messages that are waiting to be posted, when data call disconnect
101a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * is complete
102a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
103a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ArrayList<Message> mDisconnectAllCompleteMsgList = new ArrayList<Message>();
104a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
105a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private RegistrantList mAllDataDisconnectedRegistrants = new RegistrantList();
106a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
107a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected int mDisconnectPendingCount = 0;
108a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
109a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
110cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Handles changes to the APN db.
111b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla     */
112cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private class ApnChangeObserver extends ContentObserver {
113cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public ApnChangeObserver () {
114cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            super(mDataConnectionTracker);
115cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
116c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
117cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
118cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public void onChange(boolean selfChange) {
119cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            sendMessage(obtainMessage(DctConstants.EVENT_APN_CHANGED));
120cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
121cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
122c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
123cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Instance Variables
124c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
125cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean mReregisterOnReconnectFailure = false;
126c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
127c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
128cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Constants
129c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
130ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    // Used by puppetmaster/*/radio_stress.py
131ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private static final String PUPPET_MASTER_RADIO_STRESS_TEST = "gsm.defaultpdpcontext.active";
132c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
133ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private static final int POLL_PDP_MILLIS = 5 * 1000;
134c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1352b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen    private static final int PROVISIONING_SPINNER_TIMEOUT_MILLIS = 120 * 1000;
1362b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen
137cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final Uri PREFERAPN_NO_UPDATE_URI =
138cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        Uri.parse("content://telephony/carriers/preferapn_no_update");
139cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final String APN_ID = "apn_id";
140cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
141ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private boolean mCanSetPreferApn = false;
142c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
143187a39f896f88eb6c5e4306d9595546654825976Wink Saville    private AtomicBoolean mAttached = new AtomicBoolean(false);
144187a39f896f88eb6c5e4306d9595546654825976Wink Saville
145cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** Watches for changes to the APN db. */
146cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ApnChangeObserver mApnObserver;
147cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
148b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private final String mProvisionActionName;
149b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private BroadcastReceiver mProvisionBroadcastReceiver;
1502b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen    private ProgressDialog mProvisioningSpinner;
151b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
1524dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt    /** Used to send us NetworkRequests from ConnectivityService.  Remeber it so we can
1534dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt     * unregister on dispose. */
1544dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt    private Messenger mNetworkFactoryMessenger;
155071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt    private NetworkFactory mNetworkFactory;
156071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt    private NetworkCapabilities mNetworkFilter;
1574dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt
158a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean mImsRegistrationState = false;
159a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ApnContext mWaitCleanUpApnContext = null;
160a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private boolean mDeregistrationAlarmState = false;
161a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private PendingIntent mImsDeregistrationDelayIntent = null;
162a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
163cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Constructor
164454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    public DcTracker(PhoneBase p) {
165cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        super(p);
166cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("GsmDCT.constructor");
167cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
168cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mDataConnectionTracker = this;
169a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        update();
170cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mApnObserver = new ApnChangeObserver();
171cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        p.getContext().getContentResolver().registerContentObserver(
172cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                Telephony.Carriers.CONTENT_URI, true, mApnObserver);
173cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
174d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        initApnContexts();
175d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
176d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        for (ApnContext apnContext : mApnContexts.values()) {
177d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            // Register the reconnect and restart actions.
178d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            IntentFilter filter = new IntentFilter();
179d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            filter.addAction(INTENT_RECONNECT_ALARM + '.' + apnContext.getApnType());
180d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            filter.addAction(INTENT_RESTART_TRYSETUP_ALARM + '.' + apnContext.getApnType());
181d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
182d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        }
183d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
1841f2a2323572b2f3ab18234726cc1b048c670fbabRobert Greenwalt        ConnectivityManager cm = (ConnectivityManager)p.getContext().getSystemService(
1851f2a2323572b2f3ab18234726cc1b048c670fbabRobert Greenwalt                Context.CONNECTIVITY_SERVICE);
186071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
187071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        mNetworkFilter = new NetworkCapabilities();
188071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        mNetworkFilter.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
189fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
190fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL);
191fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
192fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_FOTA);
193fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
194fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_CBS);
195fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_IA);
196fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_RCS);
197fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_XCAP);
198fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS);
199fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
200fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
201071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
202071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        mNetworkFactory = new TelephonyNetworkFactory(this.getLooper(), p.getContext(),
203071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt                "TelephonyNetworkFactory", mNetworkFilter);
204071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        mNetworkFactory.setScoreFilter(50);
205071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        mNetworkFactoryMessenger = new Messenger(mNetworkFactory);
206071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        cm.registerNetworkFactory(mNetworkFactoryMessenger, "Telephony");
20776f43316a5a6082d601bffd4b6898d0bd81e11fcram
20876f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Add Emergency APN to APN setting list by default to support EPDN in sim absent cases
20976f43316a5a6082d601bffd4b6898d0bd81e11fcram        initEmergencyApnSetting();
21076f43316a5a6082d601bffd4b6898d0bd81e11fcram        addEmergencyApnSetting();
211b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
212b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        mProvisionActionName = "com.android.internal.telephony.PROVISION" + p.getPhoneId();
213cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
214c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
215a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void registerForAllEvents() {
216a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.mCi.registerForAvailable(this, DctConstants.EVENT_RADIO_AVAILABLE, null);
217a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.mCi.registerForOffOrNotAvailable(this,
218a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville               DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
219a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.mCi.registerForDataNetworkStateChanged(this,
220a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville               DctConstants.EVENT_DATA_STATE_CHANGED, null);
221a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getCallTracker().registerForVoiceCallEnded (this,
222a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville               DctConstants.EVENT_VOICE_CALL_ENDED, null);
223a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getCallTracker().registerForVoiceCallStarted (this,
224a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville               DctConstants.EVENT_VOICE_CALL_STARTED, null);
225a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getServiceStateTracker().registerForDataConnectionAttached(this,
226a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville               DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null);
227a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getServiceStateTracker().registerForDataConnectionDetached(this,
228a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville               DctConstants.EVENT_DATA_CONNECTION_DETACHED, null);
229a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getServiceStateTracker().registerForRoamingOn(this,
230a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville               DctConstants.EVENT_ROAMING_ON, null);
231a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getServiceStateTracker().registerForRoamingOff(this,
232a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville               DctConstants.EVENT_ROAMING_OFF, null);
233a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getServiceStateTracker().registerForPsRestrictedEnabled(this,
234a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                DctConstants.EVENT_PS_RESTRICT_ENABLED, null);
235a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getServiceStateTracker().registerForPsRestrictedDisabled(this,
236a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                DctConstants.EVENT_PS_RESTRICT_DISABLED, null);
237a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     //   SubscriptionManager.registerForDdsSwitch(this,
238a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     //          DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS, null);
239a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(this,
240a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                DctConstants.EVENT_DATA_RAT_CHANGED, null);
241a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
242cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
243cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void dispose() {
244cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("GsmDCT.dispose");
2454dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt
246b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        if (mProvisionBroadcastReceiver != null) {
247b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            mPhone.getContext().unregisterReceiver(mProvisionBroadcastReceiver);
248b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            mProvisionBroadcastReceiver = null;
249b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
2502b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        if (mProvisioningSpinner != null) {
2512b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.dismiss();
2522b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner = null;
2532b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        }
254b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
2554dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt        ConnectivityManager cm = (ConnectivityManager)mPhone.getContext().getSystemService(
2564dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt                Context.CONNECTIVITY_SERVICE);
2574dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt        cm.unregisterNetworkFactory(mNetworkFactoryMessenger);
2584dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt        mNetworkFactoryMessenger = null;
2594dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt
260cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, null);
261cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
262cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        super.dispose();
263cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
264a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getContext().getContentResolver().unregisterContentObserver(mApnObserver);
265a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mApnContexts.clear();
266a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPrioritySortedApnContexts.clear();
267a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
268a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        destroyDataConnections();
269a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
270a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void unregisterForAllEvents() {
271a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         //Unregister for all events
27222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.unregisterForAvailable(this);
27322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.unregisterForOffOrNotAvailable(this);
274cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
275a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (r != null) {
276a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            r.unregisterForRecordsLoaded(this);
277a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mIccRecords.set(null);
278a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
27922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.unregisterForDataNetworkStateChanged(this);
280cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getCallTracker().unregisterForVoiceCallEnded(this);
281cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getCallTracker().unregisterForVoiceCallStarted(this);
282cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().unregisterForDataConnectionAttached(this);
283cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().unregisterForDataConnectionDetached(this);
284cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().unregisterForRoamingOn(this);
285cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().unregisterForRoamingOff(this);
286cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().unregisterForPsRestrictedEnabled(this);
287cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().unregisterForPsRestrictedDisabled(this);
288a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        //SubscriptionManager.unregisterForDdsSwitch(this);
289cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
290cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
291071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt    private class TelephonyNetworkFactory extends NetworkFactory {
292071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        public TelephonyNetworkFactory(Looper l, Context c, String TAG, NetworkCapabilities nc) {
293071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            super(l, c, TAG, nc);
294071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
295071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
296071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        @Override
297071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        protected void needNetworkFor(NetworkRequest networkRequest, int score) {
298071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            // figure out the apn type and enable it
299071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (DBG) log("Cellular needs Network for " + networkRequest);
300071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            ApnContext apnContext = apnContextForNetworkRequest(networkRequest);
301071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (apnContext != null) apnContext.incRefCount();
302071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
303071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
304071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        @Override
305071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        protected void releaseNetworkFor(NetworkRequest networkRequest) {
306071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (DBG) log("Cellular releasing Network for " + networkRequest);
307071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            ApnContext apnContext = apnContextForNetworkRequest(networkRequest);
308071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (apnContext != null) apnContext.decRefCount();
309071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
310071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt    }
311071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
312071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt    private ApnContext apnContextForNetworkRequest(NetworkRequest nr) {
313071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        NetworkCapabilities nc = nr.networkCapabilities;
314071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        // for now, ignore the bandwidth stuff
315fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        if (nc.getTransportTypes().length > 0 &&
316071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt                nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == false) {
317071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            return null;
318071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
319071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
320071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        // in the near term just do 1-1 matches.
321071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        // TODO - actually try to match the set of capabilities
322071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        int type = -1;
323071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        String name = null;
324071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
325071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        boolean error = false;
326071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
327071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (name != null) error = true;
328071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            name = PhoneConstants.APN_TYPE_DEFAULT;
329071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            type = ConnectivityManager.TYPE_MOBILE;
330071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
331071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
332071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (name != null) error = true;
333071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            name = PhoneConstants.APN_TYPE_MMS;
334071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            type = ConnectivityManager.TYPE_MOBILE_MMS;
335071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
336071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
337071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (name != null) error = true;
338071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            name = PhoneConstants.APN_TYPE_SUPL;
339071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            type = ConnectivityManager.TYPE_MOBILE_SUPL;
340071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
341071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
342071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (name != null) error = true;
343071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            name = PhoneConstants.APN_TYPE_DUN;
344071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            type = ConnectivityManager.TYPE_MOBILE_DUN;
345071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
346071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
347071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (name != null) error = true;
348071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            name = PhoneConstants.APN_TYPE_FOTA;
349071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            type = ConnectivityManager.TYPE_MOBILE_FOTA;
350071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
351071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
352071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (name != null) error = true;
353071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            name = PhoneConstants.APN_TYPE_IMS;
354071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            type = ConnectivityManager.TYPE_MOBILE_IMS;
355071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
356071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
357071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (name != null) error = true;
358071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            name = PhoneConstants.APN_TYPE_CBS;
359071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            type = ConnectivityManager.TYPE_MOBILE_CBS;
360071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
361071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IA)) {
362071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (name != null) error = true;
363071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            name = PhoneConstants.APN_TYPE_IA;
364071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            type = ConnectivityManager.TYPE_MOBILE_IA;
365071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
366071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_RCS)) {
367071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (name != null) error = true;
368071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            name = null;
369071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            loge("RCS APN type not yet supported");
370071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
371071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_XCAP)) {
372071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (name != null) error = true;
373071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            name = null;
374071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            loge("XCAP APN type not yet supported");
375071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
376071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)) {
377071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            if (name != null) error = true;
378071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            name = null;
379071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            loge("EIMS APN type not yet supported");
380071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
381071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (error) {
382071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            loge("Multiple apn types specified in request - result is unspecified!");
383071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
384071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (type == -1 || name == null) {
385071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            loge("Unsupported NetworkRequest in Telephony: " + nr);
386071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt            return null;
387071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
388071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        ApnContext apnContext = mApnContexts.get(name);
389071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (apnContext == null) {
390d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            loge("Request for unsupported mobile type: " + type);
391071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
392071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        return apnContext;
393071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt    }
394071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
395b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    // Turn telephony radio on or off.
396b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private void setRadio(boolean on) {
397b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        final ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
398b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        try {
399b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            phone.setRadio(on);
400b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        } catch (Exception e) {
401b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            // Ignore.
402b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
403b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    }
404b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
405b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    // Class to handle Intent dispatched with user selects the "Sign-in to network"
406b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    // notification.
407b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private class ProvisionNotificationBroadcastReceiver extends BroadcastReceiver {
4082b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        private final String mNetworkOperator;
409b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        // Mobile provisioning URL.  Valid while provisioning notification is up.
410b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        // Set prior to notification being posted as URL contains ICCID which
411b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        // disappears when radio is off (which is the case when notification is up).
412b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        private final String mProvisionUrl;
413b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
4142b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        public ProvisionNotificationBroadcastReceiver(String provisionUrl, String networkOperator) {
4152b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mNetworkOperator = networkOperator;
416b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            mProvisionUrl = provisionUrl;
417b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
418b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
419b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        private void setEnableFailFastMobileData(int enabled) {
4206395443719ec3ee0257085945e753d02f603886bRobert Greenwalt            sendMessage(obtainMessage(DctConstants.CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA, enabled, 0));
421b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
422b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
423b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        private void enableMobileProvisioning() {
424b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            final Message msg = obtainMessage(DctConstants.CMD_ENABLE_MOBILE_PROVISIONING);
425b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            msg.setData(Bundle.forPair(DctConstants.PROVISIONING_URL_KEY, mProvisionUrl));
426b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            sendMessage(msg);
427b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
428b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
429b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        @Override
430b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        public void onReceive(Context context, Intent intent) {
4312b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // Turning back on the radio can take time on the order of a minute, so show user a
4322b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // spinner so they know something is going on.
4332b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner = new ProgressDialog(context);
4342b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setTitle(mNetworkOperator);
4352b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setMessage(
4362b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    // TODO: Don't borrow "Connecting..." i18n string; give Telephony a version.
4372b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    context.getText(com.android.internal.R.string.media_route_status_connecting));
4382b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setIndeterminate(true);
4392b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setCancelable(true);
4402b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // Allow non-Activity Service Context to create a View.
4412b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.getWindow().setType(
4422b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
4432b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.show();
4442b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // After timeout, hide spinner so user can at least use their device.
4452b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // TODO: Indicate to user that it is taking an unusually long time to connect?
4462b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            sendMessageDelayed(obtainMessage(DctConstants.CMD_CLEAR_PROVISIONING_SPINNER,
4472b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner), PROVISIONING_SPINNER_TIMEOUT_MILLIS);
448b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            // This code is almost identical to the old
449b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            // ConnectivityService.handleMobileProvisioningAction code.
450b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            setRadio(true);
451b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            setEnableFailFastMobileData(DctConstants.ENABLED);
452b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            enableMobileProvisioning();
453b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
454b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    }
455b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
456cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
457cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isApnTypeActive(String type) {
458cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(type);
459cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) return false;
460cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
461ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        return (apnContext.getDcAc() != null);
462cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
463cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
464cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
465cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isDataPossible(String apnType) {
466cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
467cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
468cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
469cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
470cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean apnContextIsEnabled = apnContext.isEnabled();
471cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        DctConstants.State apnContextState = apnContext.getState();
472cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean apnTypePossible = !(apnContextIsEnabled &&
473cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                (apnContextState == DctConstants.State.FAILED));
474cf5205f70eb1eac497164124187a088ecb03fff5Ram        boolean isEmergencyApn = apnContext.getApnType().equals(PhoneConstants.APN_TYPE_EMERGENCY);
475cf5205f70eb1eac497164124187a088ecb03fff5Ram        // Set the emergency APN availability status as TRUE irrespective of conditions checked in
476cf5205f70eb1eac497164124187a088ecb03fff5Ram        // isDataAllowed() like IN_SERVICE, MOBILE DATA status etc.
477cf5205f70eb1eac497164124187a088ecb03fff5Ram        boolean dataAllowed = isEmergencyApn || isDataAllowed();
478cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean possible = dataAllowed && apnTypePossible;
479cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
480ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (VDBG) {
481cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log(String.format("isDataPossible(%s): possible=%b isDataAllowed=%b " +
482cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    "apnTypePossible=%b apnContextisEnabled=%b apnContextState()=%s",
483cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnType, possible, dataAllowed, apnTypePossible,
484cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContextIsEnabled, apnContextState));
485cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
486cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return possible;
487cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
488cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
489cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
490cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void finalize() {
491cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(DBG) log("finalize");
492cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
493cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
494a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void supplyMessenger() {
495a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville       // Supply the data connection tracker messenger only if
496a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville       // this is corresponding to the current DDS.
497a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville       if (!isActiveDataSubscription()) {
498a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville           return;
499a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville       }
500a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
501a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ConnectivityManager cm = (ConnectivityManager)mPhone.getContext().getSystemService(
502a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                Context.CONNECTIVITY_SERVICE);
503a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE, new Messenger(this));
504a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE_MMS, new Messenger(this));
505a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE_SUPL, new Messenger(this));
506a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE_DUN, new Messenger(this));
507a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE_HIPRI, new Messenger(this));
508a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE_FOTA, new Messenger(this));
509a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE_IMS, new Messenger(this));
510a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE_CBS, new Messenger(this));
511cf5205f70eb1eac497164124187a088ecb03fff5Ram        cm.supplyMessenger(ConnectivityManager.TYPE_MOBILE_EMERGENCY, new Messenger(this));
512a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
513a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
5144a9b3afeb2ec4d573eca335a3706392ecf9f281eWink Saville    private ApnContext addApnContext(String type, NetworkConfig networkConfig) {
515071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        ApnContext apnContext = new ApnContext(mPhone.getContext(), type, LOG_TAG, networkConfig,
516071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt                this);
517cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mApnContexts.put(type, apnContext);
5183fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        mPrioritySortedApnContexts.add(apnContext);
519bce3d2575122929bb27ec8a37d56e96da39a3ca2Robert Greenwalt        return apnContext;
520cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
521c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
522d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt    protected void initApnContexts() {
523d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        log("initApnContexts: E");
524d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        // Load device network attributes from resources
525d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        String[] networkConfigStrings = mPhone.getContext().getResources().getStringArray(
526d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                com.android.internal.R.array.networkAttributes);
527d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        for (String networkConfigString : networkConfigStrings) {
528d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            NetworkConfig networkConfig = new NetworkConfig(networkConfigString);
529d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            ApnContext apnContext = null;
530d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
531d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            switch (networkConfig.type) {
532d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE:
533d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_DEFAULT, networkConfig);
534d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
535d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_MMS:
536d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_MMS, networkConfig);
537d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
538d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_SUPL:
539d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_SUPL, networkConfig);
540d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
541d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_DUN:
542d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_DUN, networkConfig);
543d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
544d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_HIPRI:
545d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_HIPRI, networkConfig);
546d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
547d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_FOTA:
548d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_FOTA, networkConfig);
549d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
550d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_IMS:
551d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_IMS, networkConfig);
552d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
553d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_CBS:
554d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_CBS, networkConfig);
555d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
556d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_IA:
557d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_IA, networkConfig);
558d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
559cf5205f70eb1eac497164124187a088ecb03fff5Ram            case ConnectivityManager.TYPE_MOBILE_EMERGENCY:
560cf5205f70eb1eac497164124187a088ecb03fff5Ram                apnContext = addApnContext(PhoneConstants.APN_TYPE_EMERGENCY, networkConfig);
561cf5205f70eb1eac497164124187a088ecb03fff5Ram                break;
562d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            default:
563d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                log("initApnContexts: skipping unknown type=" + networkConfig.type);
564d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                continue;
565d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            }
566d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            log("initApnContexts: apnContext=" + apnContext);
567d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        }
568d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        log("initApnContexts: X mApnContexts=" + mApnContexts);
569d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt    }
570d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
571cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
572cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public LinkProperties getLinkProperties(String apnType) {
573cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
574cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
575454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = apnContext.getDcAc();
576cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac != null) {
577cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("return link properites for " + apnType);
578cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return dcac.getLinkPropertiesSync();
579cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
580cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
581cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("return new LinkProperties");
582cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return new LinkProperties();
583cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
584cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
585608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt    @Override
586608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt    public NetworkCapabilities getNetworkCapabilities(String apnType) {
587608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        ApnContext apnContext = mApnContexts.get(apnType);
588608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        if (apnContext!=null) {
589608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            DcAsyncChannel dataConnectionAc = apnContext.getDcAc();
590608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            if (dataConnectionAc != null) {
591608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                if (DBG) {
592608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                    log("get active pdp is not null, return NetworkCapabilities for " + apnType);
593608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                }
594608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                return dataConnectionAc.getNetworkCapabilitiesSync();
595608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            }
596608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        }
597608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        if (DBG) log("return new NetworkCapabilities");
598608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        return new NetworkCapabilities();
599608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt    }
600cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
601cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
602cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return all active apn types
603cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public String[] getActiveApnTypes() {
604cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("get all active apn types");
605cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ArrayList<String> result = new ArrayList<String>();
606cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
607cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
608187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (mAttached.get() && apnContext.isReady()) {
609cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                result.add(apnContext.getApnType());
610cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
611cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
612c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
613cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result.toArray(new String[0]);
614cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
615cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
616cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
617cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return active apn of specific apn type
618cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public String getActiveApnString(String apnType) {
619ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (VDBG) log( "get active apn string for type:" + apnType);
620cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
621cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
622cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ApnSetting apnSetting = apnContext.getApnSetting();
623cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnSetting != null) {
624cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return apnSetting.apn;
625cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
626cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
627cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
628cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
629cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
630cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
631cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isApnTypeEnabled(String apnType) {
632cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
633cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
634cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
635cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
636cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return apnContext.isEnabled();
637cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
638cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
639cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
640cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void setState(DctConstants.State s) {
641cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setState should not be used in GSM" + s);
642cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
643cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
644cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return state of specific apn type
645cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
646cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public DctConstants.State getState(String apnType) {
647cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
648cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
649cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return apnContext.getState();
650c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
651cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return DctConstants.State.FAILED;
652cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
653c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
654c9b81a0c05128694c617fcdd67e73821895822feWink Saville    // Return if apn type is a provisioning apn.
655c9b81a0c05128694c617fcdd67e73821895822feWink Saville    @Override
656c9b81a0c05128694c617fcdd67e73821895822feWink Saville    protected boolean isProvisioningApn(String apnType) {
657c9b81a0c05128694c617fcdd67e73821895822feWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
658c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (apnContext != null) {
659c9b81a0c05128694c617fcdd67e73821895822feWink Saville            return apnContext.isProvisioningApn();
660c9b81a0c05128694c617fcdd67e73821895822feWink Saville        }
661c9b81a0c05128694c617fcdd67e73821895822feWink Saville        return false;
662c9b81a0c05128694c617fcdd67e73821895822feWink Saville    }
663c9b81a0c05128694c617fcdd67e73821895822feWink Saville
664cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return state of overall
665cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
666cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public DctConstants.State getOverallState() {
667cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isConnecting = false;
668cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isFailed = true; // All enabled Apns should be FAILED.
669cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isAnyEnabled = false;
670cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
671cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
672cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.isEnabled()) {
673cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                isAnyEnabled = true;
674cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                switch (apnContext.getState()) {
675cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case CONNECTED:
676cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case DISCONNECTING:
677cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("overall state is CONNECTED");
678cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return DctConstants.State.CONNECTED;
679ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                case RETRYING:
680cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case CONNECTING:
681cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isConnecting = true;
682cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isFailed = false;
683cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
684cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case IDLE:
685cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case SCANNING:
686cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isFailed = false;
687cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
688cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                default:
689cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isAnyEnabled = true;
690cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
691cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
692cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
693c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
694c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
695cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (!isAnyEnabled) { // Nothing enabled. return IDLE.
696cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log( "overall state is IDLE");
697cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.IDLE;
698c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
699c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
700cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnecting) {
701cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log( "overall state is CONNECTING");
702cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.CONNECTING;
703cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (!isFailed) {
704cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log( "overall state is IDLE");
705cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.IDLE;
706cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
707cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log( "overall state is FAILED");
708cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.FAILED;
709c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
710c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
711c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
712cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
713cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean isApnTypeAvailable(String type) {
714cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (type.equals(PhoneConstants.APN_TYPE_DUN) && fetchDunApn() != null) {
715cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return true;
716c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
717c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
718ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings != null) {
719ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for (ApnSetting apn : mAllApnSettings) {
720cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn.canHandleType(type)) {
721cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return true;
722cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
723cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
724c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
725cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return false;
726c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
727c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
728cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
729cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Report on whether data connectivity is enabled for any APN.
730cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return {@code false} if data connectivity has been explicitly disabled,
731cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * {@code true} otherwise.
732cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
733cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
734cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean getAnyDataEnabled() {
735cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        synchronized (mDataEnabledLock) {
736cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!(mInternalDataEnabled && mUserDataEnabled && sPolicyDataEnabled)) return false;
737cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            for (ApnContext apnContext : mApnContexts.values()) {
738cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Make sure we don't have a context that is going down
739cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // and is explicitly disabled.
740cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (isDataAllowed(apnContext)) {
741cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return true;
742cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
743cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
744cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
745c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
746c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
747c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
748a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean getAnyDataEnabled(boolean checkUserDataEnabled) {
749a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        synchronized (mDataEnabledLock) {
750a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (!(mInternalDataEnabled && (!checkUserDataEnabled || mUserDataEnabled)
751a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        && (!checkUserDataEnabled || sPolicyDataEnabled)))
752a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return false;
753a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
754a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            for (ApnContext apnContext : mApnContexts.values()) {
755a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // Make sure we dont have a context that going down
756a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // and is explicitly disabled.
757a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (isDataAllowed(apnContext)) {
758a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    return true;
759a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
760a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
761a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return false;
762a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
763a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
764a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
765cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean isDataAllowed(ApnContext apnContext) {
766cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return apnContext.isReady() && isDataAllowed();
767c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
768c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
769cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //****** Called from ServiceStateTracker
770c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
771cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Invoked when ServiceStateTracker observes a transition from GPRS
772cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * attach to detach.
773c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
774cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onDataConnectionDetached() {
775cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        /*
776cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * We presently believe it is unnecessary to tear down the PDP context
777cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * when GPRS detaches, but we should stop the network polling.
778cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         */
779cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log ("onDataConnectionDetached: stop polling and notify detached");
780cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopNetStatPoll();
781cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopDataStallAlarm();
782cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyDataConnection(Phone.REASON_DATA_DETACHED);
783187a39f896f88eb6c5e4306d9595546654825976Wink Saville        mAttached.set(false);
784cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
785c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
786cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onDataConnectionAttached() {
787cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onDataConnectionAttached");
7887ab10e4710bdb54c6d9a5ee01cd443a42a2689f5Sungmin Choi        mAttached.set(true);
789cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getOverallState() == DctConstants.State.CONNECTED) {
790cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onDataConnectionAttached: start polling notify attached");
791cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            startNetStatPoll();
792cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
793cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_DATA_ATTACHED);
794cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
795cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // update APN availability so that APN can be enabled.
796cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_DATA_ATTACHED);
797cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
79812fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        if (mAutoAttachOnCreationConfig) {
79912fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao            mAutoAttachOnCreation = true;
80012fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        }
801ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(Phone.REASON_DATA_ATTACHED);
802cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
803c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
804cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
805cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean isDataAllowed() {
806cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        final boolean internalDataEnabled;
807cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        synchronized (mDataEnabledLock) {
808cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            internalDataEnabled = mInternalDataEnabled;
809cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
810cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
8119894b3fb2f35e21d9cfd45f233ed093589e14c26sy.yun        boolean attachedState = mAttached.get();
812cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
813cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
814cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean recordsLoaded = (r != null) ? r.getRecordsLoaded() : false;
815cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
816a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        //FIXME always attach
817a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean psRestricted = mIsPsRestricted;
818a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        int phoneNum = TelephonyManager.getDefault().getPhoneCount();
819a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (phoneNum > 1) {
820a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            attachedState = true;
821a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            psRestricted = false;
822a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
823a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
824cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean allowed =
8259894b3fb2f35e21d9cfd45f233ed093589e14c26sy.yun                    (attachedState || mAutoAttachOnCreation) &&
826cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    recordsLoaded &&
827cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    (mPhone.getState() == PhoneConstants.State.IDLE ||
828cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                     mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) &&
829cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    internalDataEnabled &&
830cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    (!mPhone.getServiceState().getRoaming() || getDataOnRoamingEnabled()) &&
831a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    //!mIsPsRestricted &&
832a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    !psRestricted &&
833cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    desiredPowerState;
834cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (!allowed && DBG) {
835cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            String reason = "";
8369894b3fb2f35e21d9cfd45f233ed093589e14c26sy.yun            if (!(attachedState || mAutoAttachOnCreation)) {
8379894b3fb2f35e21d9cfd45f233ed093589e14c26sy.yun                reason += " - Attached= " + attachedState;
838cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
839cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!recordsLoaded) reason += " - SIM not loaded";
840cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPhone.getState() != PhoneConstants.State.IDLE &&
841cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
842cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                reason += " - PhoneState= " + mPhone.getState();
843cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                reason += " - Concurrent voice and data not allowed";
844cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
845cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!internalDataEnabled) reason += " - mInternalDataEnabled= false";
846cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPhone.getServiceState().getRoaming() && !getDataOnRoamingEnabled()) {
847cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                reason += " - Roaming and data roaming not enabled";
848cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
849cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mIsPsRestricted) reason += " - mIsPsRestricted= true";
850cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!desiredPowerState) reason += " - desiredPowerState= false";
851cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("isDataAllowed: not allowed due to" + reason);
852c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
853cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return allowed;
854cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
855c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
856ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void setupDataOnConnectableApns(String reason) {
8573fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (DBG) log("setupDataOnConnectableApns: " + reason);
8583fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
8593fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        for (ApnContext apnContext : mPrioritySortedApnContexts) {
8603fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (DBG) log("setupDataOnConnectableApns: apnContext " + apnContext);
861cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.getState() == DctConstants.State.FAILED) {
862cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setState(DctConstants.State.IDLE);
863cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
864ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.isConnectable()) {
865ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                log("setupDataOnConnectableApns: isConnectable() call trySetupData");
866ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setReason(reason);
867ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                trySetupData(apnContext);
868cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
869cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
870c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
871c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
872cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean trySetupData(ApnContext apnContext) {
873cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
874cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("trySetupData for type:" + apnContext.getApnType() +
875cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    " due to " + apnContext.getReason() + " apnContext=" + apnContext);
876cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("trySetupData with mIsPsRestricted=" + mIsPsRestricted);
877cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
878cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
879cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
880cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
881cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
882cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setState(DctConstants.State.CONNECTED);
883cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
884cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
885cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("trySetupData: X We're on the simulator; assuming connected retValue=true");
886cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return true;
887cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
888cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
889cf5205f70eb1eac497164124187a088ecb03fff5Ram        // Allow SETUP_DATA request for E-APN to be completed during emergency call
890cf5205f70eb1eac497164124187a088ecb03fff5Ram        // and MOBILE DATA On/Off cases as well.
891cf5205f70eb1eac497164124187a088ecb03fff5Ram        boolean isEmergencyApn = apnContext.getApnType().equals(PhoneConstants.APN_TYPE_EMERGENCY);
892cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
893a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean checkUserDataEnabled =
894a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    !(apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IMS));
895cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
896cf5205f70eb1eac497164124187a088ecb03fff5Ram        if (apnContext.isConnectable() && (isEmergencyApn ||
897cf5205f70eb1eac497164124187a088ecb03fff5Ram                (isDataAllowed(apnContext) &&
898cf5205f70eb1eac497164124187a088ecb03fff5Ram                getAnyDataEnabled(checkUserDataEnabled) && !isEmergency()))) {
899ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getState() == DctConstants.State.FAILED) {
900ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) log("trySetupData: make a FAILED ApnContext IDLE so its reusable");
901ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setState(DctConstants.State.IDLE);
902ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
903203e588e3c42a81aa8a56f595119c181a63b12caWink Saville            int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
904cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.getState() == DctConstants.State.IDLE) {
905203e588e3c42a81aa8a56f595119c181a63b12caWink Saville
906203e588e3c42a81aa8a56f595119c181a63b12caWink Saville                ArrayList<ApnSetting> waitingApns = buildWaitingApns(apnContext.getApnType(),
907203e588e3c42a81aa8a56f595119c181a63b12caWink Saville                        radioTech);
908cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (waitingApns.isEmpty()) {
909ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    notifyNoData(DcFailCause.MISSING_UNKNOWN_APN, apnContext);
910cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    notifyOffApnsOfAvailability(apnContext.getReason());
911cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("trySetupData: X No APN found retValue=false");
912cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return false;
913cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
914cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setWaitingApns(waitingApns);
915cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) {
916ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        log ("trySetupData: Create from mAllApnSettings : "
917ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                    + apnListToString(mAllApnSettings));
918cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
919cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
920cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
921cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
922cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
923cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("trySetupData: call setupData, waitingApns : "
924cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        + apnListToString(apnContext.getWaitingApns()));
925cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
926203e588e3c42a81aa8a56f595119c181a63b12caWink Saville            boolean retValue = setupData(apnContext, radioTech);
927cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(apnContext.getReason());
928cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
929cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("trySetupData: X retValue=" + retValue);
930cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return retValue;
931cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
932cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
933ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    && apnContext.isConnectable()) {
934cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
935ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
936cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(apnContext.getReason());
937cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log ("trySetupData: X apnContext not 'ready' retValue=false");
938cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
939cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
940c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
941c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
942cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
943cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Disabled apn's still need avail/unavail notificiations - send them out
944cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void notifyOffApnsOfAvailability(String reason) {
945cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
946187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (!mAttached.get() || !apnContext.isReady()) {
947ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) log("notifyOffApnOfAvailability type:" + apnContext.getApnType());
948cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
949cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                            apnContext.getApnType(),
950cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                            PhoneConstants.DataState.DISCONNECTED);
951cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
952ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) {
953187a39f896f88eb6c5e4306d9595546654825976Wink Saville                    log("notifyOffApnsOfAvailability skipped apn due to attached && isReady " +
954cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            apnContext.toString());
955cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
956c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
957c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
958c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
959c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
960cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
961cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * If tearDown is true, this only tears down a CONNECTED session. Presently,
962cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * there is no mechanism for abandoning an CONNECTING session,
963cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * but would likely involve cancelling pending async requests or
964cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * setting a flag or new state to ignore them when they came in
965cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param tearDown true if the underlying DataConnection should be
966cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * disconnected.
967cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param reason reason for the clean up.
9683fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return boolean - true if we did cleanup any connections, false if they
9693fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     *                   were already all disconnected.
970cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
9713fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    protected boolean cleanUpAllConnections(boolean tearDown, String reason) {
972cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("cleanUpAllConnections: tearDown=" + tearDown + " reason=" + reason);
9733fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        boolean didDisconnect = false;
974a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean specificdisable = false;
975a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
976a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (!TextUtils.isEmpty(reason)) {
977a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            specificdisable = reason.equals(Phone.REASON_DATA_SPECIFIC_DISABLED);
978a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
979cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
980cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
9813fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (apnContext.isDisconnected() == false) didDisconnect = true;
982a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (specificdisable) {
983a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IMS)) {
984a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    if (DBG) log("ApnConextType: " + apnContext.getApnType());
985a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    apnContext.setReason(reason);
986a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    cleanUpConnection(tearDown, apnContext);
987a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
988a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
989a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // TODO - only do cleanup if not disconnected
990a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                apnContext.setReason(reason);
991a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                cleanUpConnection(tearDown, apnContext);
992a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
993c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
994cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
995cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopNetStatPoll();
996cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopDataStallAlarm();
997cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
998cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: Do we need mRequestedApnType?
999cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
1000a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1001a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("cleanUpConnection: mDisconnectPendingCount = " + mDisconnectPendingCount);
1002a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (tearDown && mDisconnectPendingCount == 0) {
1003a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyDataDisconnectComplete();
1004a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
1005a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1006a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
10073fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return didDisconnect;
1008cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1009cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1010cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1011cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Cleanup all connections.
1012cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1013cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * TODO: Cleanup only a specified connection passed as a parameter.
1014cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *       Also, make sure when you clean up a conn, if it is last apply
1015cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *       logic as though it is cleanupAllConnections
1016cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1017cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param cause for the clean up.
1018cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1019cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1020cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1021cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onCleanUpAllConnections(String cause) {
1022cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, cause);
1023cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1024cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1025a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void cleanUpConnection(boolean tearDown, ApnContext apnContext) {
1026cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1027cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
1028cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("cleanUpConnection: apn context is null");
1029cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
1030cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1031cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1032454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac = apnContext.getDcAc();
1033cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
1034cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("cleanUpConnection: E tearDown=" + tearDown + " reason=" + apnContext.getReason() +
1035cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    " apnContext=" + apnContext);
1036cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1037cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (tearDown) {
1038cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.isDisconnected()) {
1039cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // The request is tearDown and but ApnContext is not connected.
1040cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // If apnContext is not enabled anymore, break the linkage to the DCAC/DC.
1041cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setState(DctConstants.State.IDLE);
1042cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (!apnContext.isReady()) {
10434750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                    if (dcac != null) {
10444750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                        dcac.tearDown(apnContext, "", null);
10454750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                    }
1046cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setDataConnectionAc(null);
1047cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1048cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1049cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Connection is still there. Try to clean up.
1050cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (dcac != null) {
1051cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (apnContext.getState() != DctConstants.State.DISCONNECTING) {
1052cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        boolean disconnectAll = false;
1053cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (PhoneConstants.APN_TYPE_DUN.equals(apnContext.getApnType())) {
1054a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            // CAF_MSIM is this below condition required.
1055a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            // if (PhoneConstants.APN_TYPE_DUN.equals(PhoneConstants.APN_TYPE_DEFAULT)) {
10561484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                            if (teardownForDun()) {
1057cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                if (DBG) log("tearing down dedicated DUN connection");
1058cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // we need to tear it down - we brought it up just for dun and
1059cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // other people are camped on it and now dun is done.  We need
1060cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // to stop using it and let the normal apn list get used to find
1061cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // connections for the remaining desired connections
1062cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                disconnectAll = true;
1063cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            }
1064cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
1065cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (DBG) {
1066cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            log("cleanUpConnection: tearing down" + (disconnectAll ? " all" :""));
1067cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
1068cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        Message msg = obtainMessage(DctConstants.EVENT_DISCONNECT_DONE, apnContext);
1069cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (disconnectAll) {
1070ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            apnContext.getDcAc().tearDownAll(apnContext.getReason(), msg);
1071cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        } else {
1072ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            apnContext.getDcAc()
1073cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                .tearDown(apnContext, apnContext.getReason(), msg);
1074cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
1075cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.setState(DctConstants.State.DISCONNECTING);
1076a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        mDisconnectPendingCount++;
1077cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1078cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1079cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // apn is connected but no reference to dcac.
1080cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // Should not be happen, but reset the state in case.
1081cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setState(DctConstants.State.IDLE);
1082cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mPhone.notifyDataConnection(apnContext.getReason(),
1083cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                                apnContext.getApnType());
1084cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1085cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1086cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1087cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // force clean up the data connection.
1088ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac != null) dcac.reqReset();
1089cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setState(DctConstants.State.IDLE);
1090cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1091cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setDataConnectionAc(null);
1092cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1093cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1094ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // Make sure reconnection alarm is cleaned up if there is no ApnContext
1095cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // associated to the connection.
1096cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (dcac != null) {
1097ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            cancelReconnectAlarm(apnContext);
1098c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1099cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
1100cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("cleanUpConnection: X tearDown=" + tearDown + " reason=" + apnContext.getReason() +
1101ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    " apnContext=" + apnContext + " dcac=" + apnContext.getDcAc());
1102cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1103cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1104c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1105cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
11061484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt     * Determine if DUN connection is special and we need to teardown on start/stop
11071484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt     */
11081484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt    private boolean teardownForDun() {
11091484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // CDMA always needs to do this the profile id is correct
11101484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        final int rilRat = mPhone.getServiceState().getRilDataRadioTechnology();
11111484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        if (ServiceState.isCdma(rilRat)) return true;
11121484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt
11131484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        return (fetchDunApn() != null);
11141484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt    }
11151484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt
11161484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt    /**
1117ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Cancels the alarm associated with apnContext.
1118cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1119ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * @param apnContext on which the alarm should be stopped.
1120cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1121ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void cancelReconnectAlarm(ApnContext apnContext) {
1122ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnContext == null) return;
1123cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1124ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        PendingIntent intent = apnContext.getReconnectIntent();
1125cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1126cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (intent != null) {
1127cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                AlarmManager am =
1128cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
1129cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                am.cancel(intent);
1130ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setReconnectIntent(null);
1131cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1132c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1133c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1134cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1135cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param types comma delimited list of APN types
1136cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return array of APN types
1137cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1138cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private String[] parseTypes(String types) {
1139c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String[] result;
1140cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // If unset, set to DEFAULT.
1141cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (types == null || types.equals("")) {
1142c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            result = new String[1];
1143cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result[0] = PhoneConstants.APN_TYPE_ALL;
1144cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1145cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result = types.split(",");
1146c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1147c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
1148c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1149c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
115061cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan    private boolean imsiMatches(String imsiDB, String imsiSIM) {
1151fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        // Note: imsiDB value has digit number or 'x' character for seperating USIM information
1152fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        // for MVNO operator. And then digit number is matched at same order and 'x' character
1153fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        // could replace by any digit number.
1154fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        // ex) if imsiDB inserted '310260x10xxxxxx' for GG Operator,
1155fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        //     that means first 6 digits, 8th and 9th digit
1156fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        //     should be set in USIM for GG Operator.
1157fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        int len = imsiDB.length();
1158fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        int idxCompare = 0;
1159fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
1160fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        if (len <= 0) return false;
1161fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        if (len > imsiSIM.length()) return false;
1162fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
1163fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        for (int idx=0; idx<len; idx++) {
1164fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            char c = imsiDB.charAt(idx);
1165fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            if ((c == 'x') || (c == 'X') || (c == imsiSIM.charAt(idx))) {
1166fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                continue;
1167fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            } else {
1168fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                return false;
1169fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            }
1170fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        }
1171fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        return true;
1172fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    }
1173fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
11743262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal    @Override
11753262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal    protected boolean mvnoMatches(IccRecords r, String mvnoType, String mvnoMatchData) {
11763262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        if (mvnoType.equalsIgnoreCase("spn")) {
1177fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            if ((r.getServiceProviderName() != null) &&
11783262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                    r.getServiceProviderName().equalsIgnoreCase(mvnoMatchData)) {
1179fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                return true;
1180fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            }
11813262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        } else if (mvnoType.equalsIgnoreCase("imsi")) {
1182fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            String imsiSIM = r.getIMSI();
11833262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal            if ((imsiSIM != null) && imsiMatches(mvnoMatchData, imsiSIM)) {
1184fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                return true;
1185fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            }
11863262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        } else if (mvnoType.equalsIgnoreCase("gid")) {
1187fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            String gid1 = r.getGid1();
11883262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal            int mvno_match_data_length = mvnoMatchData.length();
118959a71354e0169c7877ffd56d476ddd65ecf5a88dRobert Greenwalt            if ((gid1 != null) && (gid1.length() >= mvno_match_data_length) &&
11903262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                    gid1.substring(0, mvno_match_data_length).equalsIgnoreCase(mvnoMatchData)) {
1191fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                return true;
1192fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            }
1193fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        }
1194fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        return false;
1195fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    }
1196fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
1197796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan    @Override
1198796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan    protected boolean isPermanentFail(DcFailCause dcFailCause) {
1199796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan        return (dcFailCause.isPermanentFail() &&
1200796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan                (mAttached.get() == false || dcFailCause != DcFailCause.SIGNAL_LOST));
1201796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan    }
1202796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan
1203fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    private ApnSetting makeApnSetting(Cursor cursor) {
1204fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        String[] types = parseTypes(
1205fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.TYPE)));
1206fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        ApnSetting apn = new ApnSetting(
1207fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID)),
1208fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NUMERIC)),
1209fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NAME)),
1210fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN)),
1211fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1212fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1213fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY))),
1214fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PORT)),
1215fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1216fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1217fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC))),
1218fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1219fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1220fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY))),
1221fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPORT)),
1222fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)),
1223fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)),
1224fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.AUTH_TYPE)),
1225fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                types,
1226fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROTOCOL)),
1227fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(
1228fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        Telephony.Carriers.ROAMING_PROTOCOL)),
1229fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(
1230fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        Telephony.Carriers.CARRIER_ENABLED)) == 1,
12319d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.BEARER)),
12329d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROFILE_ID)),
12339d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(
12349d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                        Telephony.Carriers.MODEM_COGNITIVE)) == 1,
12359d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MAX_CONNS)),
12369d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(
12379d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                        Telephony.Carriers.WAIT_TIME)),
1238e9701717e43cc5aacbcf624f77a53be92350662cw                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MAX_CONNS_TIME)),
12393262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MTU)),
12403262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_TYPE)),
12413262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_MATCH_DATA)));
1242fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        return apn;
1243fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    }
1244fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
1245cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ArrayList<ApnSetting> createApnList(Cursor cursor) {
12463262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        ArrayList<ApnSetting> mnoApns = new ArrayList<ApnSetting>();
12473262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        ArrayList<ApnSetting> mvnoApns = new ArrayList<ApnSetting>();
1248fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        IccRecords r = mIccRecords.get();
1249fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
1250cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor.moveToFirst()) {
1251cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            do {
12523262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                ApnSetting apn = makeApnSetting(cursor);
12533262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                if (apn == null) {
12543262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                    continue;
12553262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                }
12563262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
12573262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                if (apn.hasMvnoParams()) {
12583262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                    if (r != null && mvnoMatches(r, apn.mvnoType, apn.mvnoMatchData)) {
12593262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                        mvnoApns.add(apn);
1260fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    }
1261fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                } else {
12623262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                    mnoApns.add(apn);
1263fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                }
1264cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } while (cursor.moveToNext());
1265cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
12663262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
12673262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        ArrayList<ApnSetting> result = mvnoApns.isEmpty() ? mnoApns : mvnoApns;
1268cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createApnList: X result=" + result);
1269c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
1270c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1271c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1272454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private boolean dataConnectionNotInUse(DcAsyncChannel dcac) {
1273ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("dataConnectionNotInUse: check if dcac is inuse dcac=" + dcac);
1274cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1275ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getDcAc() == dcac) {
1276cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("dataConnectionNotInUse: in use by apnContext=" + apnContext);
1277cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
1278cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1279cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1280cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: Fix retry handling so free DataConnections have empty apnlists.
1281cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Probably move retry handling into DataConnections and reduce complexity
1282cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // of DCT.
1283cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("dataConnectionNotInUse: tearDownAll");
1284ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        dcac.tearDownAll("No connection", null);
1285cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("dataConnectionNotInUse: not in use return true");
1286cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
1287cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1288cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1289454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel findFreeDataConnection() {
1290454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
1291cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac.isInactiveSync() && dataConnectionNotInUse(dcac)) {
1292cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
1293cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("findFreeDataConnection: found free DataConnection=" +
1294ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        " dcac=" + dcac);
1295cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1296ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                return dcac;
1297cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1298cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1299cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("findFreeDataConnection: NO free DataConnection");
1300cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
1301cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1302cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1303203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    private boolean setupData(ApnContext apnContext, int radioTech) {
1304cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setupData: apnContext=" + apnContext);
1305ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnSetting apnSetting;
13061484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        DcAsyncChannel dcac = null;
1307cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1308ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnSetting = apnContext.getNextWaitingApn();
1309ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnSetting == null) {
1310cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("setupData: return for no apn found!");
1311cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
1312cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1313cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1314231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        int profileId = apnSetting.profileId;
1315231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        if (profileId == 0) {
1316231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen            profileId = getApnProfileID(apnContext.getApnType());
1317231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        }
1318231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen
13191484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // On CDMA, if we're explicitly asking for DUN, we need have
13201484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // a dun-profiled connection so we can't share an existing one
13211484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // On GSM/LTE we can share existing apn connections provided they support
13221484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // this type.
13231484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        if (apnContext.getApnType() != PhoneConstants.APN_TYPE_DUN ||
13241484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                teardownForDun() == false) {
13251484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt            dcac = checkForCompatibleConnectedApnContext(apnContext);
13261484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt            if (dcac != null) {
13271484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // Get the dcacApnSetting for the connection we want to share.
13281484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                ApnSetting dcacApnSetting = dcac.getApnSettingSync();
13291484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                if (dcacApnSetting != null) {
13301484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    // Setting is good, so use it.
13311484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    apnSetting = dcacApnSetting;
13321484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                }
1333ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1334ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
1335ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (dcac == null) {
13363fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (isOnlySingleDcAllowed(radioTech)) {
13373fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (isHigherPriorityApnContextActive(apnContext)) {
13383fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (DBG) {
13393fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        log("setupData: Higher priority ApnContext active.  Ignoring call");
13403fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    }
13413fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    return false;
13423fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                }
13433fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
13443fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // Only lower priority calls left.  Disconnect them all in this single PDP case
13453fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // so that we can bring up the requested higher priority call (once we receive
13463fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // repsonse for deactivate request for the calls we are about to disconnect
13473fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (cleanUpAllConnections(true, Phone.REASON_SINGLE_PDN_ARBITRATION)) {
13483fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // If any call actually requested to be disconnected, means we can't
13493fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // bring up this connection yet as we need to wait for those data calls
13503fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // to be disconnected.
13513fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (DBG) log("setupData: Some calls are disconnecting first.  Wait and retry");
13523fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    return false;
13533fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                }
13543fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
13553fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // No other calls are active, so proceed
13563fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (DBG) log("setupData: Single pdp. Continue setting up data call.");
13573fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
13583fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
1359ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            dcac = findFreeDataConnection();
1360cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1361ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac == null) {
1362ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                dcac = createDataConnection();
1363cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1364cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1365ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac == null) {
1366ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) log("setupData: No free DataConnection and couldn't create one, WEIRD");
1367cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
1368cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1369cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1370ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("setupData: dcac=" + dcac + " apnSetting=" + apnSetting);
1371cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1372cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setDataConnectionAc(dcac);
1373ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setApnSetting(apnSetting);
1374cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setState(DctConstants.State.CONNECTING);
1375cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1376cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1377cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Message msg = obtainMessage();
1378cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        msg.what = DctConstants.EVENT_DATA_SETUP_COMPLETE;
1379cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        msg.obj = apnContext;
138012fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        dcac.bringUp(apnContext, getInitialMaxRetry(), profileId, radioTech, mAutoAttachOnCreation,
138112fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao                msg);
1382cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1383cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setupData: initing!");
1384cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
1385cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1386cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1387c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1388cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Handles changes to the APN database.
1389c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1390cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onApnChanged() {
1391cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        DctConstants.State overallState = getOverallState();
1392cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isDisconnected = (overallState == DctConstants.State.IDLE ||
1393cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                overallState == DctConstants.State.FAILED);
1394cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1395cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone instanceof GSMPhone) {
1396cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // The "current" may no longer be valid.  MMS depends on this to send properly. TBD
1397cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ((GSMPhone)mPhone).updateCurrentCarrierInProvider();
1398cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1399cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1400cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: It'd be nice to only do this if the changed entrie(s)
1401cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // match the current operator.
1402cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onApnChanged: createAllApnList and cleanUpAllConnections");
1403cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        createAllApnList();
14045d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi        setInitialAttachApn();
1405cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(!isDisconnected, Phone.REASON_APN_CHANGED);
14063f52153a5409861eaa6e9aee5c8560bf3447cf48Hui Wang        setupDataOnConnectableApns(Phone.REASON_APN_CHANGED);
1407c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1408c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1409c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1410cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param cid Connection id provided from RIL.
1411cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return DataConnectionAc associated with specified cid.
1412c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1413454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel findDataConnectionAcByCid(int cid) {
1414454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
1415cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac.getCidSync() == cid) {
1416cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return dcac;
1417cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1418c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1419cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
1420c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1421c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1422cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // TODO: For multiple Active APNs not exactly sure how to do this.
1423c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
1424cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void gotoIdleAndNotifyDataConnection(String reason) {
1425cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("gotoIdleAndNotifyDataConnection: reason=" + reason);
1426cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyDataConnection(reason);
1427cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mActiveApn = null;
1428cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1429cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
14303fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    /**
14313fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * "Active" here means ApnContext isEnabled() and not in FAILED state
14323fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @param apnContext to compare with
14333fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return true if higher priority active apn found
14343fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     */
14353fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean isHigherPriorityApnContextActive(ApnContext apnContext) {
14363fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        for (ApnContext otherContext : mPrioritySortedApnContexts) {
14373fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (apnContext.getApnType().equalsIgnoreCase(otherContext.getApnType())) return false;
14383fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (otherContext.isEnabled() && otherContext.getState() != DctConstants.State.FAILED) {
14393fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                return true;
14403fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
14413fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
14423fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return false;
14433fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    }
14443fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
14453fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    /**
14463fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * Reports if we support multiple connections or not.
14473fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * This is a combination of factors, based on carrier and RAT.
14483fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @param rilRadioTech the RIL Radio Tech currently in use
14493fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return true if only single DataConnection is allowed
14503fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     */
14513fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean isOnlySingleDcAllowed(int rilRadioTech) {
14523fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        int[] singleDcRats = mPhone.getContext().getResources().getIntArray(
14533fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                com.android.internal.R.array.config_onlySingleDcAllowed);
14543fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        boolean onlySingleDcAllowed = false;
14553fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (Build.IS_DEBUGGABLE &&
14563fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                SystemProperties.getBoolean("persist.telephony.test.singleDc", false)) {
14573fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            onlySingleDcAllowed = true;
14583fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
14593fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (singleDcRats != null) {
14603fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            for (int i=0; i < singleDcRats.length && onlySingleDcAllowed == false; i++) {
14613fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (rilRadioTech == singleDcRats[i]) onlySingleDcAllowed = true;
14623fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
14633fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
14643fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
14653fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (DBG) log("isOnlySingleDcAllowed(" + rilRadioTech + "): " + onlySingleDcAllowed);
14663fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return onlySingleDcAllowed;
14673fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    }
14683fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
1469cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1470cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void restartRadio() {
1471cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("restartRadio: ************TURN OFF RADIO**************");
1472cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, Phone.REASON_RADIO_TURNED_OFF);
1473cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().powerOffRadioSafely(this);
1474cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        /* Note: no need to call setRadioPower(true).  Assuming the desired
1475cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * radio power state is still ON (as tracked by ServiceStateTracker),
1476cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * ServiceStateTracker will call setRadioPower when it receives the
1477cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * RADIO_STATE_CHANGED notification for the power off.  And if the
1478cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * desired power state has changed in the interim, we don't want to
1479cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * override it with an unconditional power on.
1480cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         */
1481cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1482cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int reset = Integer.parseInt(SystemProperties.get("net.ppp.reset-by-timeout", "0"));
1483cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        SystemProperties.set("net.ppp.reset-by-timeout", String.valueOf(reset+1));
1484cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1485cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1486cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1487cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Return true if data connection need to be setup after disconnected due to
1488cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * reason.
1489cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1490cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param reason the reason why data is disconnected
1491cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return true if try setup data connection is need for this reason
1492cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
14933fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean retryAfterDisconnected(ApnContext apnContext) {
1494cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean retry = true;
14953fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        String reason = apnContext.getReason();
1496cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
14973fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) ||
14983fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())
14993fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                 && isHigherPriorityApnContextActive(apnContext))) {
1500cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            retry = false;
1501cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1502cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return retry;
1503cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1504cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1505cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void startAlarmForReconnect(int delay, ApnContext apnContext) {
1506cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String apnType = apnContext.getApnType();
150774672e8ee972f12406b72551261b4cc7e0651933Wink Saville
150874672e8ee972f12406b72551261b4cc7e0651933Wink Saville        Intent intent = new Intent(INTENT_RECONNECT_ALARM + "." + apnType);
150974672e8ee972f12406b72551261b4cc7e0651933Wink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, apnContext.getReason());
1510cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, apnType);
1511cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1512a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // Get current sub id.
1513a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        long subId = SubscriptionManager.getDefaultDataSubId();
1514a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
1515a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
151674672e8ee972f12406b72551261b4cc7e0651933Wink Saville        if (DBG) {
151774672e8ee972f12406b72551261b4cc7e0651933Wink Saville            log("startAlarmForReconnect: delay=" + delay + " action=" + intent.getAction()
151874672e8ee972f12406b72551261b4cc7e0651933Wink Saville                    + " apn=" + apnContext);
151974672e8ee972f12406b72551261b4cc7e0651933Wink Saville        }
152074672e8ee972f12406b72551261b4cc7e0651933Wink Saville
1521ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        PendingIntent alarmIntent = PendingIntent.getBroadcast (mPhone.getContext(), 0,
1522ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        intent, PendingIntent.FLAG_UPDATE_CURRENT);
1523ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setReconnectIntent(alarmIntent);
1524ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1525ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                SystemClock.elapsedRealtime() + delay, alarmIntent);
1526ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
1527cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1528ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void startAlarmForRestartTrySetup(int delay, ApnContext apnContext) {
1529ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        String apnType = apnContext.getApnType();
153074672e8ee972f12406b72551261b4cc7e0651933Wink Saville        Intent intent = new Intent(INTENT_RESTART_TRYSETUP_ALARM + "." + apnType);
1531ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        intent.putExtra(INTENT_RESTART_TRYSETUP_ALARM_EXTRA_TYPE, apnType);
1532cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
153374672e8ee972f12406b72551261b4cc7e0651933Wink Saville        if (DBG) {
153474672e8ee972f12406b72551261b4cc7e0651933Wink Saville            log("startAlarmForRestartTrySetup: delay=" + delay + " action=" + intent.getAction()
153574672e8ee972f12406b72551261b4cc7e0651933Wink Saville                    + " apn=" + apnContext);
153674672e8ee972f12406b72551261b4cc7e0651933Wink Saville        }
1537cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        PendingIntent alarmIntent = PendingIntent.getBroadcast (mPhone.getContext(), 0,
1538cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                        intent, PendingIntent.FLAG_UPDATE_CURRENT);
1539ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setReconnectIntent(alarmIntent);
1540ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1541cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                SystemClock.elapsedRealtime() + delay, alarmIntent);
1542cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1543cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1544ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void notifyNoData(DcFailCause lastFailCauseCode,
1545cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                              ApnContext apnContext) {
1546cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log( "notifyNoData: type=" + apnContext.getApnType());
1547796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan        if (isPermanentFail(lastFailCauseCode)
1548cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            && (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT))) {
1549cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
1550cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1551cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1552cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1553cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onRecordsLoaded() {
1554cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onRecordsLoaded: createAllApnList");
155512fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        mAutoAttachOnCreationConfig = mPhone.getContext().getResources()
155612fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao                .getBoolean(com.android.internal.R.bool.config_auto_attach_data_on_creation);
1557cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        createAllApnList();
15585d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi        setInitialAttachApn();
155922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPhone.mCi.getRadioState().isOn()) {
1560cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRecordsLoaded: notifying data availability");
1561cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_SIM_LOADED);
1562cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1563ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(Phone.REASON_SIM_LOADED);
1564cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1565cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1566cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1567cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onSetDependencyMet(String apnType, boolean met) {
1568cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // don't allow users to tweak hipri to work around default dependency not met
1569cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_HIPRI.equals(apnType)) return;
1570cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1571cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1572cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
1573cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onSetDependencyMet: ApnContext not found in onSetDependencyMet(" +
1574cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnType + ", " + met + ")");
1575cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
1576cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1577cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        applyNewState(apnContext, apnContext.isEnabled(), met);
1578cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_DEFAULT.equals(apnType)) {
1579cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // tie actions on default to similar actions on HIPRI regarding dependencyMet
1580cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext = mApnContexts.get(PhoneConstants.APN_TYPE_HIPRI);
1581cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext != null) applyNewState(apnContext, apnContext.isEnabled(), met);
1582cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1583cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1584c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1585cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void applyNewState(ApnContext apnContext, boolean enabled, boolean met) {
1586cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean cleanup = false;
1587cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean trySetup = false;
1588cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
1589cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("applyNewState(" + apnContext.getApnType() + ", " + enabled +
1590cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    "(" + apnContext.isEnabled() + "), " + met + "(" +
1591cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.getDependencyMet() +"))");
1592cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1593cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext.isReady()) {
1594305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt            cleanup = true;
15952428693913ae731d4ace3414429f5e91af24ea36Wink Saville            if (enabled && met) {
15962428693913ae731d4ace3414429f5e91af24ea36Wink Saville                DctConstants.State state = apnContext.getState();
15972428693913ae731d4ace3414429f5e91af24ea36Wink Saville                switch(state) {
15982428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case CONNECTING:
15992428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case SCANNING:
16002428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case CONNECTED:
16012428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case DISCONNECTING:
16022428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // We're "READY" and active so just return
16032428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        if (DBG) log("applyNewState: 'ready' so return");
16042428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        return;
16052428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case IDLE:
16062428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // fall through: this is unexpected but if it happens cleanup and try setup
16072428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case FAILED:
16082428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case RETRYING: {
16092428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // We're "READY" but not active so disconnect (cleanup = true) and
16102428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // connect (trySetup = true) to be sure we retry the connection.
16112428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        trySetup = true;
16122428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        apnContext.setReason(Phone.REASON_DATA_ENABLED);
16132428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        break;
16142428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    }
16152428693913ae731d4ace3414429f5e91af24ea36Wink Saville                }
1616305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt            } else if (met) {
1617cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setReason(Phone.REASON_DATA_DISABLED);
1618305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // If ConnectivityService has disabled this network, stop trying to bring
1619305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // it up, but do not tear it down - ConnectivityService will do that
1620305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // directly by talking with the DataConnection.
16211484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                //
16221484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // This doesn't apply to DUN, however.  Those connections have special
16231484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // requirements from carriers and we need stop using them when the dun
16241484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // request goes away.  This applies to both CDMA and GSM because they both
16251484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // can declare the DUN APN sharable by default traffic, thus still satisfying
16261484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // those requests and not torn down organically.
16271484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                if (apnContext.getApnType() == PhoneConstants.APN_TYPE_DUN && teardownForDun()) {
16281484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    cleanup = true;
16291484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                } else {
16301484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    cleanup = false;
16311484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                }
1632cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1633cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_UNMET);
1634cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1635cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1636cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (enabled && met) {
1637cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apnContext.isEnabled()) {
1638cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_MET);
1639cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1640cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setReason(Phone.REASON_DATA_ENABLED);
1641c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1642cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apnContext.getState() == DctConstants.State.FAILED) {
1643cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setState(DctConstants.State.IDLE);
1644cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1645cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                trySetup = true;
1646cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1647cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1648cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setEnabled(enabled);
1649cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setDependencyMet(met);
1650cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cleanup) cleanUpConnection(true, apnContext);
1651cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (trySetup) trySetupData(apnContext);
1652cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1653c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1654454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel checkForCompatibleConnectedApnContext(ApnContext apnContext) {
1655cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String apnType = apnContext.getApnType();
1656cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnSetting dunSetting = null;
1657cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1658cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_DUN.equals(apnType)) {
1659cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            dunSetting = fetchDunApn();
1660cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1661ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) {
1662ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            log("checkForCompatibleConnectedApnContext: apnContext=" + apnContext );
1663ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
1664cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1665454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel potentialDcac = null;
1666ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnContext potentialApnCtx = null;
1667ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        for (ApnContext curApnCtx : mApnContexts.values()) {
1668454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel curDcac = curApnCtx.getDcAc();
1669a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("curDcac: " + curDcac);
1670ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (curDcac != null) {
1671ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                ApnSetting apnSetting = curApnCtx.getApnSetting();
1672a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("apnSetting: " + apnSetting);
1673cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (dunSetting != null) {
1674cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (dunSetting.equals(apnSetting)) {
1675ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        switch (curApnCtx.getState()) {
1676cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            case CONNECTED:
1677cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                if (DBG) {
1678ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                    log("checkForCompatibleConnectedApnContext:"
1679ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                            + " found dun conn=" + curDcac
1680ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                            + " curApnCtx=" + curApnCtx);
1681cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                }
1682ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                return curDcac;
1683ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            case RETRYING:
1684cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            case CONNECTING:
1685ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                potentialDcac = curDcac;
1686ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                potentialApnCtx = curApnCtx;
1687cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            default:
1688cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // Not connected, potential unchanged
1689cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                break;
1690cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
1691cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1692cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else if (apnSetting != null && apnSetting.canHandleType(apnType)) {
1693ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    switch (curApnCtx.getState()) {
1694cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        case CONNECTED:
1695cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            if (DBG) {
1696ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                log("checkForCompatibleConnectedApnContext:"
1697ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        + " found canHandle conn=" + curDcac
1698ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        + " curApnCtx=" + curApnCtx);
1699cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            }
1700ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            return curDcac;
1701ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        case RETRYING:
1702cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        case CONNECTING:
1703ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            potentialDcac = curDcac;
1704ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            potentialApnCtx = curApnCtx;
1705cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        default:
1706cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            // Not connected, potential unchanged
1707cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            break;
1708cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1709cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1710ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            } else {
1711ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) {
1712ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    log("checkForCompatibleConnectedApnContext: not conn curApnCtx=" + curApnCtx);
1713ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                }
1714cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1715cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1716ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (potentialDcac != null) {
1717cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
1718ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                log("checkForCompatibleConnectedApnContext: found potential conn=" + potentialDcac
1719ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        + " curApnCtx=" + potentialApnCtx);
1720cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1721ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            return potentialDcac;
1722cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1723c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1724ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("checkForCompatibleConnectedApnContext: NO conn apnContext=" + apnContext);
1725cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
1726cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1727c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1728cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1729cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onEnableApn(int apnId, int enabled) {
1730cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnIdToType(apnId));
1731cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
1732cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onEnableApn(" + apnId + ", " + enabled + "): NO ApnContext");
1733cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
1734cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1735cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO change our retry manager to use the appropriate numbers for the new APN
1736cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onEnableApn: apnContext=" + apnContext + " call applyNewState");
1737cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        applyNewState(apnContext, enabled == DctConstants.ENABLED, apnContext.getDependencyMet());
1738cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1739c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1740cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1741cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // TODO: We shouldnt need this.
1742cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean onTrySetupData(String reason) {
1743cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onTrySetupData: reason=" + reason);
1744ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(reason);
1745cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
1746cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1747c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1748cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean onTrySetupData(ApnContext apnContext) {
1749cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onTrySetupData: apnContext=" + apnContext);
1750cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return trySetupData(apnContext);
1751cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1752c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1753cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1754cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onRoamingOff() {
1755cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onRoamingOff");
1756c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1757cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mUserDataEnabled == false) return;
1758c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1759cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getDataOnRoamingEnabled() == false) {
1760cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_OFF);
1761ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_ROAMING_OFF);
1762cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1763cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_ROAMING_OFF);
1764cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1765cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1766cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1767cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1768cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onRoamingOn() {
1769cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mUserDataEnabled == false) return;
1770cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1771cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getDataOnRoamingEnabled()) {
1772cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRoamingOn: setup data on roaming");
1773ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_ROAMING_ON);
1774cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_ROAMING_ON);
1775cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1776cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRoamingOn: Tear down data connection on roaming.");
1777cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpAllConnections(true, Phone.REASON_ROAMING_ON);
1778cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
1779cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1780cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1781cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1782cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1783cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onRadioAvailable() {
1784cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onRadioAvailable");
1785cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
1786cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
1787cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
1788cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // setState(DctConstants.State.CONNECTED);
1789cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(null);
1790cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1791cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("onRadioAvailable: We're on the simulator; assuming data is connected");
1792cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1793cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1794cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
1795cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (r != null && r.getRecordsLoaded()) {
1796cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(null);
1797cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1798cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1799cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getOverallState() != DctConstants.State.IDLE) {
1800cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpConnection(true, null);
1801cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1802cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1803cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1804cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1805cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onRadioOffOrNotAvailable() {
1806cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Make sure our reconnect delay starts at the initial value
1807cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // next time the radio comes on
1808cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1809cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mReregisterOnReconnectFailure = false;
1810cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1811cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
1812cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
1813cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
1814cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("We're on the simulator; assuming radio off is meaningless");
1815cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1816cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRadioOffOrNotAvailable: is off and clean up all connections");
1817cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpAllConnections(false, Phone.REASON_RADIO_TURNED_OFF);
1818cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1819cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyOffApnsOfAvailability(null);
1820cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1821cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1822c9b81a0c05128694c617fcdd67e73821895822feWink Saville    @Override
1823c9b81a0c05128694c617fcdd67e73821895822feWink Saville    protected void completeConnection(ApnContext apnContext) {
1824c9b81a0c05128694c617fcdd67e73821895822feWink Saville        boolean isProvApn = apnContext.isProvisioningApn();
1825c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1826c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (DBG) log("completeConnection: successful, notify the world apnContext=" + apnContext);
1827c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1828c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (mIsProvisioning && !TextUtils.isEmpty(mProvisioningUrl)) {
1829c9b81a0c05128694c617fcdd67e73821895822feWink Saville            if (DBG) {
1830c9b81a0c05128694c617fcdd67e73821895822feWink Saville                log("completeConnection: MOBILE_PROVISIONING_ACTION url="
1831c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        + mProvisioningUrl);
1832c9b81a0c05128694c617fcdd67e73821895822feWink Saville            }
1833c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt            Intent newIntent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN,
1834c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt                    Intent.CATEGORY_APP_BROWSER);
1835c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt            newIntent.setData(Uri.parse(mProvisioningUrl));
1836c9b81a0c05128694c617fcdd67e73821895822feWink Saville            newIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
1837c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    Intent.FLAG_ACTIVITY_NEW_TASK);
1838c9b81a0c05128694c617fcdd67e73821895822feWink Saville            try {
1839c9b81a0c05128694c617fcdd67e73821895822feWink Saville                mPhone.getContext().startActivity(newIntent);
1840c9b81a0c05128694c617fcdd67e73821895822feWink Saville            } catch (ActivityNotFoundException e) {
1841c9b81a0c05128694c617fcdd67e73821895822feWink Saville                loge("completeConnection: startActivityAsUser failed" + e);
1842c9b81a0c05128694c617fcdd67e73821895822feWink Saville            }
1843c9b81a0c05128694c617fcdd67e73821895822feWink Saville        }
1844c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mIsProvisioning = false;
1845c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mProvisioningUrl = null;
18462b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        if (mProvisioningSpinner != null) {
18472b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            sendMessage(obtainMessage(DctConstants.CMD_CLEAR_PROVISIONING_SPINNER,
18482b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner));
18492b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        }
1850c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1851c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1852c9b81a0c05128694c617fcdd67e73821895822feWink Saville        startNetStatPoll();
1853c9b81a0c05128694c617fcdd67e73821895822feWink Saville        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
1854c9b81a0c05128694c617fcdd67e73821895822feWink Saville    }
1855c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1856ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
1857ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * A SETUP (aka bringUp) has completed, possibly with an error. If
1858ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * there is an error this method will call {@link #onDataSetupCompleteError}.
1859ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
1860cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1861cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onDataSetupComplete(AsyncResult ar) {
1862608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt
1863ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        DcFailCause cause = DcFailCause.UNKNOWN;
1864cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean handleError = false;
1865cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = null;
1866cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1867cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(ar.userObj instanceof ApnContext){
1868cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext = (ApnContext)ar.userObj;
1869cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1870cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            throw new RuntimeException("onDataSetupComplete: No apnContext");
1871cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1872cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1873cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (ar.exception == null) {
1874454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = apnContext.getDcAc();
1875cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1876cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (RADIO_TESTS) {
1877cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Note: To change radio.test.onDSC.null.dcac from command line you need to
1878cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // adb root and adb remount and from the command line you can only change the
1879cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // value to 1 once. To change it a second time you can reboot or execute
1880cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // adb shell stop and then adb shell start. The command line to set the value is:
1881ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink 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');"
1882cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ContentResolver cr = mPhone.getContext().getContentResolver();
1883cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                String radioTestProperty = "radio.test.onDSC.null.dcac";
1884cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (Settings.System.getInt(cr, radioTestProperty, 0) == 1) {
1885cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: " + radioTestProperty +
1886cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            " is true, set dcac to null and reset property to false");
1887cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    dcac = null;
1888cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    Settings.System.putInt(cr, radioTestProperty, 0);
1889cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: " + radioTestProperty + "=" +
1890cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            Settings.System.getInt(mPhone.getContext().getContentResolver(),
1891cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                    radioTestProperty, -1));
1892cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1893c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1894cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac == null) {
1895cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("onDataSetupComplete: no connection to DC, handle as error");
1896ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                cause = DcFailCause.CONNECTION_TO_DATACONNECTIONAC_BROKEN;
1897cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                handleError = true;
1898cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1899cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ApnSetting apn = apnContext.getApnSetting();
1900cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
1901cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: success apn=" + (apn == null ? "unknown" : apn.apn));
1902cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1903cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn != null && apn.proxy != null && apn.proxy.length() != 0) {
1904cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    try {
1905cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        String port = apn.port;
1906cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (TextUtils.isEmpty(port)) port = "8080";
19079c180aedfc9f0d20525c0128487d3500e6c0a715Jason Monk                        ProxyInfo proxy = new ProxyInfo(apn.proxy,
1908cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                Integer.parseInt(port), null);
1909cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        dcac.setLinkPropertiesHttpProxySync(proxy);
1910cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    } catch (NumberFormatException e) {
1911cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        loge("onDataSetupComplete: NumberFormatException making ProxyProperties (" +
1912cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                apn.port + "): " + e);
1913cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1914cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1915cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1916cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // everything is setup
1917cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if(TextUtils.equals(apnContext.getApnType(),PhoneConstants.APN_TYPE_DEFAULT)) {
1918ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "true");
191922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mCanSetPreferApn && mPreferredApn == null) {
1920cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (DBG) log("onDataSetupComplete: PREFERED APN is null");
1921cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mPreferredApn = apn;
1922cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (mPreferredApn != null) {
1923cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            setPreferredApn(mPreferredApn.id);
1924cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
1925cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1926cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1927ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
1928cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1929c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1930c9b81a0c05128694c617fcdd67e73821895822feWink Saville                // A connection is setup
1931c9b81a0c05128694c617fcdd67e73821895822feWink Saville                apnContext.setState(DctConstants.State.CONNECTED);
1932c9b81a0c05128694c617fcdd67e73821895822feWink Saville                boolean isProvApn = apnContext.isProvisioningApn();
1933b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                final ConnectivityManager cm = ConnectivityManager.from(mPhone.getContext());
1934b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                if (mProvisionBroadcastReceiver != null) {
1935b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mPhone.getContext().unregisterReceiver(mProvisionBroadcastReceiver);
1936b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mProvisionBroadcastReceiver = null;
1937b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                }
1938c9b81a0c05128694c617fcdd67e73821895822feWink Saville                if ((!isProvApn) || mIsProvisioning) {
1939b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // Hide any provisioning notification.
1940b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    cm.setProvisioningNotificationVisible(false, ConnectivityManager.TYPE_MOBILE,
1941b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                            mProvisionActionName);
1942c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // Complete the connection normally notifying the world we're connected.
1943c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // We do this if this isn't a special provisioning apn or if we've been
1944c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // told its time to provision.
1945c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    completeConnection(apnContext);
1946c9b81a0c05128694c617fcdd67e73821895822feWink Saville                } else {
1947c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // This is a provisioning APN that we're reporting as connected. Later
1948c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // when the user desires to upgrade this to a "default" connection,
1949c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // mIsProvisioning == true, we'll go through the code path above.
1950c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // mIsProvisioning becomes true when CMD_ENABLE_MOBILE_PROVISIONING
1951c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // is sent to the DCT.
1952c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    if (DBG) {
1953c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        log("onDataSetupComplete: successful, BUT send connected to prov apn as"
1954c9b81a0c05128694c617fcdd67e73821895822feWink Saville                                + " mIsProvisioning:" + mIsProvisioning + " == false"
1955c9b81a0c05128694c617fcdd67e73821895822feWink Saville                                + " && (isProvisioningApn:" + isProvApn + " == true");
1956c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    }
1957c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1958b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // While radio is up, grab provisioning URL.  The URL contains ICCID which
1959b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // disappears when radio is off.
1960b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mProvisionBroadcastReceiver = new ProvisionNotificationBroadcastReceiver(
19612b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                            cm.getMobileProvisioningUrl(),
19622b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                            TelephonyManager.getDefault().getNetworkOperatorName());
1963b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mPhone.getContext().registerReceiver(mProvisionBroadcastReceiver,
1964b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                            new IntentFilter(mProvisionActionName));
1965b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // Put up user notification that sign-in is required.
1966b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    cm.setProvisioningNotificationVisible(true, ConnectivityManager.TYPE_MOBILE,
1967b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                            mProvisionActionName);
1968b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // Turn off radio to save battery and avoid wasting carrier resources.
1969b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // The network isn't usable and network validation will just fail anyhow.
1970b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    setRadio(false);
1971b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
1972c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    Intent intent = new Intent(
1973c9b81a0c05128694c617fcdd67e73821895822feWink Saville                            TelephonyIntents.ACTION_DATA_CONNECTION_CONNECTED_TO_PROVISIONING_APN);
1974c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    intent.putExtra(PhoneConstants.DATA_APN_KEY, apnContext.getApnSetting().apn);
1975c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnContext.getApnType());
1976c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1977c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    String apnType = apnContext.getApnType();
1978c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    LinkProperties linkProperties = getLinkProperties(apnType);
1979c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    if (linkProperties != null) {
1980c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties);
1981c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        String iface = linkProperties.getInterfaceName();
1982c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        if (iface != null) {
1983c9b81a0c05128694c617fcdd67e73821895822feWink Saville                            intent.putExtra(PhoneConstants.DATA_IFACE_NAME_KEY, iface);
1984c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        }
1985c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    }
1986608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                    NetworkCapabilities networkCapabilities = getNetworkCapabilities(apnType);
198796cce86cf08e37e0f09ed5057b1196e26b302743Robert Greenwalt                    if (networkCapabilities != null) {
198896cce86cf08e37e0f09ed5057b1196e26b302743Robert Greenwalt                        intent.putExtra(PhoneConstants.DATA_NETWORK_CAPABILITIES_KEY,
198996cce86cf08e37e0f09ed5057b1196e26b302743Robert Greenwalt                                networkCapabilities);
1990c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    }
1991c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1992c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    mPhone.getContext().sendBroadcastAsUser(intent, UserHandle.ALL);
1993c9b81a0c05128694c617fcdd67e73821895822feWink Saville                }
1994c9b81a0c05128694c617fcdd67e73821895822feWink Saville                if (DBG) {
1995c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    log("onDataSetupComplete: SETUP complete type=" + apnContext.getApnType()
1996c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        + ", reason:" + apnContext.getReason());
1997c9b81a0c05128694c617fcdd67e73821895822feWink Saville                }
1998c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1999cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2000ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            cause = (DcFailCause) (ar.result);
2001cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
2002cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ApnSetting apn = apnContext.getApnSetting();
2003cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log(String.format("onDataSetupComplete: error apn=%s cause=%s",
2004cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        (apn == null ? "unknown" : apn.apn), cause));
2005c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2006cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cause.isEventLoggable()) {
2007cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Log this failure to the Event Logs.
2008cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                int cid = getCellLocationId();
2009cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                EventLog.writeEvent(EventLogTags.PDP_SETUP_FAIL,
2010cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        cause.ordinal(), cid, TelephonyManager.getDefault().getNetworkType());
2011c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
20120742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela            ApnSetting apn = apnContext.getApnSetting();
20130742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela            mPhone.notifyPreciseDataConnectionFailed(apnContext.getReason(),
20140742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela                    apnContext.getApnType(), apn != null ? apn.apn : "unknown", cause.toString());
2015cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2016cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Count permanent failures and remove the APN we just tried
2017796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan            if (isPermanentFail(cause)) apnContext.decWaitingApnsPermFailCount();
2018cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2019cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.removeWaitingApn(apnContext.getApnSetting());
2020cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
2021cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log(String.format("onDataSetupComplete: WaitingApns.size=%d" +
2022cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        " WaitingApnsPermFailureCountDown=%d",
2023cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.getWaitingApns().size(),
2024cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.getWaitingApnsPermFailCount()));
2025c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2026cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            handleError = true;
2027cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2028cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2029cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (handleError) {
2030ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            onDataSetupCompleteError(ar);
2031ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
2032a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2033a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        /* If flag is set to false after SETUP_DATA_CALL is invoked, we need
2034a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         * to clean data connections.
2035a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         */
2036a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (!mInternalDataEnabled) {
2037a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            cleanUpAllConnections(null);
2038a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2039a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2040ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
2041cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2042ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
2043ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville     * @return number of milli-seconds to delay between trying apns'
2044ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville     */
2045ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville    private int getApnDelay() {
2046ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        if (mFailFast) {
2047ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville            return SystemProperties.getInt("persist.radio.apn_ff_delay",
2048ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville                    APN_FAIL_FAST_DELAY_DEFAULT_MILLIS);
2049ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        } else {
2050ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville            return SystemProperties.getInt("persist.radio.apn_delay", APN_DELAY_DEFAULT_MILLIS);
2051ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        }
2052ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville    }
2053ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville
2054ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville    /**
2055ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Error has occurred during the SETUP {aka bringUP} request and the DCT
2056ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * should either try the next waiting APN or start over from the
2057ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * beginning if the list is empty. Between each SETUP request there will
2058ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville     * be a delay defined by {@link #getApnDelay()}.
2059ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
2060ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    @Override
2061ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    protected void onDataSetupCompleteError(AsyncResult ar) {
2062ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        String reason = "";
2063ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnContext apnContext = null;
2064ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
2065ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if(ar.userObj instanceof ApnContext){
2066ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext = (ApnContext)ar.userObj;
2067ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        } else {
2068ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            throw new RuntimeException("onDataSetupCompleteError: No apnContext");
2069ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
2070ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
2071ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // See if there are more APN's to try
2072ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnContext.getWaitingApns().isEmpty()) {
2073ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext.setState(DctConstants.State.FAILED);
2074ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType());
2075ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
2076ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext.setDataConnectionAc(null);
2077ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
2078ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getWaitingApnsPermFailCount() == 0) {
2079ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) {
2080017166876a51eda9ae6b3254119023604e249bc5Wink Saville                    log("onDataSetupCompleteError: All APN's had permanent failures, stop retrying");
2081c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
2082cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
2083e056c8263473f67dc78630f5535c3664fabacd23Wink Saville                int delay = getApnDelay();
2084ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) {
2085da1dd2e1bccb6141109a65d4e40253f39c405537Wink Saville                    log("onDataSetupCompleteError: Not all APN's had permanent failures delay="
2086da1dd2e1bccb6141109a65d4e40253f39c405537Wink Saville                            + delay);
2087ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                }
2088017166876a51eda9ae6b3254119023604e249bc5Wink Saville                startAlarmForRestartTrySetup(delay, apnContext);
2089c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2090ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        } else {
2091da1dd2e1bccb6141109a65d4e40253f39c405537Wink Saville            if (DBG) log("onDataSetupCompleteError: Try next APN");
2092ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext.setState(DctConstants.State.SCANNING);
2093ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // Wait a bit before trying the next APN, so that
2094ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // we're not tying up the RIL command channel
2095ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville            startAlarmForReconnect(getApnDelay(), apnContext);
2096c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2097c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2098c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2099c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
2100cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Called when EVENT_DISCONNECT_DONE is received.
2101c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
2102cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2103cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onDisconnectDone(int connId, AsyncResult ar) {
2104cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = null;
2105cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2106cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (ar.userObj instanceof ApnContext) {
2107cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext = (ApnContext) ar.userObj;
2108cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2109cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onDisconnectDone: Invalid ar in onDisconnectDone, ignore");
2110cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
2111c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2113cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE apnContext=" + apnContext);
2114cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setState(DctConstants.State.IDLE);
2115cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2116cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
2117cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2118cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // if all data connection are gone, check whether Airplane mode request was
2119cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // pending.
2120cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isDisconnected()) {
2121cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPhone.getServiceStateTracker().processPendingRadioPowerOffAfterDataOff()) {
2122449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                if(DBG) log("onDisconnectDone: radio will be turned off, no retries");
2123cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Radio will be turned off. No need to retry data setup
2124cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setApnSetting(null);
2125cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setDataConnectionAc(null);
2126a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2127a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // Need to notify disconnect as well, in the case of switching Airplane mode.
2128a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // Otherwise, it would cause 30s delayed to turn on Airplane mode.
2129a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mDisconnectPendingCount > 0)
2130a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mDisconnectPendingCount--;
2131a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2132a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mDisconnectPendingCount == 0) {
2133a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    notifyDataDisconnectComplete();
2134a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    notifyAllDataDisconnected();
2135a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
2136cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return;
2137cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2138c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2139c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2140cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // If APN is still enabled, try to bring it back up automatically
21413fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (mAttached.get() && apnContext.isReady() && retryAfterDisconnected(apnContext)) {
2142ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
2143cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Wait a bit before trying the next APN, so that
2144cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // we're not tying up the RIL command channel.
2145cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // This also helps in any external dependency to turn off the context.
2146449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            if(DBG) log("onDisconnectDone: attached, ready and retry after disconnect");
2147ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville            startAlarmForReconnect(getApnDelay(), apnContext);
2148c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
2149449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            boolean restartRadioAfterProvisioning = mPhone.getContext().getResources().getBoolean(
2150449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                    com.android.internal.R.bool.config_restartRadioAfterProvisioning);
2151449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville
2152449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            if (apnContext.isProvisioningApn() && restartRadioAfterProvisioning) {
2153449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                log("onDisconnectDone: restartRadio after provisioning");
2154449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                restartRadio();
2155449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            }
2156cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setApnSetting(null);
2157cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setDataConnectionAc(null);
21583fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())) {
2159449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                if(DBG) log("onDisconnectDone: isOnlySigneDcAllowed true so setup single apn");
21603fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                setupDataOnConnectableApns(Phone.REASON_SINGLE_PDN_ARBITRATION);
2161449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            } else {
2162449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                if(DBG) log("onDisconnectDone: not retrying");
21633fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
2164c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2165a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2166a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mDisconnectPendingCount > 0)
2167a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mDisconnectPendingCount--;
2168a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2169a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mDisconnectPendingCount == 0) {
2170a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyDataDisconnectComplete();
2171a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
2172a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2173a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2174c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2175c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2176ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
2177ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Called when EVENT_DISCONNECT_DC_RETRYING is received.
2178ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
2179ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    @Override
2180ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    protected void onDisconnectDcRetrying(int connId, AsyncResult ar) {
2181ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // We could just do this in DC!!!
2182ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnContext apnContext = null;
2183ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
2184ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (ar.userObj instanceof ApnContext) {
2185ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext = (ApnContext) ar.userObj;
2186ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        } else {
2187ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            loge("onDisconnectDcRetrying: Invalid ar in onDisconnectDone, ignore");
2188ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            return;
2189ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
2190ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
2191ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setState(DctConstants.State.RETRYING);
2192ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if(DBG) log("onDisconnectDcRetrying: apnContext=" + apnContext);
2193ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
2194ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
2195ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
2196ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
2197c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2198cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2199cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onVoiceCallStarted() {
2200cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onVoiceCallStarted");
2201ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        mInVoiceCall = true;
2202cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnected() && ! mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
2203cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onVoiceCallStarted stop polling");
2204cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            stopNetStatPoll();
2205cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            stopDataStallAlarm();
2206cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
2207c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2208c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2209c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2210cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2211cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onVoiceCallEnded() {
2212cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onVoiceCallEnded");
2213ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        mInVoiceCall = false;
2214cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnected()) {
2215cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
2216cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                startNetStatPoll();
2217cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
2218cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
2219cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
2220cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // clean slate after call end.
2221cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                resetPollStats();
2222c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2223c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2224cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // reset reconnect timer
2225ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(Phone.REASON_VOICE_CALL_ENDED);
2226c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2227c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2228cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2229cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onCleanUpConnection(boolean tearDown, int apnId, String reason) {
2230cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onCleanUpConnection");
2231cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnIdToType(apnId));
2232cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
2233cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setReason(reason);
2234cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpConnection(tearDown, apnContext);
2235c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2236c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2237c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2238cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2239cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean isConnected() {
2240cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
2241ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getState() == DctConstants.State.CONNECTED) {
2242cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // At least one context is connected, return true
2243cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return true;
2244c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2245c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2246cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // There are not any contexts connected, return false
2247cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return false;
2248c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2249c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2250cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2251cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isDisconnected() {
2252cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
2253cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!apnContext.isDisconnected()) {
2254cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // At least one context was not disconnected return false
2255cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
2256cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2257c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2258cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // All contexts were disconnected so return true
2259cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
2260c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2261c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2262cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2263cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void notifyDataConnection(String reason) {
2264cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("notifyDataConnection: reason=" + reason);
2265cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
2266187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (mAttached.get() && apnContext.isReady()) {
2267187a39f896f88eb6c5e4306d9595546654825976Wink Saville                if (DBG) log("notifyDataConnection: type:" + apnContext.getApnType());
2268cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
2269cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.getApnType());
2270cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2271c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2272cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyOffApnsOfAvailability(reason);
2273c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2274c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2275c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
2276cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Based on the sim operator numeric, create a list for all possible
2277cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Data Connections and setup the preferredApn.
2278c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
2279cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void createAllApnList() {
2280ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mAllApnSettings = new ArrayList<ApnSetting>();
2281cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
2282cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String operator = (r != null) ? r.getOperatorNumeric() : "";
2283cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (operator != null) {
2284cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            String selection = "numeric = '" + operator + "'";
2285cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // query only enabled apn.
2286cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // carrier_enabled : 1 means enabled apn, 0 disabled apn.
22879d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan            // selection += " and carrier_enabled = 1";
2288cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: selection=" + selection);
2289cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2290cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            Cursor cursor = mPhone.getContext().getContentResolver().query(
2291cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    Telephony.Carriers.CONTENT_URI, null, selection, null, null);
2292cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2293cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cursor != null) {
2294cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (cursor.getCount() > 0) {
2295ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    mAllApnSettings = createApnList(cursor);
2296cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2297cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cursor.close();
2298cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2299c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2300c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
230176f43316a5a6082d601bffd4b6898d0bd81e11fcram        addEmergencyApnSetting();
230276f43316a5a6082d601bffd4b6898d0bd81e11fcram
230329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        dedupeApnSettings();
230429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
2305ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings.isEmpty()) {
2306cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: No APN found for carrier: " + operator);
2307cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPreferredApn = null;
2308ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // TODO: What is the right behavior?
2309cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            //notifyNoData(DataConnection.FailCause.MISSING_UNKNOWN_APN);
2310c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
2311cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPreferredApn = getPreferredApn();
2312cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator)) {
2313cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn = null;
2314cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                setPreferredApn(-1);
2315cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2316cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: mPreferredApn=" + mPreferredApn);
2317c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2318ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("createAllApnList: X mAllApnSettings=" + mAllApnSettings);
23199d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan
23209d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        setDataProfilesAsNeeded();
2321c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2322c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
232329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    private void dedupeApnSettings() {
232429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        ArrayList<ApnSetting> resultApns = new ArrayList<ApnSetting>();
232529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
232629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        // coalesce APNs if they are similar enough to prevent
232729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        // us from bringing up two data calls with the same interface
232829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        int i = 0;
232929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        while (i < mAllApnSettings.size() - 1) {
233029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            ApnSetting first = mAllApnSettings.get(i);
233129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            ApnSetting second = null;
233229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            int j = i + 1;
233329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            while (j < mAllApnSettings.size()) {
233429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                second = mAllApnSettings.get(j);
233529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                if (apnsSimilar(first, second)) {
233629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    ApnSetting newApn = mergeApns(first, second);
233729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    mAllApnSettings.set(i, newApn);
233829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    first = newApn;
233929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    mAllApnSettings.remove(j);
234029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                } else {
234129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    j++;
234229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                }
234329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            }
234429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            i++;
234529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        }
234629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    }
234729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
2348d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe    //check whether the types of two APN same (even only one type of each APN is same)
2349d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe    private boolean apnTypeSameAny(ApnSetting first, ApnSetting second) {
2350d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe        if(VDBG) {
2351d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            StringBuilder apnType1 = new StringBuilder(first.apn + ": ");
2352d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            for(int index1 = 0; index1 < first.types.length; index1++) {
2353d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                apnType1.append(first.types[index1]);
2354d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                apnType1.append(",");
2355d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            }
2356d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe
2357d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            StringBuilder apnType2 = new StringBuilder(second.apn + ": ");
2358d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            for(int index1 = 0; index1 < second.types.length; index1++) {
2359d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                apnType2.append(second.types[index1]);
2360d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                apnType2.append(",");
2361d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            }
2362d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            log("APN1: is " + apnType1);
2363d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            log("APN2: is " + apnType2);
2364d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe        }
2365d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe
2366d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe        for(int index1 = 0; index1 < first.types.length; index1++) {
2367d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            for(int index2 = 0; index2 < second.types.length; index2++) {
2368d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                if(first.types[index1].equals(PhoneConstants.APN_TYPE_ALL) ||
2369d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                        second.types[index2].equals(PhoneConstants.APN_TYPE_ALL) ||
2370d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                        first.types[index1].equals(second.types[index2])) {
2371d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                    if(VDBG)log("apnTypeSameAny: return true");
2372d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                    return true;
2373d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                }
2374d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            }
2375d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe        }
2376d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe
2377d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe        if(VDBG)log("apnTypeSameAny: return false");
2378d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe        return false;
2379d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe    }
2380d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe
238129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    // Check if neither mention DUN and are substantially similar
238229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    private boolean apnsSimilar(ApnSetting first, ApnSetting second) {
238329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        return (first.canHandleType(PhoneConstants.APN_TYPE_DUN) == false &&
238429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                second.canHandleType(PhoneConstants.APN_TYPE_DUN) == false &&
238529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                Objects.equals(first.apn, second.apn) &&
2386d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                !apnTypeSameAny(first, second) &&
238761cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                xorEquals(first.proxy, second.proxy) &&
238861cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                xorEquals(first.port, second.port) &&
238929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                first.carrierEnabled == second.carrierEnabled &&
239029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                first.bearer == second.bearer &&
239129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                first.profileId == second.profileId &&
239229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                Objects.equals(first.mvnoType, second.mvnoType) &&
239329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                Objects.equals(first.mvnoMatchData, second.mvnoMatchData) &&
239429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                xorEquals(first.mmsc, second.mmsc) &&
239529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                xorEquals(first.mmsProxy, second.mmsProxy) &&
239629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                xorEquals(first.mmsPort, second.mmsPort));
239729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    }
239829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
239929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    // equal or one is not specified
240029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    private boolean xorEquals(String first, String second) {
240129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        return (Objects.equals(first, second) ||
240229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                TextUtils.isEmpty(first) ||
240329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                TextUtils.isEmpty(second));
240429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    }
240529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
240629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    private ApnSetting mergeApns(ApnSetting dest, ApnSetting src) {
240729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        ArrayList<String> resultTypes = new ArrayList<String>();
240829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        resultTypes.addAll(Arrays.asList(dest.types));
240929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        for (String srcType : src.types) {
241029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            if (resultTypes.contains(srcType) == false) resultTypes.add(srcType);
241129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        }
241229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        String mmsc = (TextUtils.isEmpty(dest.mmsc) ? src.mmsc : dest.mmsc);
241329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        String mmsProxy = (TextUtils.isEmpty(dest.mmsProxy) ? src.mmsProxy : dest.mmsProxy);
241429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        String mmsPort = (TextUtils.isEmpty(dest.mmsPort) ? src.mmsPort : dest.mmsPort);
241561cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String proxy = (TextUtils.isEmpty(dest.proxy) ? src.proxy : dest.proxy);
241661cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String port = (TextUtils.isEmpty(dest.port) ? src.port : dest.port);
241761cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String protocol = src.protocol.equals("IPV4V6") ? src.protocol : dest.protocol;
241861cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String roamingProtocol = src.roamingProtocol.equals("IPV4V6") ? src.roamingProtocol :
241961cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                dest.roamingProtocol;
242029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
242129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        return new ApnSetting(dest.id, dest.numeric, dest.carrier, dest.apn,
242261cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                proxy, port, mmsc, mmsProxy, mmsPort, dest.user, dest.password,
242361cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                dest.authType, resultTypes.toArray(new String[0]), protocol,
242461cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                roamingProtocol, dest.carrierEnabled, dest.bearer, dest.profileId,
242529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                (dest.modemCognitive || src.modemCognitive), dest.maxConns, dest.waitTime,
242629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                dest.maxConnsTime, dest.mtu, dest.mvnoType, dest.mvnoMatchData);
242729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    }
242829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
2429ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /** Return the DC AsyncChannel for the new data connection */
2430454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel createDataConnection() {
2431cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createDataConnection E");
2432cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2433cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int id = mUniqueIdGenerator.getAndIncrement();
2434ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        DataConnection conn = DataConnection.makeDataConnection(mPhone, id,
2435ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                                this, mDcTesterFailBringUpAll, mDcc);
2436cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mDataConnections.put(id, conn);
2437454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac = new DcAsyncChannel(conn, LOG_TAG);
2438cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int status = dcac.fullyConnectSync(mPhone.getContext(), this, conn.getHandler());
2439cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (status == AsyncChannel.STATUS_SUCCESSFUL) {
2440ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            mDataConnectionAcHashMap.put(dcac.getDataConnectionIdSync(), dcac);
2441c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
2442ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            loge("createDataConnection: Could not connect to dcac=" + dcac + " status=" + status);
2443c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2444cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2445cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createDataConnection() X id=" + id + " dc=" + conn);
2446ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        return dcac;
2447c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2448c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2449cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void destroyDataConnections() {
2450cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(mDataConnections != null) {
2451cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("destroyDataConnections: clear mDataConnectionList");
2452cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mDataConnections.clear();
2453cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2454cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("destroyDataConnections: mDataConnecitonList is empty, ignore");
2455c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2456c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2457c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2458c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
2459cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Build a list of APNs to be used to create PDP's.
2460c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
2461cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param requestedApnType
2462cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return waitingApns list to be used to create PDP
2463cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *          error when waitingApns.isEmpty()
2464c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
2465203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    private ArrayList<ApnSetting> buildWaitingApns(String requestedApnType, int radioTech) {
2466cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("buildWaitingApns: E requestedApnType=" + requestedApnType);
2467cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ArrayList<ApnSetting> apnList = new ArrayList<ApnSetting>();
2468cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2469cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (requestedApnType.equals(PhoneConstants.APN_TYPE_DUN)) {
2470cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ApnSetting dun = fetchDunApn();
2471cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dun != null) {
2472cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnList.add(dun);
2473cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: X added APN_TYPE_DUN apnList=" + apnList);
2474cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return apnList;
2475c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2476c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2477c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2478cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
2479cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String operator = (r != null) ? r.getOperatorNumeric() : "";
2480c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2481cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // This is a workaround for a bug (7305641) where we don't failover to other
2482cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // suitable APNs if our preferred APN fails.  On prepaid ATT sims we need to
2483cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // failover to a provisioning APN, but once we've used their default data
2484cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // connection we are locked to it for life.  This change allows ATT devices
2485cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // to say they don't want to use preferred at all.
2486cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean usePreferred = true;
2487cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        try {
2488cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            usePreferred = ! mPhone.getContext().getResources().getBoolean(com.android.
2489cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    internal.R.bool.config_dontPreferApn);
2490cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } catch (Resources.NotFoundException e) {
2491cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("buildWaitingApns: usePreferred NotFoundException set to true");
2492cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            usePreferred = true;
2493cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2494cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
2495cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("buildWaitingApns: usePreferred=" + usePreferred
249622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    + " canSetPreferApn=" + mCanSetPreferApn
2497cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " mPreferredApn=" + mPreferredApn
2498cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " operator=" + operator + " radioTech=" + radioTech
2499cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " IccRecords r=" + r);
2500cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2501c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
250222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (usePreferred && mCanSetPreferApn && mPreferredApn != null &&
2503cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn.canHandleType(requestedApnType)) {
2504cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
2505cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("buildWaitingApns: Preferred APN:" + operator + ":"
2506cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        + mPreferredApn.numeric + ":" + mPreferredApn);
2507cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2508cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPreferredApn.numeric.equals(operator)) {
2509cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (mPreferredApn.bearer == 0 || mPreferredApn.bearer == radioTech) {
2510cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnList.add(mPreferredApn);
2511cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
2512cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return apnList;
2513cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2514cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("buildWaitingApns: no preferred APN");
2515cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    setPreferredApn(-1);
2516cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mPreferredApn = null;
2517c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
2518cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
2519cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: no preferred APN");
2520cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                setPreferredApn(-1);
2521cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn = null;
2522c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2523c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2524ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings != null) {
2525ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (DBG) log("buildWaitingApns: mAllApnSettings=" + mAllApnSettings);
2526ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for (ApnSetting apn : mAllApnSettings) {
2527cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: apn=" + apn);
2528cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn.canHandleType(requestedApnType)) {
2529cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (apn.bearer == 0 || apn.bearer == radioTech) {
2530cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (DBG) log("buildWaitingApns: adding apn=" + apn.toString());
2531cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnList.add(apn);
2532c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else {
2533cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (DBG) {
2534cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            log("buildWaitingApns: bearer:" + apn.bearer + " != "
2535cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                    + "radioTech:" + radioTech);
2536cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
2537c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
2538cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2539cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
2540cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("buildWaitingApns: couldn't handle requesedApnType="
2541cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            + requestedApnType);
2542c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
2543c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2544c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2545cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2546ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            loge("mAllApnSettings is empty!");
2547c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2548cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("buildWaitingApns: X apnList=" + apnList);
2549cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return apnList;
2550c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2551c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2552cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private String apnListToString (ArrayList<ApnSetting> apns) {
2553cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        StringBuilder result = new StringBuilder();
2554cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (int i = 0, size = apns.size(); i < size; i++) {
2555cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result.append('[')
2556cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                  .append(apns.get(i).toString())
2557cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                  .append(']');
2558c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2559cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result.toString();
2560c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2561c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2562cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void setPreferredApn(int pos) {
256322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (!mCanSetPreferApn) {
2564cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("setPreferredApn: X !canSEtPreferApn");
2565cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
2566cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2567cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2568cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("setPreferredApn: delete");
2569cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ContentResolver resolver = mPhone.getContext().getContentResolver();
2570cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        resolver.delete(PREFERAPN_NO_UPDATE_URI, null, null);
2571cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2572cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (pos >= 0) {
2573cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("setPreferredApn: insert");
2574cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ContentValues values = new ContentValues();
2575cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            values.put(APN_ID, pos);
2576cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            resolver.insert(PREFERAPN_NO_UPDATE_URI, values);
2577cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2578cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2579cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2580cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ApnSetting getPreferredApn() {
2581ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings.isEmpty()) {
2582ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            log("getPreferredApn: X not found mAllApnSettings.isEmpty");
2583cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return null;
2584cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2585cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2586cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Cursor cursor = mPhone.getContext().getContentResolver().query(
2587cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                PREFERAPN_NO_UPDATE_URI, new String[] { "_id", "name", "apn" },
2588cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
2589cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2590cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor != null) {
259122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCanSetPreferApn = true;
2592cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
259322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCanSetPreferApn = false;
2594cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2595cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("getPreferredApn: mRequestedApnType=" + mRequestedApnType + " cursor=" + cursor
2596cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                + " cursor.count=" + ((cursor != null) ? cursor.getCount() : 0));
2597cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
259822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mCanSetPreferApn && cursor.getCount() > 0) {
2599cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            int pos;
2600cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cursor.moveToFirst();
2601cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            pos = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID));
2602ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for(ApnSetting p : mAllApnSettings) {
2603cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("getPreferredApn: apnSetting=" + p);
2604cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (p.id == pos && p.canHandleType(mRequestedApnType)) {
2605cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("getPreferredApn: X found apnSetting" + p);
2606cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    cursor.close();
2607cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return p;
2608cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2609cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
2610cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2611cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2612cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor != null) {
2613cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cursor.close();
2614cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2615cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2616cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("getPreferredApn: X not found");
2617cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
2618cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
2619cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2620cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2621cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void handleMessage (Message msg) {
2622cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("handleMessage msg=" + msg);
2623cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2624cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (!mPhone.mIsTheCurrentActivePhone || mIsDisposed) {
2625cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("handleMessage: Ignore GSM msgs since GSM phone is inactive");
2626cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
2627cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2628cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2629a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (!isActiveDataSubscription()) {
2630a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            loge("Ignore msgs since phone is not the current DDS");
2631a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return;
2632a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2633a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2634cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        switch (msg.what) {
2635cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_RECORDS_LOADED:
2636cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onRecordsLoaded();
2637cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2638cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2639cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_CONNECTION_DETACHED:
2640cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onDataConnectionDetached();
2641cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2642cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2643cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_CONNECTION_ATTACHED:
2644cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onDataConnectionAttached();
2645cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2646cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2647cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DO_RECOVERY:
2648cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                doRecovery();
2649cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2650cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2651cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_APN_CHANGED:
2652cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onApnChanged();
2653cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2654cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2655cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_PS_RESTRICT_ENABLED:
2656cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                /**
2657cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * We don't need to explicitly to tear down the PDP context
2658cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * when PS restricted is enabled. The base band will deactive
2659cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * PDP context and notify us with PDP_CONTEXT_CHANGED.
2660cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * But we should stop the network polling and prevent reset PDP.
2661cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 */
2662cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
2663cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                stopNetStatPoll();
2664cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                stopDataStallAlarm();
2665cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsPsRestricted = true;
2666cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
2667cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2668cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_PS_RESTRICT_DISABLED:
2669cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                /**
2670cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * When PS restrict is removed, we need setup PDP connection if
2671cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * PDP connection is down.
2672cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 */
2673cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_PS_RESTRICT_DISABLED " + mIsPsRestricted);
2674cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsPsRestricted  = false;
2675cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (isConnected()) {
2676cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    startNetStatPoll();
2677cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
2678cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2679cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // TODO: Should all PDN states be checked to fail?
2680ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    if (mState == DctConstants.State.FAILED) {
2681cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        cleanUpAllConnections(false, Phone.REASON_PS_RESTRICT_ENABLED);
2682cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mReregisterOnReconnectFailure = false;
2683cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
26843fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    ApnContext apnContext = mApnContexts.get(PhoneConstants.APN_TYPE_DEFAULT);
26853fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (apnContext != null) {
26863fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        apnContext.setReason(Phone.REASON_PS_RESTRICT_ENABLED);
26873fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        trySetupData(apnContext);
26883fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    } else {
26893fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        loge("**** Default ApnContext not found ****");
26903fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        if (Build.IS_DEBUGGABLE) {
26913fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                            throw new RuntimeException("Default ApnContext not found");
26923fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        }
26933fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    }
2694cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2695cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
2696ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
2697cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_TRY_SETUP_DATA:
2698cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (msg.obj instanceof ApnContext) {
2699cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    onTrySetupData((ApnContext)msg.obj);
2700cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else if (msg.obj instanceof String) {
2701cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    onTrySetupData((String)msg.obj);
2702cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2703cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    loge("EVENT_TRY_SETUP request w/o apnContext or String");
2704cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2705cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
2706cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2707cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_CLEAN_UP_CONNECTION:
2708cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                boolean tearDown = (msg.arg1 == 0) ? false : true;
2709cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_CLEAN_UP_CONNECTION tearDown=" + tearDown);
2710cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (msg.obj instanceof ApnContext) {
2711cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    cleanUpConnection(tearDown, (ApnContext)msg.obj);
2712cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2713ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    loge("EVENT_CLEAN_UP_CONNECTION request w/o apn context, call super");
2714ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    super.handleMessage(msg);
2715cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2716cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
2717a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE:
2718a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
2719a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                onSetInternalDataEnabled(enabled, (Message) msg.obj);
2720a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
2721a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2722a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS:
2723a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                Message mCause = obtainMessage(DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS, null);
2724a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if ((msg.obj != null) && (msg.obj instanceof String)) {
2725a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mCause.obj = msg.obj;
2726a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
2727a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                super.handleMessage(mCause);
2728a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
2729ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
2730220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville            case DctConstants.EVENT_DATA_RAT_CHANGED:
2731220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville                //May new Network allow setupData, so try it here
2732220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville                setupDataOnConnectableApns(Phone.REASON_NW_TYPE_CHANGED);
2733220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville                break;
2734220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville
27352b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            case DctConstants.CMD_CLEAR_PROVISIONING_SPINNER:
27362b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                // Check message sender intended to clear the current spinner.
27372b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                if (mProvisioningSpinner == msg.obj) {
27382b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner.dismiss();
27392b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner = null;
27402b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                }
27412b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                break;
27422b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen
2743cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            default:
2744cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // handle the message in the super class DataConnectionTracker
2745cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                super.handleMessage(msg);
2746cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2747cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2748cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
2749cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2750cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected int getApnProfileID(String apnType) {
2751cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IMS)) {
2752cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_IMS;
2753cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_FOTA)) {
2754cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_FOTA;
2755cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_CBS)) {
2756cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_CBS;
27571b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IA)) {
27581b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            return RILConstants.DATA_PROFILE_DEFAULT; // DEFAULT for now
275945df26444864daad60afdd4d121ab4043da3834bSungmin Choi        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_DUN)) {
276045df26444864daad60afdd4d121ab4043da3834bSungmin Choi            return RILConstants.DATA_PROFILE_TETHERED;
2761cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2762cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_DEFAULT;
2763cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2764cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2765cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2766cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private int getCellLocationId() {
2767cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int cid = -1;
2768cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        CellLocation loc = mPhone.getCellLocation();
2769cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2770cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (loc != null) {
2771cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (loc instanceof GsmCellLocation) {
2772cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cid = ((GsmCellLocation)loc).getCid();
2773cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else if (loc instanceof CdmaCellLocation) {
2774cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cid = ((CdmaCellLocation)loc).getBaseStationId();
2775cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
2776cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2777cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return cid;
2778cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
2779cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2780a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private IccRecords getUiccRecords(int appFamily) {
2781a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return mUiccController.getIccRecords(mPhone.getPhoneId(), appFamily);
2782a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2783a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2784a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2785cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2786cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onUpdateIcc() {
2787cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mUiccController == null ) {
2788cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            return;
2789cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2790cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2791a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        IccRecords newIccRecords = getUiccRecords(UiccController.APP_FAM_3GPP);
2792cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2793cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
2794cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (r != newIccRecords) {
2795cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (r != null) {
2796cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("Removing stale icc objects.");
2797cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                r.unregisterForRecordsLoaded(this);
2798cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIccRecords.set(null);
27999aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan            }
2800cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (newIccRecords != null) {
2801cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("New records found");
2802cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIccRecords.set(newIccRecords);
2803cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                newIccRecords.registerForRecordsLoaded(
2804cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        this, DctConstants.EVENT_RECORDS_LOADED, null);
28059aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan            }
28069aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan        }
2807cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
2808cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2809a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    // setAsCurrentDataConnectionTracker
2810a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void update() {
2811a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("update sub = " + mPhone.getSubId());
2812a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (isActiveDataSubscription()) {
2813a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("update(): Active DDS, register for all events now!");
2814a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            registerForAllEvents();
2815a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            onUpdateIcc();
2816a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2817a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mUserDataEnabled = Settings.Global.getInt(mPhone.getContext().getContentResolver(),
2818a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    Settings.Global.MOBILE_DATA, 1) == 1;
2819a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2820a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (mPhone instanceof CDMALTEPhone) {
2821a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ((CDMALTEPhone)mPhone).updateCurrentCarrierInProvider();
2822a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                supplyMessenger();
2823a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else if (mPhone instanceof GSMPhone) {
2824a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ((GSMPhone)mPhone).updateCurrentCarrierInProvider();
2825a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                supplyMessenger();
2826a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
2827a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("Phone object is not MultiSim. This should not hit!!!!");
2828a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
2829a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2830a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else {
2831a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            unregisterForAllEvents();
2832a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("update(): NOT the active DDS, unregister for all events!");
2833a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2834a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2835a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2836a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
2837a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void cleanUpAllConnections(String cause) {
2838a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cleanUpAllConnections(cause, null);
2839a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2840a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2841a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void updateRecords() {
2842a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (isActiveDataSubscription()) {
2843a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            onUpdateIcc();
2844a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2845a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2846a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2847a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void cleanUpAllConnections(String cause, Message disconnectAllCompleteMsg) {
2848a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("cleanUpAllConnections");
2849a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (disconnectAllCompleteMsg != null) {
2850a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mDisconnectAllCompleteMsgList.add(disconnectAllCompleteMsg);
2851a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2852a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2853a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Message msg = obtainMessage(DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS);
2854a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        msg.obj = cause;
2855a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sendMessage(msg);
2856a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2857a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2858a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void notifyDataDisconnectComplete() {
2859a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("notifyDataDisconnectComplete");
2860a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        for (Message m: mDisconnectAllCompleteMsgList) {
2861a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            m.sendToTarget();
2862a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2863a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mDisconnectAllCompleteMsgList.clear();
2864a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2865a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2866a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2867a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void notifyAllDataDisconnected() {
2868a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sEnableFailFastRefCounter = 0;
2869a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mFailFast = false;
2870a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.notifyRegistrants();
2871a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2872a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2873a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void registerForAllDataDisconnected(Handler h, int what, Object obj) {
2874a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.addUnique(h, what, obj);
2875a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2876a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (isDisconnected()) {
2877a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("notify All Data Disconnected");
2878a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
2879a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2880a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2881a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2882a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void unregisterForAllDataDisconnected(Handler h) {
2883a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.remove(h);
2884a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2885a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2886a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2887a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
2888a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void onSetInternalDataEnabled(boolean enable) {
2889a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        onSetInternalDataEnabled(enable, null);
2890a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2891a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2892a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void onSetInternalDataEnabled(boolean enabled, Message onCompleteMsg) {
2893a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean sendOnComplete = true;
2894a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2895a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        synchronized (mDataEnabledLock) {
2896a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mInternalDataEnabled = enabled;
2897a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (enabled) {
2898a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("onSetInternalDataEnabled: changed to enabled, try to setup data call");
2899a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                onTrySetupData(Phone.REASON_DATA_ENABLED);
2900a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
2901a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                sendOnComplete = false;
2902a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("onSetInternalDataEnabled: changed to disabled, cleanUpAllConnections");
2903a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                cleanUpAllConnections(null, onCompleteMsg);
2904a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
2905a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2906a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2907a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (sendOnComplete) {
2908a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (onCompleteMsg != null) {
2909a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                onCompleteMsg.sendToTarget();
2910a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
2911a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2912a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2913a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2914a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean setInternalDataEnabledFlag(boolean enable) {
2915a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG)
2916a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("setInternalDataEnabledFlag(" + enable + ")");
2917a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2918a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mInternalDataEnabled != enable) {
2919a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mInternalDataEnabled = enable;
2920a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2921a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return true;
2922a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2923a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2924a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
2925a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean setInternalDataEnabled(boolean enable) {
2926a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return setInternalDataEnabled(enable, null);
2927a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2928a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2929a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean setInternalDataEnabled(boolean enable, Message onCompleteMsg) {
2930a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG)
2931a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("setInternalDataEnabled(" + enable + ")");
2932a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2933a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Message msg = obtainMessage(DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE, onCompleteMsg);
2934a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        msg.arg1 = (enable ? DctConstants.ENABLED : DctConstants.DISABLED);
2935a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sendMessage(msg);
2936a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return true;
2937a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2938a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2939a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /** Returns true if this is current DDS. */
2940a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected boolean isActiveDataSubscription() {
2941a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // FIXME This should have code like
2942a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // return (mPhone.getSubId() == SubscriptionManager.getDefaultDataSubId());
2943a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return true;
2944a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2945a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2946a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void setDataAllowed(boolean enable, Message response) {
2947a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         mIsCleanupRequired = !enable;
2948a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         mPhone.mCi.setDataAllowed(enable, response);
2949a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         mInternalDataEnabled = enable;
2950a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2951a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2952cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2953cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void log(String s) {
2954a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Rlog.d(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s);
2955cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
2956cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2957cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2958cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void loge(String s) {
2959a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Rlog.e(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s);
2960cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
2961cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2962cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2963c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2964cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println("DataConnectionTracker extends:");
2965cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        super.dump(fd, pw, args);
2966cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mReregisterOnReconnectFailure=" + mReregisterOnReconnectFailure);
296722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" canSetPreferApn=" + mCanSetPreferApn);
2968cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mApnObserver=" + mApnObserver);
2969cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" getOverallState=" + getOverallState());
2970ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        pw.println(" mDataConnectionAsyncChannels=%s\n" + mDataConnectionAcHashMap);
2971187a39f896f88eb6c5e4306d9595546654825976Wink Saville        pw.println(" mAttached=" + mAttached.get());
2972c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2973a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2974a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
2975bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram    public String[] getPcscfAddress(String apnType) {
2976a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("getPcscfAddress()");
2977bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        ApnContext apnContext = null;
2978bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram
2979bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        if(apnType == null){
2980bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            log("apnType is null, return null");
2981bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            return null;
2982bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        }
2983a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2984bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_EMERGENCY)) {
2985bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            apnContext = mApnContexts.get(PhoneConstants.APN_TYPE_EMERGENCY);
2986bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IMS)) {
2987bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            apnContext = mApnContexts.get(PhoneConstants.APN_TYPE_IMS);
2988bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        } else {
2989bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            log("apnType is invalid, return null");
2990bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            return null;
2991bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        }
2992a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2993a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (apnContext == null) {
2994a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("apnContext is null, return null");
2995a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return null;
2996a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2997a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2998a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        DcAsyncChannel dcac = apnContext.getDcAc();
2999a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        String[] result = null;
3000a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3001a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (dcac != null) {
3002a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            result = dcac.getPcscfAddr();
3003a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3004a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            for (int i = 0; i < result.length; i++) {
3005a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("Pcscf[" + i + "]: " + result[i]);
3006a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
3007a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return result;
3008a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
3009a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return null;
3010a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
3011a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3012a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
3013a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void setImsRegistrationState(boolean registered) {
3014a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("setImsRegistrationState - mImsRegistrationState(before): "+ mImsRegistrationState
3015a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                + ", registered(current) : " + registered);
3016a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3017a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mPhone == null) return;
3018a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3019a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ServiceStateTracker sst = mPhone.getServiceStateTracker();
3020a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (sst == null) return;
3021a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3022a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sst.setImsRegistrationState(registered);
3023a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
302476f43316a5a6082d601bffd4b6898d0bd81e11fcram
302576f43316a5a6082d601bffd4b6898d0bd81e11fcram    /**
302676f43316a5a6082d601bffd4b6898d0bd81e11fcram     * Read APN configuration from Telephony.db for Emergency APN
302776f43316a5a6082d601bffd4b6898d0bd81e11fcram     * All opertors recognize the connection request for EPDN based on APN type
302876f43316a5a6082d601bffd4b6898d0bd81e11fcram     * PLMN name,APN name are not mandatory parameters
302976f43316a5a6082d601bffd4b6898d0bd81e11fcram     */
303076f43316a5a6082d601bffd4b6898d0bd81e11fcram    private void initEmergencyApnSetting() {
303176f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Operator Numeric is not available when sim records are not loaded.
303276f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Query Telephony.db with APN type as EPDN request does not
303376f43316a5a6082d601bffd4b6898d0bd81e11fcram        // require APN name, plmn and all operators support same APN config.
303476f43316a5a6082d601bffd4b6898d0bd81e11fcram        // DB will contain only one entry for Emergency APN
303576f43316a5a6082d601bffd4b6898d0bd81e11fcram        String selection = "type=\"emergency\"";
303676f43316a5a6082d601bffd4b6898d0bd81e11fcram        Cursor cursor = mPhone.getContext().getContentResolver().query(
303776f43316a5a6082d601bffd4b6898d0bd81e11fcram                Telephony.Carriers.CONTENT_URI, null, selection, null, null);
303876f43316a5a6082d601bffd4b6898d0bd81e11fcram
303976f43316a5a6082d601bffd4b6898d0bd81e11fcram        if (cursor != null) {
304076f43316a5a6082d601bffd4b6898d0bd81e11fcram            if (cursor.getCount() > 0) {
304176f43316a5a6082d601bffd4b6898d0bd81e11fcram                if (cursor.moveToFirst()) {
304276f43316a5a6082d601bffd4b6898d0bd81e11fcram                    mEmergencyApn = makeApnSetting(cursor);
304376f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
304476f43316a5a6082d601bffd4b6898d0bd81e11fcram            }
304576f43316a5a6082d601bffd4b6898d0bd81e11fcram            cursor.close();
304676f43316a5a6082d601bffd4b6898d0bd81e11fcram        }
304776f43316a5a6082d601bffd4b6898d0bd81e11fcram    }
304876f43316a5a6082d601bffd4b6898d0bd81e11fcram
304976f43316a5a6082d601bffd4b6898d0bd81e11fcram    /**
305076f43316a5a6082d601bffd4b6898d0bd81e11fcram     * Add the Emergency APN settings to APN settings list
305176f43316a5a6082d601bffd4b6898d0bd81e11fcram     */
305276f43316a5a6082d601bffd4b6898d0bd81e11fcram    private void addEmergencyApnSetting() {
305376f43316a5a6082d601bffd4b6898d0bd81e11fcram        if(mEmergencyApn != null) {
305476f43316a5a6082d601bffd4b6898d0bd81e11fcram            if(mAllApnSettings == null) {
305576f43316a5a6082d601bffd4b6898d0bd81e11fcram                mAllApnSettings = new ArrayList<ApnSetting>();
305676f43316a5a6082d601bffd4b6898d0bd81e11fcram            } else {
305776f43316a5a6082d601bffd4b6898d0bd81e11fcram                boolean hasEmergencyApn = false;
305876f43316a5a6082d601bffd4b6898d0bd81e11fcram                for (ApnSetting apn : mAllApnSettings) {
305976f43316a5a6082d601bffd4b6898d0bd81e11fcram                    if (ArrayUtils.contains(apn.types, PhoneConstants.APN_TYPE_EMERGENCY)) {
306076f43316a5a6082d601bffd4b6898d0bd81e11fcram                        hasEmergencyApn = true;
306176f43316a5a6082d601bffd4b6898d0bd81e11fcram                        break;
306276f43316a5a6082d601bffd4b6898d0bd81e11fcram                    }
306376f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
306476f43316a5a6082d601bffd4b6898d0bd81e11fcram
306576f43316a5a6082d601bffd4b6898d0bd81e11fcram                if(hasEmergencyApn == false) {
306676f43316a5a6082d601bffd4b6898d0bd81e11fcram                    mAllApnSettings.add(mEmergencyApn);
306776f43316a5a6082d601bffd4b6898d0bd81e11fcram                } else {
306876f43316a5a6082d601bffd4b6898d0bd81e11fcram                    log("addEmergencyApnSetting - E-APN setting is already present");
306976f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
307076f43316a5a6082d601bffd4b6898d0bd81e11fcram            }
307176f43316a5a6082d601bffd4b6898d0bd81e11fcram        }
307276f43316a5a6082d601bffd4b6898d0bd81e11fcram    }
3073c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville}
3074