DcTracker.java revision fd555a178c05e409917f22745743ed59402208e6
1c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/*
2c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Copyright (C) 2006 The Android Open Source Project
3c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
4c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Licensed under the Apache License, Version 2.0 (the "License");
5c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * you may not use this file except in compliance with the License.
6c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * You may obtain a copy of the License at
7c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
8c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *      http://www.apache.org/licenses/LICENSE-2.0
9c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
10c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Unless required by applicable law or agreed to in writing, software
11c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * distributed under the License is distributed on an "AS IS" BASIS,
12c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * See the License for the specific language governing permissions and
14c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * limitations under the License.
15c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
16c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
174918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savillepackage com.android.internal.telephony.dataconnection;
18c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
19cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kallaimport android.app.AlarmManager;
20c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.app.PendingIntent;
21c9b81a0c05128694c617fcdd67e73821895822feWink Savilleimport android.content.ActivityNotFoundException;
22c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.ContentResolver;
23cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.content.ContentValues;
24c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Context;
25c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Intent;
26c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.IntentFilter;
27cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.content.res.Resources;
28c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.database.ContentObserver;
29cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.database.Cursor;
30cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.ConnectivityManager;
31c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.net.LinkProperties;
3296cce86cf08e37e0f09ed5057b1196e26b302743Robert Greenwaltimport android.net.NetworkCapabilities;
33cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.NetworkConfig;
3462c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwaltimport android.net.NetworkFactory;
3562c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwaltimport android.net.NetworkRequest;
36cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.NetworkUtils;
379c180aedfc9f0d20525c0128487d3500e6c0a715Jason Monkimport android.net.ProxyInfo;
38cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.Uri;
39c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.AsyncResult;
403fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwaltimport android.os.Build;
4162c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwaltimport android.os.Looper;
42c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Message;
431f2a2323572b2f3ab18234726cc1b048c670fbabRobert Greenwaltimport android.os.Messenger;
44c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemClock;
45c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemProperties;
46c9b81a0c05128694c617fcdd67e73821895822feWink Savilleimport android.os.UserHandle;
47c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.provider.Settings;
48cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.provider.Telephony;
49cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.CellLocation;
50c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.telephony.ServiceState;
51c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.telephony.TelephonyManager;
52cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.cdma.CdmaCellLocation;
53cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.gsm.GsmCellLocation;
54c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.text.TextUtils;
55cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kallaimport android.util.EventLog;
5699c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Savilleimport android.telephony.Rlog;
57c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
584918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savilleimport com.android.internal.telephony.Phone;
594918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savilleimport com.android.internal.telephony.PhoneBase;
60cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.DctConstants;
61cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.EventLogTags;
62c9b81a0c05128694c617fcdd67e73821895822feWink Savilleimport com.android.internal.telephony.TelephonyIntents;
63cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.gsm.GSMPhone;
644918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savilleimport com.android.internal.telephony.PhoneConstants;
65cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.RILConstants;
66d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccRecords;
67bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenkaimport com.android.internal.telephony.uicc.UiccController;
68c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.util.AsyncChannel;
69c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
70c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.io.FileDescriptor;
71c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.io.PrintWriter;
72c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.ArrayList;
73187a39f896f88eb6c5e4306d9595546654825976Wink Savilleimport java.util.concurrent.atomic.AtomicBoolean;
74c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.HashMap;
75c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
76c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/**
77c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * {@hide}
78c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
79454b1dfd508844b42eb775e4ab2359be74d3672bWink Savillepublic final class DcTracker extends DcTrackerBase {
80cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected final String LOG_TAG = "DCT";
81c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
82b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla    /**
83cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Handles changes to the APN db.
84b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla     */
85cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private class ApnChangeObserver extends ContentObserver {
86cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public ApnChangeObserver () {
87cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            super(mDataConnectionTracker);
88cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
89c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
90cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
91cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public void onChange(boolean selfChange) {
92cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            sendMessage(obtainMessage(DctConstants.EVENT_APN_CHANGED));
93cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
94cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
95c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
96cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Instance Variables
97c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
98cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean mReregisterOnReconnectFailure = false;
99c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
100c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
101cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Constants
102c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
103ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    // Used by puppetmaster/*/radio_stress.py
104ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private static final String PUPPET_MASTER_RADIO_STRESS_TEST = "gsm.defaultpdpcontext.active";
105c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
106ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private static final int POLL_PDP_MILLIS = 5 * 1000;
107c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
108cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final Uri PREFERAPN_NO_UPDATE_URI =
109cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        Uri.parse("content://telephony/carriers/preferapn_no_update");
110cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final String APN_ID = "apn_id";
111cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
112ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private boolean mCanSetPreferApn = false;
113c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
114187a39f896f88eb6c5e4306d9595546654825976Wink Saville    private AtomicBoolean mAttached = new AtomicBoolean(false);
115187a39f896f88eb6c5e4306d9595546654825976Wink Saville
116cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** Watches for changes to the APN db. */
117cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ApnChangeObserver mApnObserver;
118cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1194dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt    /** Used to send us NetworkRequests from ConnectivityService.  Remeber it so we can
1204dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt     * unregister on dispose. */
1214dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt    private Messenger mNetworkFactoryMessenger;
12262c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt    private NetworkFactory mNetworkFactory;
12362c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt    private NetworkCapabilities mNetworkFilter;
1244dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt
125cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Constructor
126454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    public DcTracker(PhoneBase p) {
127cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        super(p);
128cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("GsmDCT.constructor");
12922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        p.mCi.registerForAvailable (this, DctConstants.EVENT_RADIO_AVAILABLE, null);
13022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        p.mCi.registerForOffOrNotAvailable(this, DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE,
131cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                null);
132b077af12dfe0abfcdd51ce5c9852940b89567e99Yashdev Singh
133cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        p.getCallTracker().registerForVoiceCallEnded (this, DctConstants.EVENT_VOICE_CALL_ENDED,
134cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                null);
135cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        p.getCallTracker().registerForVoiceCallStarted (this, DctConstants.EVENT_VOICE_CALL_STARTED,
136cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                null);
137cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        p.getServiceStateTracker().registerForDataConnectionAttached(this,
138cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null);
139cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        p.getServiceStateTracker().registerForDataConnectionDetached(this,
140cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                DctConstants.EVENT_DATA_CONNECTION_DETACHED, null);
141cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        p.getServiceStateTracker().registerForRoamingOn(this, DctConstants.EVENT_ROAMING_ON, null);
142cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        p.getServiceStateTracker().registerForRoamingOff(this, DctConstants.EVENT_ROAMING_OFF,
143cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                null);
144cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        p.getServiceStateTracker().registerForPsRestrictedEnabled(this,
145cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                DctConstants.EVENT_PS_RESTRICT_ENABLED, null);
146cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        p.getServiceStateTracker().registerForPsRestrictedDisabled(this,
147cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                DctConstants.EVENT_PS_RESTRICT_DISABLED, null);
148cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
149cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mDataConnectionTracker = this;
150cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
151cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mApnObserver = new ApnChangeObserver();
152cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        p.getContext().getContentResolver().registerContentObserver(
153cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                Telephony.Carriers.CONTENT_URI, true, mApnObserver);
154cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1551f2a2323572b2f3ab18234726cc1b048c670fbabRobert Greenwalt        ConnectivityManager cm = (ConnectivityManager)p.getContext().getSystemService(
1561f2a2323572b2f3ab18234726cc1b048c670fbabRobert Greenwalt                Context.CONNECTIVITY_SERVICE);
15762c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt
15862c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        mNetworkFilter = new NetworkCapabilities();
15962c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        mNetworkFilter.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
160fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
161fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL);
162fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
163fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_FOTA);
164fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
165fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_CBS);
166fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_IA);
167fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_RCS);
168fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_XCAP);
169fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS);
170fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
171fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
17262c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt
17362c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        mNetworkFactory = new TelephonyNetworkFactory(this.getLooper(), p.getContext(),
17462c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt                "TelephonyNetworkFactory", mNetworkFilter);
17562c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        mNetworkFactory.setScoreFilter(50);
17662c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        mNetworkFactoryMessenger = new Messenger(mNetworkFactory);
17762c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        cm.registerNetworkFactory(mNetworkFactoryMessenger, "Telephony");
178cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
179c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
180cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
181cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void dispose() {
182cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("GsmDCT.dispose");
1834dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt
1844dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt        ConnectivityManager cm = (ConnectivityManager)mPhone.getContext().getSystemService(
1854dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt                Context.CONNECTIVITY_SERVICE);
1864dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt        cm.unregisterNetworkFactory(mNetworkFactoryMessenger);
1874dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt        mNetworkFactoryMessenger = null;
1884dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt
189cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, null);
190cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
191cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        super.dispose();
192cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
193cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        //Unregister for all events
19422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.unregisterForAvailable(this);
19522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.unregisterForOffOrNotAvailable(this);
196cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
197cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (r != null) { r.unregisterForRecordsLoaded(this);}
19822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.unregisterForDataNetworkStateChanged(this);
199cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getCallTracker().unregisterForVoiceCallEnded(this);
200cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getCallTracker().unregisterForVoiceCallStarted(this);
201cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().unregisterForDataConnectionAttached(this);
202cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().unregisterForDataConnectionDetached(this);
203cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().unregisterForRoamingOn(this);
204cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().unregisterForRoamingOff(this);
205cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().unregisterForPsRestrictedEnabled(this);
206cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().unregisterForPsRestrictedDisabled(this);
207cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
20822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.getContext().getContentResolver().unregisterContentObserver(mApnObserver);
209cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mApnContexts.clear();
2103fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        mPrioritySortedApnContexts.clear();
211cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
212cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        destroyDataConnections();
213cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
214cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
21562c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt    private class TelephonyNetworkFactory extends NetworkFactory {
21662c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        public TelephonyNetworkFactory(Looper l, Context c, String TAG, NetworkCapabilities nc) {
21762c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            super(l, c, TAG, nc);
21862c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        }
21962c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt
22062c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        @Override
22162c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        protected void needNetworkFor(NetworkRequest networkRequest, int score) {
22262c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            // figure out the apn type and enable it
22362c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            if (DBG) log("Cellular needs Network for " + networkRequest);
22462c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            ApnContext apnContext = apnContextForNetworkRequest(networkRequest);
22562c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            if (apnContext != null) apnContext.incRefCount();
22662c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        }
22762c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt
22862c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        @Override
22962c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        protected void releaseNetworkFor(NetworkRequest networkRequest) {
23062c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            if (DBG) log("Cellular releasing Network for " + networkRequest);
23162c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            ApnContext apnContext = apnContextForNetworkRequest(networkRequest);
23262c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            if (apnContext != null) apnContext.decRefCount();
23362c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        }
23462c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt    }
23562c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt
23662c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt    private ApnContext apnContextForNetworkRequest(NetworkRequest nr) {
23762c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        NetworkCapabilities nc = nr.networkCapabilities;
23862c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        // for now, ignore the bandwidth stuff
239fd555a178c05e409917f22745743ed59402208e6Robert Greenwalt        if (nc.getTransportTypes().length > 0 &&
24062c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt                nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == false) {
24162c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            return null;
24262c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        }
24362c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt
24462c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        // in the near term just do 1-1 matches.
24562c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        // TODO - actually try to match the set of capabilities
24662c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        int type = -1;
24762c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        String name = null;
24862c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt
24962c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        boolean error = false;
25062c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
25162c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            if (name != null) error = true;
25262c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            name = PhoneConstants.APN_TYPE_DEFAULT;
25362c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            type = ConnectivityManager.TYPE_MOBILE;
25462c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        }
25562c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
25662c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            if (name != null) error = true;
25762c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            name = PhoneConstants.APN_TYPE_MMS;
25862c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            type = ConnectivityManager.TYPE_MOBILE_MMS;
25962c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        }
26062c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
26162c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            if (name != null) error = true;
26262c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            name = PhoneConstants.APN_TYPE_SUPL;
26362c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            type = ConnectivityManager.TYPE_MOBILE_SUPL;
26462c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        }
26562c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
26662c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            if (name != null) error = true;
26762c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            name = PhoneConstants.APN_TYPE_DUN;
26862c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            type = ConnectivityManager.TYPE_MOBILE_DUN;
26962c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        }
27062c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
27162c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            if (name != null) error = true;
27262c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            name = PhoneConstants.APN_TYPE_FOTA;
27362c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            type = ConnectivityManager.TYPE_MOBILE_FOTA;
27462c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        }
27562c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
27662c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            if (name != null) error = true;
27762c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            name = PhoneConstants.APN_TYPE_IMS;
27862c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            type = ConnectivityManager.TYPE_MOBILE_IMS;
27962c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        }
28062c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
28162c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            if (name != null) error = true;
28262c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            name = PhoneConstants.APN_TYPE_CBS;
28362c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            type = ConnectivityManager.TYPE_MOBILE_CBS;
28462c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        }
28562c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IA)) {
28662c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            if (name != null) error = true;
28762c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            name = PhoneConstants.APN_TYPE_IA;
28862c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            type = ConnectivityManager.TYPE_MOBILE_IA;
28962c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        }
29062c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_RCS)) {
29162c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            if (name != null) error = true;
29262c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            name = null;
29362c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            loge("RCS APN type not yet supported");
29462c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        }
29562c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_XCAP)) {
29662c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            if (name != null) error = true;
29762c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            name = null;
29862c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            loge("XCAP APN type not yet supported");
29962c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        }
30062c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)) {
30162c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            if (name != null) error = true;
30262c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            name = null;
30362c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            loge("EIMS APN type not yet supported");
30462c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        }
30562c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        if (error) {
30662c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            loge("Multiple apn types specified in request - result is unspecified!");
30762c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        }
30862c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        if (type == -1 || name == null) {
30962c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            loge("Unsupported NetworkRequest in Telephony: " + nr);
31062c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            return null;
31162c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        }
31262c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        ApnContext apnContext = mApnContexts.get(name);
31362c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        if (apnContext == null) {
31462c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            if (DBG) log("Attempting to create new ApnContext for " + type);
31562c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            String[] networkConfigStrings = mPhone.getContext().getResources().getStringArray(
31662c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt                    com.android.internal.R.array.networkAttributes);
31762c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            for (String networkConfigString : networkConfigStrings) {
31862c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt                NetworkConfig networkConfig = new NetworkConfig(networkConfigString);
31962c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt                if (networkConfig.type == type) {
32062c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt                    apnContext = addApnContext(name, networkConfig);
32162c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt                    break;
32262c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt                }
32362c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            }
32462c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            if (apnContext == null) {
32562c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt                loge("Unable to create new ApnContext for " + type);
32662c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt            }
32762c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        }
32862c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        return apnContext;
32962c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt    }
33062c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt
331cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
332cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isApnTypeActive(String type) {
333cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(type);
334cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) return false;
335cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
336ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        return (apnContext.getDcAc() != null);
337cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
338cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
339cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
340cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isDataPossible(String apnType) {
341cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
342cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
343cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
344cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
345cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean apnContextIsEnabled = apnContext.isEnabled();
346cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        DctConstants.State apnContextState = apnContext.getState();
347cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean apnTypePossible = !(apnContextIsEnabled &&
348cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                (apnContextState == DctConstants.State.FAILED));
349cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean dataAllowed = isDataAllowed();
350cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean possible = dataAllowed && apnTypePossible;
351cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
352ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (VDBG) {
353cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log(String.format("isDataPossible(%s): possible=%b isDataAllowed=%b " +
354cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    "apnTypePossible=%b apnContextisEnabled=%b apnContextState()=%s",
355cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnType, possible, dataAllowed, apnTypePossible,
356cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContextIsEnabled, apnContextState));
357cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
358cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return possible;
359cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
360cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
361cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
362cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void finalize() {
363cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(DBG) log("finalize");
364cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
365cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3664a9b3afeb2ec4d573eca335a3706392ecf9f281eWink Saville    private ApnContext addApnContext(String type, NetworkConfig networkConfig) {
36762c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt        ApnContext apnContext = new ApnContext(mPhone.getContext(), type, LOG_TAG, networkConfig,
36862c954a7a7c4199956c127fcb575ed9114d44491Robert Greenwalt                this);
369cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mApnContexts.put(type, apnContext);
3703fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        mPrioritySortedApnContexts.add(apnContext);
371bce3d2575122929bb27ec8a37d56e96da39a3ca2Robert Greenwalt        return apnContext;
372cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
373c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
374cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
375cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public LinkProperties getLinkProperties(String apnType) {
376cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
377cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
378454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = apnContext.getDcAc();
379cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac != null) {
380cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("return link properites for " + apnType);
381cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return dcac.getLinkPropertiesSync();
382cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
383cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
384cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("return new LinkProperties");
385cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return new LinkProperties();
386cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
387cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
388f3ab6ab303e1da929ce26b7c5d63565bff136221Robert Greenwalt    @Override
389f3ab6ab303e1da929ce26b7c5d63565bff136221Robert Greenwalt    public NetworkCapabilities getNetworkCapabilities(String apnType) {
390f3ab6ab303e1da929ce26b7c5d63565bff136221Robert Greenwalt        ApnContext apnContext = mApnContexts.get(apnType);
391f3ab6ab303e1da929ce26b7c5d63565bff136221Robert Greenwalt        if (apnContext!=null) {
392f3ab6ab303e1da929ce26b7c5d63565bff136221Robert Greenwalt            DcAsyncChannel dataConnectionAc = apnContext.getDcAc();
393f3ab6ab303e1da929ce26b7c5d63565bff136221Robert Greenwalt            if (dataConnectionAc != null) {
394f3ab6ab303e1da929ce26b7c5d63565bff136221Robert Greenwalt                if (DBG) {
395f3ab6ab303e1da929ce26b7c5d63565bff136221Robert Greenwalt                    log("get active pdp is not null, return NetworkCapabilities for " + apnType);
396f3ab6ab303e1da929ce26b7c5d63565bff136221Robert Greenwalt                }
397f3ab6ab303e1da929ce26b7c5d63565bff136221Robert Greenwalt                return dataConnectionAc.getNetworkCapabilitiesSync();
398f3ab6ab303e1da929ce26b7c5d63565bff136221Robert Greenwalt            }
399f3ab6ab303e1da929ce26b7c5d63565bff136221Robert Greenwalt        }
400f3ab6ab303e1da929ce26b7c5d63565bff136221Robert Greenwalt        if (DBG) log("return new NetworkCapabilities");
401f3ab6ab303e1da929ce26b7c5d63565bff136221Robert Greenwalt        return new NetworkCapabilities();
402f3ab6ab303e1da929ce26b7c5d63565bff136221Robert Greenwalt    }
403cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
404cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
405cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return all active apn types
406cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public String[] getActiveApnTypes() {
407cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("get all active apn types");
408cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ArrayList<String> result = new ArrayList<String>();
409cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
410cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
411187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (mAttached.get() && apnContext.isReady()) {
412cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                result.add(apnContext.getApnType());
413cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
414cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
415c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
416cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result.toArray(new String[0]);
417cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
418cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
419cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
420cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return active apn of specific apn type
421cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public String getActiveApnString(String apnType) {
422ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (VDBG) log( "get active apn string for type:" + apnType);
423cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
424cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
425cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ApnSetting apnSetting = apnContext.getApnSetting();
426cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnSetting != null) {
427cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return apnSetting.apn;
428cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
429cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
430cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
431cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
432cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
433cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
434cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isApnTypeEnabled(String apnType) {
435cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
436cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
437cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
438cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
439cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return apnContext.isEnabled();
440cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
441cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
442cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
443cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void setState(DctConstants.State s) {
444cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setState should not be used in GSM" + s);
445cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
446cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
447cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return state of specific apn type
448cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
449cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public DctConstants.State getState(String apnType) {
450cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
451cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
452cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return apnContext.getState();
453c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
454cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return DctConstants.State.FAILED;
455cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
456c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
457c9b81a0c05128694c617fcdd67e73821895822feWink Saville    // Return if apn type is a provisioning apn.
458c9b81a0c05128694c617fcdd67e73821895822feWink Saville    @Override
459c9b81a0c05128694c617fcdd67e73821895822feWink Saville    protected boolean isProvisioningApn(String apnType) {
460c9b81a0c05128694c617fcdd67e73821895822feWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
461c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (apnContext != null) {
462c9b81a0c05128694c617fcdd67e73821895822feWink Saville            return apnContext.isProvisioningApn();
463c9b81a0c05128694c617fcdd67e73821895822feWink Saville        }
464c9b81a0c05128694c617fcdd67e73821895822feWink Saville        return false;
465c9b81a0c05128694c617fcdd67e73821895822feWink Saville    }
466c9b81a0c05128694c617fcdd67e73821895822feWink Saville
467cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return state of overall
468cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
469cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public DctConstants.State getOverallState() {
470cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isConnecting = false;
471cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isFailed = true; // All enabled Apns should be FAILED.
472cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isAnyEnabled = false;
473cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
474cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
475cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.isEnabled()) {
476cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                isAnyEnabled = true;
477cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                switch (apnContext.getState()) {
478cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case CONNECTED:
479cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case DISCONNECTING:
480cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("overall state is CONNECTED");
481cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return DctConstants.State.CONNECTED;
482ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                case RETRYING:
483cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case CONNECTING:
484cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isConnecting = true;
485cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isFailed = false;
486cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
487cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case IDLE:
488cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case SCANNING:
489cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isFailed = false;
490cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
491cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                default:
492cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isAnyEnabled = true;
493cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
494cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
495cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
496c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
497c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
498cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (!isAnyEnabled) { // Nothing enabled. return IDLE.
499cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log( "overall state is IDLE");
500cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.IDLE;
501c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
502c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
503cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnecting) {
504cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log( "overall state is CONNECTING");
505cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.CONNECTING;
506cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (!isFailed) {
507cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log( "overall state is IDLE");
508cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.IDLE;
509cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
510cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log( "overall state is FAILED");
511cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.FAILED;
512c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
513c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
514c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
515c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
516cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Ensure that we are connected to an APN of the specified type.
517c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
518cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param apnType the APN type
519cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return Success is indicated by {@code PhoneConstants.APN_ALREADY_ACTIVE} or
520cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *         {@code PhoneConstants.APN_REQUEST_STARTED}. In the latter case, a
521cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *         broadcast will be sent by the ConnectivityManager when a
522cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *         connection to the APN has been established.
523c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
524cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
525cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public synchronized int enableApnType(String apnType) {
526cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
527cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null || !isApnTypeAvailable(apnType)) {
528cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("enableApnType: " + apnType + " is type not available");
529cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return PhoneConstants.APN_TYPE_NOT_AVAILABLE;
530c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
531c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
532cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // If already active, return
533cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("enableApnType: " + apnType + " mState(" + apnContext.getState() + ")");
534c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
535cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext.getState() == DctConstants.State.CONNECTED) {
536cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("enableApnType: return APN_ALREADY_ACTIVE");
537cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return PhoneConstants.APN_ALREADY_ACTIVE;
538c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
539cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        setEnabled(apnTypeToId(apnType), true);
540cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
541cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("enableApnType: new apn request for type " + apnType +
542cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    " return APN_REQUEST_STARTED");
543cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
544cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return PhoneConstants.APN_REQUEST_STARTED;
545cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
546c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
547cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
548cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public synchronized int disableApnType(String type) {
549cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("disableApnType:" + type);
550cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(type);
551cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
552cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
553cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            setEnabled(apnTypeToId(type), false);
554cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.getState() != DctConstants.State.IDLE && apnContext.getState()
555cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    != DctConstants.State.FAILED) {
556cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("diableApnType: return APN_REQUEST_STARTED");
557cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return PhoneConstants.APN_REQUEST_STARTED;
558cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
559cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("disableApnType: return APN_ALREADY_INACTIVE");
560cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return PhoneConstants.APN_ALREADY_INACTIVE;
561cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
562cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
563cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
564cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
565cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("disableApnType: no apn context was found, return APN_REQUEST_FAILED");
566cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
567cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return PhoneConstants.APN_REQUEST_FAILED;
568c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
569cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
570c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
571cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
572cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean isApnTypeAvailable(String type) {
573cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (type.equals(PhoneConstants.APN_TYPE_DUN) && fetchDunApn() != null) {
574cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return true;
575c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
576c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
577ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings != null) {
578ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for (ApnSetting apn : mAllApnSettings) {
579cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn.canHandleType(type)) {
580cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return true;
581cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
582cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
583c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
584cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return false;
585c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
586c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
587cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
588cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Report on whether data connectivity is enabled for any APN.
589cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return {@code false} if data connectivity has been explicitly disabled,
590cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * {@code true} otherwise.
591cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
592cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
593cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean getAnyDataEnabled() {
594cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        synchronized (mDataEnabledLock) {
595cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!(mInternalDataEnabled && mUserDataEnabled && sPolicyDataEnabled)) return false;
596cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            for (ApnContext apnContext : mApnContexts.values()) {
597cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Make sure we don't have a context that is going down
598cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // and is explicitly disabled.
599cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (isDataAllowed(apnContext)) {
600cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return true;
601cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
602cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
603cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
604c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
605c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
606c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
607cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean isDataAllowed(ApnContext apnContext) {
608cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return apnContext.isReady() && isDataAllowed();
609c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
610c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
611cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //****** Called from ServiceStateTracker
612c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
613cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Invoked when ServiceStateTracker observes a transition from GPRS
614cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * attach to detach.
615c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
616cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onDataConnectionDetached() {
617cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        /*
618cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * We presently believe it is unnecessary to tear down the PDP context
619cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * when GPRS detaches, but we should stop the network polling.
620cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         */
621cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log ("onDataConnectionDetached: stop polling and notify detached");
622cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopNetStatPoll();
623cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopDataStallAlarm();
624cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyDataConnection(Phone.REASON_DATA_DETACHED);
625187a39f896f88eb6c5e4306d9595546654825976Wink Saville        mAttached.set(false);
626cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
627c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
628cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onDataConnectionAttached() {
629cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onDataConnectionAttached");
6307ab10e4710bdb54c6d9a5ee01cd443a42a2689f5Sungmin Choi        mAttached.set(true);
631cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getOverallState() == DctConstants.State.CONNECTED) {
632cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onDataConnectionAttached: start polling notify attached");
633cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            startNetStatPoll();
634cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
635cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_DATA_ATTACHED);
636cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
637cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // update APN availability so that APN can be enabled.
638cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_DATA_ATTACHED);
639cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
640cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mAutoAttachOnCreation = true;
641ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(Phone.REASON_DATA_ATTACHED);
642cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
643c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
644cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
645cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean isDataAllowed() {
646cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        final boolean internalDataEnabled;
647cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        synchronized (mDataEnabledLock) {
648cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            internalDataEnabled = mInternalDataEnabled;
649cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
650cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
6519894b3fb2f35e21d9cfd45f233ed093589e14c26sy.yun        boolean attachedState = mAttached.get();
652cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
653cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
654cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean recordsLoaded = (r != null) ? r.getRecordsLoaded() : false;
655cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
656cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean allowed =
6579894b3fb2f35e21d9cfd45f233ed093589e14c26sy.yun                    (attachedState || mAutoAttachOnCreation) &&
658cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    recordsLoaded &&
659cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    (mPhone.getState() == PhoneConstants.State.IDLE ||
660cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                     mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) &&
661cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    internalDataEnabled &&
662cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    (!mPhone.getServiceState().getRoaming() || getDataOnRoamingEnabled()) &&
663cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    !mIsPsRestricted &&
664cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    desiredPowerState;
665cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (!allowed && DBG) {
666cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            String reason = "";
6679894b3fb2f35e21d9cfd45f233ed093589e14c26sy.yun            if (!(attachedState || mAutoAttachOnCreation)) {
6689894b3fb2f35e21d9cfd45f233ed093589e14c26sy.yun                reason += " - Attached= " + attachedState;
669cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
670cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!recordsLoaded) reason += " - SIM not loaded";
671cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPhone.getState() != PhoneConstants.State.IDLE &&
672cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
673cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                reason += " - PhoneState= " + mPhone.getState();
674cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                reason += " - Concurrent voice and data not allowed";
675cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
676cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!internalDataEnabled) reason += " - mInternalDataEnabled= false";
677cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPhone.getServiceState().getRoaming() && !getDataOnRoamingEnabled()) {
678cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                reason += " - Roaming and data roaming not enabled";
679cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
680cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mIsPsRestricted) reason += " - mIsPsRestricted= true";
681cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!desiredPowerState) reason += " - desiredPowerState= false";
682cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("isDataAllowed: not allowed due to" + reason);
683c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
684cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return allowed;
685cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
686c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
687ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void setupDataOnConnectableApns(String reason) {
6883fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (DBG) log("setupDataOnConnectableApns: " + reason);
6893fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
6903fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        for (ApnContext apnContext : mPrioritySortedApnContexts) {
6913fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (DBG) log("setupDataOnConnectableApns: apnContext " + apnContext);
692cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.getState() == DctConstants.State.FAILED) {
693cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setState(DctConstants.State.IDLE);
694cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
695ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.isConnectable()) {
696ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                log("setupDataOnConnectableApns: isConnectable() call trySetupData");
697ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setReason(reason);
698ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                trySetupData(apnContext);
699cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
700cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
701c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
702c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
703cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean trySetupData(ApnContext apnContext) {
704cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
705cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("trySetupData for type:" + apnContext.getApnType() +
706cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    " due to " + apnContext.getReason() + " apnContext=" + apnContext);
707cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("trySetupData with mIsPsRestricted=" + mIsPsRestricted);
708cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
709cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
710cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
711cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
712cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
713cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setState(DctConstants.State.CONNECTED);
714cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
715cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
716cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("trySetupData: X We're on the simulator; assuming connected retValue=true");
717cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return true;
718cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
719cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
720cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
721cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
7229894b3fb2f35e21d9cfd45f233ed093589e14c26sy.yun        if (apnContext.isConnectable() &&
723cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                isDataAllowed(apnContext) && getAnyDataEnabled() && !isEmergency()) {
724ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getState() == DctConstants.State.FAILED) {
725ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) log("trySetupData: make a FAILED ApnContext IDLE so its reusable");
726ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setState(DctConstants.State.IDLE);
727ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
728203e588e3c42a81aa8a56f595119c181a63b12caWink Saville            int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
729cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.getState() == DctConstants.State.IDLE) {
730203e588e3c42a81aa8a56f595119c181a63b12caWink Saville
731203e588e3c42a81aa8a56f595119c181a63b12caWink Saville                ArrayList<ApnSetting> waitingApns = buildWaitingApns(apnContext.getApnType(),
732203e588e3c42a81aa8a56f595119c181a63b12caWink Saville                        radioTech);
733cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (waitingApns.isEmpty()) {
734ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    notifyNoData(DcFailCause.MISSING_UNKNOWN_APN, apnContext);
735cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    notifyOffApnsOfAvailability(apnContext.getReason());
736cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("trySetupData: X No APN found retValue=false");
737cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return false;
738cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
739cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setWaitingApns(waitingApns);
740cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) {
741ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        log ("trySetupData: Create from mAllApnSettings : "
742ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                    + apnListToString(mAllApnSettings));
743cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
744cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
745cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
746cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
747cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
748cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("trySetupData: call setupData, waitingApns : "
749cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        + apnListToString(apnContext.getWaitingApns()));
750cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
751203e588e3c42a81aa8a56f595119c181a63b12caWink Saville            boolean retValue = setupData(apnContext, radioTech);
752cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(apnContext.getReason());
753cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
754cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("trySetupData: X retValue=" + retValue);
755cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return retValue;
756cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
757cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
758ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    && apnContext.isConnectable()) {
759cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
760ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
761cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(apnContext.getReason());
762cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log ("trySetupData: X apnContext not 'ready' retValue=false");
763cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
764cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
765c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
766c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
767cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
768cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Disabled apn's still need avail/unavail notificiations - send them out
769cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void notifyOffApnsOfAvailability(String reason) {
770cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
771187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (!mAttached.get() || !apnContext.isReady()) {
772ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) log("notifyOffApnOfAvailability type:" + apnContext.getApnType());
773cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
774cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                            apnContext.getApnType(),
775cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                            PhoneConstants.DataState.DISCONNECTED);
776cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
777ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) {
778187a39f896f88eb6c5e4306d9595546654825976Wink Saville                    log("notifyOffApnsOfAvailability skipped apn due to attached && isReady " +
779cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            apnContext.toString());
780cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
781c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
782c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
783c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
784c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
785cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
786cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * If tearDown is true, this only tears down a CONNECTED session. Presently,
787cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * there is no mechanism for abandoning an CONNECTING session,
788cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * but would likely involve cancelling pending async requests or
789cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * setting a flag or new state to ignore them when they came in
790cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param tearDown true if the underlying DataConnection should be
791cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * disconnected.
792cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param reason reason for the clean up.
7933fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return boolean - true if we did cleanup any connections, false if they
7943fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     *                   were already all disconnected.
795cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
7963fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    protected boolean cleanUpAllConnections(boolean tearDown, String reason) {
797cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("cleanUpAllConnections: tearDown=" + tearDown + " reason=" + reason);
7983fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        boolean didDisconnect = false;
799cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
800cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
8013fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (apnContext.isDisconnected() == false) didDisconnect = true;
8023fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            // TODO - only do cleanup if not disconnected
803cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setReason(reason);
804cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpConnection(tearDown, apnContext);
805c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
806cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
807cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopNetStatPoll();
808cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopDataStallAlarm();
809cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
810cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: Do we need mRequestedApnType?
811cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
8123fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return didDisconnect;
813cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
814cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
815cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
816cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Cleanup all connections.
817cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
818cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * TODO: Cleanup only a specified connection passed as a parameter.
819cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *       Also, make sure when you clean up a conn, if it is last apply
820cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *       logic as though it is cleanupAllConnections
821cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
822cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param cause for the clean up.
823cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
824cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
825cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
826cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onCleanUpAllConnections(String cause) {
827cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, cause);
828cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
829cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
830cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void cleanUpConnection(boolean tearDown, ApnContext apnContext) {
831cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
832cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
833cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("cleanUpConnection: apn context is null");
834cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
835cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
836cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
837454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac = apnContext.getDcAc();
838cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
839cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("cleanUpConnection: E tearDown=" + tearDown + " reason=" + apnContext.getReason() +
840cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    " apnContext=" + apnContext);
841cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
842cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (tearDown) {
843cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.isDisconnected()) {
844cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // The request is tearDown and but ApnContext is not connected.
845cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // If apnContext is not enabled anymore, break the linkage to the DCAC/DC.
846cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setState(DctConstants.State.IDLE);
847cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (!apnContext.isReady()) {
8484750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                    if (dcac != null) {
8494750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                        dcac.tearDown(apnContext, "", null);
8504750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                    }
851cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setDataConnectionAc(null);
852cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
853cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
854cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Connection is still there. Try to clean up.
855cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (dcac != null) {
856cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (apnContext.getState() != DctConstants.State.DISCONNECTING) {
857cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        boolean disconnectAll = false;
858cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (PhoneConstants.APN_TYPE_DUN.equals(apnContext.getApnType())) {
859cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            ApnSetting dunSetting = fetchDunApn();
860cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            if (dunSetting != null &&
861cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                    dunSetting.equals(apnContext.getApnSetting())) {
862cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                if (DBG) log("tearing down dedicated DUN connection");
863cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // we need to tear it down - we brought it up just for dun and
864cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // other people are camped on it and now dun is done.  We need
865cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // to stop using it and let the normal apn list get used to find
866cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // connections for the remaining desired connections
867cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                disconnectAll = true;
868cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            }
869cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
870cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (DBG) {
871cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            log("cleanUpConnection: tearing down" + (disconnectAll ? " all" :""));
872cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
873cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        Message msg = obtainMessage(DctConstants.EVENT_DISCONNECT_DONE, apnContext);
874cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (disconnectAll) {
875ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            apnContext.getDcAc().tearDownAll(apnContext.getReason(), msg);
876cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        } else {
877ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            apnContext.getDcAc()
878cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                .tearDown(apnContext, apnContext.getReason(), msg);
879cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
880cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.setState(DctConstants.State.DISCONNECTING);
881cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
882cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
883cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // apn is connected but no reference to dcac.
884cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // Should not be happen, but reset the state in case.
885cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setState(DctConstants.State.IDLE);
886cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mPhone.notifyDataConnection(apnContext.getReason(),
887cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                                apnContext.getApnType());
888cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
889cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
890cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
891cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // force clean up the data connection.
892ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac != null) dcac.reqReset();
893cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setState(DctConstants.State.IDLE);
894cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
895cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setDataConnectionAc(null);
896cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
897cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
898ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // Make sure reconnection alarm is cleaned up if there is no ApnContext
899cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // associated to the connection.
900cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (dcac != null) {
901ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            cancelReconnectAlarm(apnContext);
902c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
903cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
904cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("cleanUpConnection: X tearDown=" + tearDown + " reason=" + apnContext.getReason() +
905ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    " apnContext=" + apnContext + " dcac=" + apnContext.getDcAc());
906cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
907cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
908c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
909cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
910ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Cancels the alarm associated with apnContext.
911cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
912ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * @param apnContext on which the alarm should be stopped.
913cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
914ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void cancelReconnectAlarm(ApnContext apnContext) {
915ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnContext == null) return;
916cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
917ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        PendingIntent intent = apnContext.getReconnectIntent();
918cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
919cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (intent != null) {
920cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                AlarmManager am =
921cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
922cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                am.cancel(intent);
923ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setReconnectIntent(null);
924cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
925c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
926c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
927cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
928cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param types comma delimited list of APN types
929cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return array of APN types
930cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
931cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private String[] parseTypes(String types) {
932c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String[] result;
933cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // If unset, set to DEFAULT.
934cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (types == null || types.equals("")) {
935c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            result = new String[1];
936cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result[0] = PhoneConstants.APN_TYPE_ALL;
937cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
938cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result = types.split(",");
939c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
940c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
941c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
942c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
943fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi   private boolean imsiMatches(String imsiDB, String imsiSIM) {
944fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        // Note: imsiDB value has digit number or 'x' character for seperating USIM information
945fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        // for MVNO operator. And then digit number is matched at same order and 'x' character
946fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        // could replace by any digit number.
947fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        // ex) if imsiDB inserted '310260x10xxxxxx' for GG Operator,
948fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        //     that means first 6 digits, 8th and 9th digit
949fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        //     should be set in USIM for GG Operator.
950fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        int len = imsiDB.length();
951fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        int idxCompare = 0;
952fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
953fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        if (len <= 0) return false;
954fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        if (len > imsiSIM.length()) return false;
955fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
956fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        for (int idx=0; idx<len; idx++) {
957fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            char c = imsiDB.charAt(idx);
958fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            if ((c == 'x') || (c == 'X') || (c == imsiSIM.charAt(idx))) {
959fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                continue;
960fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            } else {
961fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                return false;
962fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            }
963fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        }
964fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        return true;
965fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    }
966fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
967fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    private boolean mvnoMatches(IccRecords r, String mvno_type, String mvno_match_data) {
968fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        if (mvno_type.equalsIgnoreCase("spn")) {
969fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            if ((r.getServiceProviderName() != null) &&
970fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    r.getServiceProviderName().equalsIgnoreCase(mvno_match_data)) {
971fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                return true;
972fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            }
973fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        } else if (mvno_type.equalsIgnoreCase("imsi")) {
974fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            String imsiSIM = r.getIMSI();
975fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            if ((imsiSIM != null) && imsiMatches(mvno_match_data, imsiSIM)) {
976fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                return true;
977fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            }
978fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        } else if (mvno_type.equalsIgnoreCase("gid")) {
979fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            String gid1 = r.getGid1();
98059a71354e0169c7877ffd56d476ddd65ecf5a88dRobert Greenwalt            int mvno_match_data_length = mvno_match_data.length();
98159a71354e0169c7877ffd56d476ddd65ecf5a88dRobert Greenwalt            if ((gid1 != null) && (gid1.length() >= mvno_match_data_length) &&
98259a71354e0169c7877ffd56d476ddd65ecf5a88dRobert Greenwalt                    gid1.substring(0, mvno_match_data_length).equalsIgnoreCase(mvno_match_data)) {
983fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                return true;
984fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            }
985fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        }
986fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        return false;
987fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    }
988fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
989fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    private ApnSetting makeApnSetting(Cursor cursor) {
990fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        String[] types = parseTypes(
991fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.TYPE)));
992fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        ApnSetting apn = new ApnSetting(
993fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID)),
994fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NUMERIC)),
995fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NAME)),
996fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN)),
997fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
998fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
999fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY))),
1000fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PORT)),
1001fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1002fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1003fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC))),
1004fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1005fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1006fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY))),
1007fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPORT)),
1008fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)),
1009fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)),
1010fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.AUTH_TYPE)),
1011fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                types,
1012fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROTOCOL)),
1013fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(
1014fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        Telephony.Carriers.ROAMING_PROTOCOL)),
1015fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(
1016fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        Telephony.Carriers.CARRIER_ENABLED)) == 1,
1017fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.BEARER)));
1018fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        return apn;
1019fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    }
1020fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
1021cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ArrayList<ApnSetting> createApnList(Cursor cursor) {
1022cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ArrayList<ApnSetting> result = new ArrayList<ApnSetting>();
1023fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        IccRecords r = mIccRecords.get();
1024fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
1025cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor.moveToFirst()) {
1026fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            String mvnoType = null;
1027fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi            String mvnoMatchData = null;
1028cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            do {
1029fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                String cursorMvnoType = cursor.getString(
1030fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_TYPE));
1031fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                String cursorMvnoMatchData = cursor.getString(
1032fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_MATCH_DATA));
1033fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                if (mvnoType != null) {
1034fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    if (mvnoType.equals(cursorMvnoType) &&
1035fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                            mvnoMatchData.equals(cursorMvnoMatchData)) {
1036fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        result.add(makeApnSetting(cursor));
1037fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    }
1038fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                } else {
1039fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    // no mvno match yet
1040fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    if (mvnoMatches(r, cursorMvnoType, cursorMvnoMatchData)) {
1041fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        // first match - toss out non-mvno data
1042fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        result.clear();
1043fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        mvnoType = cursorMvnoType;
1044fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        mvnoMatchData = cursorMvnoMatchData;
1045fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        result.add(makeApnSetting(cursor));
1046fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    } else {
1047fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        // add only non-mvno data
1048fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        if (cursorMvnoType.equals("")) {
1049fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                            result.add(makeApnSetting(cursor));
1050fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        }
1051fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    }
1052fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                }
1053cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } while (cursor.moveToNext());
1054cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1055cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createApnList: X result=" + result);
1056c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
1057c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1058c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1059454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private boolean dataConnectionNotInUse(DcAsyncChannel dcac) {
1060ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("dataConnectionNotInUse: check if dcac is inuse dcac=" + dcac);
1061cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1062ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getDcAc() == dcac) {
1063cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("dataConnectionNotInUse: in use by apnContext=" + apnContext);
1064cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
1065cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1066cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1067cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: Fix retry handling so free DataConnections have empty apnlists.
1068cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Probably move retry handling into DataConnections and reduce complexity
1069cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // of DCT.
1070cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("dataConnectionNotInUse: tearDownAll");
1071ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        dcac.tearDownAll("No connection", null);
1072cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("dataConnectionNotInUse: not in use return true");
1073cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
1074cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1075cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1076454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel findFreeDataConnection() {
1077454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
1078cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac.isInactiveSync() && dataConnectionNotInUse(dcac)) {
1079cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
1080cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("findFreeDataConnection: found free DataConnection=" +
1081ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        " dcac=" + dcac);
1082cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1083ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                return dcac;
1084cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1085cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1086cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("findFreeDataConnection: NO free DataConnection");
1087cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
1088cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1089cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1090203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    private boolean setupData(ApnContext apnContext, int radioTech) {
1091cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setupData: apnContext=" + apnContext);
1092ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnSetting apnSetting;
1093454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac;
1094cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1095cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int profileId = getApnProfileID(apnContext.getApnType());
1096ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnSetting = apnContext.getNextWaitingApn();
1097ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnSetting == null) {
1098cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("setupData: return for no apn found!");
1099cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
1100cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1101cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1102ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        dcac = checkForCompatibleConnectedApnContext(apnContext);
1103ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (dcac != null) {
1104ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // Get the dcacApnSetting for the connection we want to share.
1105ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            ApnSetting dcacApnSetting = dcac.getApnSettingSync();
1106ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcacApnSetting != null) {
1107ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                // Setting is good, so use it.
1108ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnSetting = dcacApnSetting;
1109ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1110ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
1111ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (dcac == null) {
11123fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (isOnlySingleDcAllowed(radioTech)) {
11133fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (isHigherPriorityApnContextActive(apnContext)) {
11143fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (DBG) {
11153fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        log("setupData: Higher priority ApnContext active.  Ignoring call");
11163fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    }
11173fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    return false;
11183fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                }
11193fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
11203fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // Only lower priority calls left.  Disconnect them all in this single PDP case
11213fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // so that we can bring up the requested higher priority call (once we receive
11223fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // repsonse for deactivate request for the calls we are about to disconnect
11233fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (cleanUpAllConnections(true, Phone.REASON_SINGLE_PDN_ARBITRATION)) {
11243fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // If any call actually requested to be disconnected, means we can't
11253fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // bring up this connection yet as we need to wait for those data calls
11263fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // to be disconnected.
11273fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (DBG) log("setupData: Some calls are disconnecting first.  Wait and retry");
11283fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    return false;
11293fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                }
11303fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
11313fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // No other calls are active, so proceed
11323fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (DBG) log("setupData: Single pdp. Continue setting up data call.");
11333fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
11343fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
1135ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            dcac = findFreeDataConnection();
1136cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1137ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac == null) {
1138ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                dcac = createDataConnection();
1139cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1140cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1141ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac == null) {
1142ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) log("setupData: No free DataConnection and couldn't create one, WEIRD");
1143cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
1144cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1145cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1146ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("setupData: dcac=" + dcac + " apnSetting=" + apnSetting);
1147cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1148cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setDataConnectionAc(dcac);
1149ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setApnSetting(apnSetting);
1150cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setState(DctConstants.State.CONNECTING);
1151cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1152cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1153cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Message msg = obtainMessage();
1154cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        msg.what = DctConstants.EVENT_DATA_SETUP_COMPLETE;
1155cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        msg.obj = apnContext;
1156203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        dcac.bringUp(apnContext, getInitialMaxRetry(), profileId, radioTech, msg);
1157cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1158cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setupData: initing!");
1159cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
1160cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1161cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1162c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1163cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Handles changes to the APN database.
1164c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1165cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onApnChanged() {
1166cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        DctConstants.State overallState = getOverallState();
1167cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isDisconnected = (overallState == DctConstants.State.IDLE ||
1168cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                overallState == DctConstants.State.FAILED);
1169cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1170cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone instanceof GSMPhone) {
1171cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // The "current" may no longer be valid.  MMS depends on this to send properly. TBD
1172cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ((GSMPhone)mPhone).updateCurrentCarrierInProvider();
1173cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1174cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1175cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: It'd be nice to only do this if the changed entrie(s)
1176cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // match the current operator.
1177cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onApnChanged: createAllApnList and cleanUpAllConnections");
1178cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        createAllApnList();
11795d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi        setInitialAttachApn();
1180cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(!isDisconnected, Phone.REASON_APN_CHANGED);
1181cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isDisconnected) {
1182ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_APN_CHANGED);
1183c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1184c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1185c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1186c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1187cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param cid Connection id provided from RIL.
1188cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return DataConnectionAc associated with specified cid.
1189c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1190454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel findDataConnectionAcByCid(int cid) {
1191454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
1192cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac.getCidSync() == cid) {
1193cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return dcac;
1194cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1195c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1196cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
1197c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1198c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1199cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // TODO: For multiple Active APNs not exactly sure how to do this.
1200c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
1201cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void gotoIdleAndNotifyDataConnection(String reason) {
1202cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("gotoIdleAndNotifyDataConnection: reason=" + reason);
1203cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyDataConnection(reason);
1204cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mActiveApn = null;
1205cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1206cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
12073fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    /**
12083fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * "Active" here means ApnContext isEnabled() and not in FAILED state
12093fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @param apnContext to compare with
12103fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return true if higher priority active apn found
12113fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     */
12123fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean isHigherPriorityApnContextActive(ApnContext apnContext) {
12133fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        for (ApnContext otherContext : mPrioritySortedApnContexts) {
12143fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (apnContext.getApnType().equalsIgnoreCase(otherContext.getApnType())) return false;
12153fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (otherContext.isEnabled() && otherContext.getState() != DctConstants.State.FAILED) {
12163fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                return true;
12173fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
12183fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
12193fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return false;
12203fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    }
12213fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
12223fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    /**
12233fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * Reports if we support multiple connections or not.
12243fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * This is a combination of factors, based on carrier and RAT.
12253fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @param rilRadioTech the RIL Radio Tech currently in use
12263fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return true if only single DataConnection is allowed
12273fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     */
12283fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean isOnlySingleDcAllowed(int rilRadioTech) {
12293fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        int[] singleDcRats = mPhone.getContext().getResources().getIntArray(
12303fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                com.android.internal.R.array.config_onlySingleDcAllowed);
12313fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        boolean onlySingleDcAllowed = false;
12323fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (Build.IS_DEBUGGABLE &&
12333fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                SystemProperties.getBoolean("persist.telephony.test.singleDc", false)) {
12343fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            onlySingleDcAllowed = true;
12353fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
12363fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (singleDcRats != null) {
12373fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            for (int i=0; i < singleDcRats.length && onlySingleDcAllowed == false; i++) {
12383fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (rilRadioTech == singleDcRats[i]) onlySingleDcAllowed = true;
12393fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
12403fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
12413fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
12423fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (DBG) log("isOnlySingleDcAllowed(" + rilRadioTech + "): " + onlySingleDcAllowed);
12433fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return onlySingleDcAllowed;
12443fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    }
12453fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
1246cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1247cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void restartRadio() {
1248cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("restartRadio: ************TURN OFF RADIO**************");
1249cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, Phone.REASON_RADIO_TURNED_OFF);
1250cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().powerOffRadioSafely(this);
1251cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        /* Note: no need to call setRadioPower(true).  Assuming the desired
1252cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * radio power state is still ON (as tracked by ServiceStateTracker),
1253cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * ServiceStateTracker will call setRadioPower when it receives the
1254cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * RADIO_STATE_CHANGED notification for the power off.  And if the
1255cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * desired power state has changed in the interim, we don't want to
1256cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * override it with an unconditional power on.
1257cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         */
1258cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1259cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int reset = Integer.parseInt(SystemProperties.get("net.ppp.reset-by-timeout", "0"));
1260cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        SystemProperties.set("net.ppp.reset-by-timeout", String.valueOf(reset+1));
1261cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1262cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1263cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1264cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Return true if data connection need to be setup after disconnected due to
1265cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * reason.
1266cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1267cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param reason the reason why data is disconnected
1268cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return true if try setup data connection is need for this reason
1269cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
12703fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean retryAfterDisconnected(ApnContext apnContext) {
1271cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean retry = true;
12723fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        String reason = apnContext.getReason();
1273cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
12743fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) ||
12753fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())
12763fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                 && isHigherPriorityApnContextActive(apnContext))) {
1277cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            retry = false;
1278cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1279cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return retry;
1280cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1281cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1282cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void startAlarmForReconnect(int delay, ApnContext apnContext) {
1283cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String apnType = apnContext.getApnType();
128474672e8ee972f12406b72551261b4cc7e0651933Wink Saville
128574672e8ee972f12406b72551261b4cc7e0651933Wink Saville        Intent intent = new Intent(INTENT_RECONNECT_ALARM + "." + apnType);
128674672e8ee972f12406b72551261b4cc7e0651933Wink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, apnContext.getReason());
1287cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, apnType);
1288cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
128974672e8ee972f12406b72551261b4cc7e0651933Wink Saville        if (DBG) {
129074672e8ee972f12406b72551261b4cc7e0651933Wink Saville            log("startAlarmForReconnect: delay=" + delay + " action=" + intent.getAction()
129174672e8ee972f12406b72551261b4cc7e0651933Wink Saville                    + " apn=" + apnContext);
129274672e8ee972f12406b72551261b4cc7e0651933Wink Saville        }
129374672e8ee972f12406b72551261b4cc7e0651933Wink Saville
1294ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        PendingIntent alarmIntent = PendingIntent.getBroadcast (mPhone.getContext(), 0,
1295ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        intent, PendingIntent.FLAG_UPDATE_CURRENT);
1296ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setReconnectIntent(alarmIntent);
1297ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1298ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                SystemClock.elapsedRealtime() + delay, alarmIntent);
1299ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
1300cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1301ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void startAlarmForRestartTrySetup(int delay, ApnContext apnContext) {
1302ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        String apnType = apnContext.getApnType();
130374672e8ee972f12406b72551261b4cc7e0651933Wink Saville        Intent intent = new Intent(INTENT_RESTART_TRYSETUP_ALARM + "." + apnType);
1304ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        intent.putExtra(INTENT_RESTART_TRYSETUP_ALARM_EXTRA_TYPE, apnType);
1305cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
130674672e8ee972f12406b72551261b4cc7e0651933Wink Saville        if (DBG) {
130774672e8ee972f12406b72551261b4cc7e0651933Wink Saville            log("startAlarmForRestartTrySetup: delay=" + delay + " action=" + intent.getAction()
130874672e8ee972f12406b72551261b4cc7e0651933Wink Saville                    + " apn=" + apnContext);
130974672e8ee972f12406b72551261b4cc7e0651933Wink Saville        }
1310cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        PendingIntent alarmIntent = PendingIntent.getBroadcast (mPhone.getContext(), 0,
1311cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                        intent, PendingIntent.FLAG_UPDATE_CURRENT);
1312ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setReconnectIntent(alarmIntent);
1313ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1314cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                SystemClock.elapsedRealtime() + delay, alarmIntent);
1315cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1316cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1317ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void notifyNoData(DcFailCause lastFailCauseCode,
1318cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                              ApnContext apnContext) {
1319cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log( "notifyNoData: type=" + apnContext.getApnType());
1320cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (lastFailCauseCode.isPermanentFail()
1321cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            && (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT))) {
1322cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
1323cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1324cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1325cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1326cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onRecordsLoaded() {
1327cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onRecordsLoaded: createAllApnList");
1328cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        createAllApnList();
13295d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi        setInitialAttachApn();
133022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPhone.mCi.getRadioState().isOn()) {
1331cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRecordsLoaded: notifying data availability");
1332cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_SIM_LOADED);
1333cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1334ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(Phone.REASON_SIM_LOADED);
1335cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1336cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1337cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1338cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onSetDependencyMet(String apnType, boolean met) {
1339cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // don't allow users to tweak hipri to work around default dependency not met
1340cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_HIPRI.equals(apnType)) return;
1341cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1342cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1343cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
1344cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onSetDependencyMet: ApnContext not found in onSetDependencyMet(" +
1345cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnType + ", " + met + ")");
1346cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
1347cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1348cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        applyNewState(apnContext, apnContext.isEnabled(), met);
1349cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_DEFAULT.equals(apnType)) {
1350cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // tie actions on default to similar actions on HIPRI regarding dependencyMet
1351cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext = mApnContexts.get(PhoneConstants.APN_TYPE_HIPRI);
1352cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext != null) applyNewState(apnContext, apnContext.isEnabled(), met);
1353cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1354cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1355c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1356cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void applyNewState(ApnContext apnContext, boolean enabled, boolean met) {
1357cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean cleanup = false;
1358cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean trySetup = false;
1359cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
1360cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("applyNewState(" + apnContext.getApnType() + ", " + enabled +
1361cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    "(" + apnContext.isEnabled() + "), " + met + "(" +
1362cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.getDependencyMet() +"))");
1363cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1364cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext.isReady()) {
13652428693913ae731d4ace3414429f5e91af24ea36Wink Saville            if (enabled && met) {
13662428693913ae731d4ace3414429f5e91af24ea36Wink Saville                DctConstants.State state = apnContext.getState();
13672428693913ae731d4ace3414429f5e91af24ea36Wink Saville                switch(state) {
13682428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case CONNECTING:
13692428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case SCANNING:
13702428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case CONNECTED:
13712428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case DISCONNECTING:
13722428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // We're "READY" and active so just return
13732428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        if (DBG) log("applyNewState: 'ready' so return");
13742428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        return;
13752428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case IDLE:
13762428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // fall through: this is unexpected but if it happens cleanup and try setup
13772428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case FAILED:
13782428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case RETRYING: {
13792428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // We're "READY" but not active so disconnect (cleanup = true) and
13802428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // connect (trySetup = true) to be sure we retry the connection.
13812428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        trySetup = true;
13822428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        apnContext.setReason(Phone.REASON_DATA_ENABLED);
13832428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        break;
13842428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    }
13852428693913ae731d4ace3414429f5e91af24ea36Wink Saville                }
13862428693913ae731d4ace3414429f5e91af24ea36Wink Saville            } else if (!enabled) {
1387cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setReason(Phone.REASON_DATA_DISABLED);
1388cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1389cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_UNMET);
1390cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1391cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanup = true;
1392cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1393cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (enabled && met) {
1394cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apnContext.isEnabled()) {
1395cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_MET);
1396cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1397cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setReason(Phone.REASON_DATA_ENABLED);
1398c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1399cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apnContext.getState() == DctConstants.State.FAILED) {
1400cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setState(DctConstants.State.IDLE);
1401cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1402cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                trySetup = true;
1403cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1404cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1405cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setEnabled(enabled);
1406cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setDependencyMet(met);
1407cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cleanup) cleanUpConnection(true, apnContext);
1408cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (trySetup) trySetupData(apnContext);
1409cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1410c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1411454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel checkForCompatibleConnectedApnContext(ApnContext apnContext) {
1412cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String apnType = apnContext.getApnType();
1413cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnSetting dunSetting = null;
1414cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1415cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_DUN.equals(apnType)) {
1416cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            dunSetting = fetchDunApn();
1417cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1418ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) {
1419ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            log("checkForCompatibleConnectedApnContext: apnContext=" + apnContext );
1420ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
1421cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1422454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel potentialDcac = null;
1423ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnContext potentialApnCtx = null;
1424ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        for (ApnContext curApnCtx : mApnContexts.values()) {
1425454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel curDcac = curApnCtx.getDcAc();
1426ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (curDcac != null) {
1427ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                ApnSetting apnSetting = curApnCtx.getApnSetting();
1428cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (dunSetting != null) {
1429cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (dunSetting.equals(apnSetting)) {
1430ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        switch (curApnCtx.getState()) {
1431cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            case CONNECTED:
1432cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                if (DBG) {
1433ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                    log("checkForCompatibleConnectedApnContext:"
1434ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                            + " found dun conn=" + curDcac
1435ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                            + " curApnCtx=" + curApnCtx);
1436cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                }
1437ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                return curDcac;
1438ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            case RETRYING:
1439cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            case CONNECTING:
1440ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                potentialDcac = curDcac;
1441ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                potentialApnCtx = curApnCtx;
1442cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            default:
1443cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // Not connected, potential unchanged
1444cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                break;
1445cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
1446cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1447cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else if (apnSetting != null && apnSetting.canHandleType(apnType)) {
1448ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    switch (curApnCtx.getState()) {
1449cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        case CONNECTED:
1450cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            if (DBG) {
1451ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                log("checkForCompatibleConnectedApnContext:"
1452ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        + " found canHandle conn=" + curDcac
1453ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        + " curApnCtx=" + curApnCtx);
1454cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            }
1455ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            return curDcac;
1456ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        case RETRYING:
1457cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        case CONNECTING:
1458ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            potentialDcac = curDcac;
1459ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            potentialApnCtx = curApnCtx;
1460cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        default:
1461cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            // Not connected, potential unchanged
1462cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            break;
1463cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1464cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1465ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            } else {
1466ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) {
1467ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    log("checkForCompatibleConnectedApnContext: not conn curApnCtx=" + curApnCtx);
1468ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                }
1469cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1470cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1471ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (potentialDcac != null) {
1472cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
1473ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                log("checkForCompatibleConnectedApnContext: found potential conn=" + potentialDcac
1474ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        + " curApnCtx=" + potentialApnCtx);
1475cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1476ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            return potentialDcac;
1477cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1478c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1479ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("checkForCompatibleConnectedApnContext: NO conn apnContext=" + apnContext);
1480cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
1481cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1482c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1483cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1484cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onEnableApn(int apnId, int enabled) {
1485cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnIdToType(apnId));
1486cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
1487cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onEnableApn(" + apnId + ", " + enabled + "): NO ApnContext");
1488cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
1489cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1490cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO change our retry manager to use the appropriate numbers for the new APN
1491cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onEnableApn: apnContext=" + apnContext + " call applyNewState");
1492cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        applyNewState(apnContext, enabled == DctConstants.ENABLED, apnContext.getDependencyMet());
1493cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1494c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1495cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1496cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // TODO: We shouldnt need this.
1497cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean onTrySetupData(String reason) {
1498cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onTrySetupData: reason=" + reason);
1499ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(reason);
1500cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
1501cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1502c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1503cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean onTrySetupData(ApnContext apnContext) {
1504cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onTrySetupData: apnContext=" + apnContext);
1505cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return trySetupData(apnContext);
1506cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1507c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1508cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1509cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onRoamingOff() {
1510cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onRoamingOff");
1511c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1512cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mUserDataEnabled == false) return;
1513c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1514cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getDataOnRoamingEnabled() == false) {
1515cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_OFF);
1516ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_ROAMING_OFF);
1517cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1518cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_ROAMING_OFF);
1519cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1520cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1521cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1522cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1523cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onRoamingOn() {
1524cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mUserDataEnabled == false) return;
1525cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1526cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getDataOnRoamingEnabled()) {
1527cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRoamingOn: setup data on roaming");
1528ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_ROAMING_ON);
1529cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_ROAMING_ON);
1530cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1531cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRoamingOn: Tear down data connection on roaming.");
1532cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpAllConnections(true, Phone.REASON_ROAMING_ON);
1533cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
1534cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1535cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1536cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1537cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1538cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onRadioAvailable() {
1539cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onRadioAvailable");
1540cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
1541cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
1542cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
1543cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // setState(DctConstants.State.CONNECTED);
1544cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(null);
1545cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1546cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("onRadioAvailable: We're on the simulator; assuming data is connected");
1547cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1548cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1549cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
1550cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (r != null && r.getRecordsLoaded()) {
1551cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(null);
1552cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1553cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1554cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getOverallState() != DctConstants.State.IDLE) {
1555cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpConnection(true, null);
1556cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1557cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1558cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1559cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1560cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onRadioOffOrNotAvailable() {
1561cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Make sure our reconnect delay starts at the initial value
1562cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // next time the radio comes on
1563cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1564cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mReregisterOnReconnectFailure = false;
1565cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1566cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
1567cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
1568cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
1569cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("We're on the simulator; assuming radio off is meaningless");
1570cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1571cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRadioOffOrNotAvailable: is off and clean up all connections");
1572cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpAllConnections(false, Phone.REASON_RADIO_TURNED_OFF);
1573cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1574cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyOffApnsOfAvailability(null);
1575cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1576cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1577c9b81a0c05128694c617fcdd67e73821895822feWink Saville    @Override
1578c9b81a0c05128694c617fcdd67e73821895822feWink Saville    protected void completeConnection(ApnContext apnContext) {
1579c9b81a0c05128694c617fcdd67e73821895822feWink Saville        boolean isProvApn = apnContext.isProvisioningApn();
1580c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1581c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (DBG) log("completeConnection: successful, notify the world apnContext=" + apnContext);
1582c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1583c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (mIsProvisioning && !TextUtils.isEmpty(mProvisioningUrl)) {
1584c9b81a0c05128694c617fcdd67e73821895822feWink Saville            if (DBG) {
1585c9b81a0c05128694c617fcdd67e73821895822feWink Saville                log("completeConnection: MOBILE_PROVISIONING_ACTION url="
1586c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        + mProvisioningUrl);
1587c9b81a0c05128694c617fcdd67e73821895822feWink Saville            }
1588c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt            Intent newIntent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN,
1589c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt                    Intent.CATEGORY_APP_BROWSER);
1590c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt            newIntent.setData(Uri.parse(mProvisioningUrl));
1591c9b81a0c05128694c617fcdd67e73821895822feWink Saville            newIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
1592c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    Intent.FLAG_ACTIVITY_NEW_TASK);
1593c9b81a0c05128694c617fcdd67e73821895822feWink Saville            try {
1594c9b81a0c05128694c617fcdd67e73821895822feWink Saville                mPhone.getContext().startActivity(newIntent);
1595c9b81a0c05128694c617fcdd67e73821895822feWink Saville            } catch (ActivityNotFoundException e) {
1596c9b81a0c05128694c617fcdd67e73821895822feWink Saville                loge("completeConnection: startActivityAsUser failed" + e);
1597c9b81a0c05128694c617fcdd67e73821895822feWink Saville            }
1598c9b81a0c05128694c617fcdd67e73821895822feWink Saville        }
1599c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mIsProvisioning = false;
1600c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mProvisioningUrl = null;
1601c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1602c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1603c9b81a0c05128694c617fcdd67e73821895822feWink Saville        startNetStatPoll();
1604c9b81a0c05128694c617fcdd67e73821895822feWink Saville        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
1605c9b81a0c05128694c617fcdd67e73821895822feWink Saville    }
1606c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1607ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
1608ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * A SETUP (aka bringUp) has completed, possibly with an error. If
1609ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * there is an error this method will call {@link #onDataSetupCompleteError}.
1610ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
1611cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1612cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onDataSetupComplete(AsyncResult ar) {
1613f3ab6ab303e1da929ce26b7c5d63565bff136221Robert Greenwalt
1614ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        DcFailCause cause = DcFailCause.UNKNOWN;
1615cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean handleError = false;
1616cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = null;
1617cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1618cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(ar.userObj instanceof ApnContext){
1619cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext = (ApnContext)ar.userObj;
1620cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1621cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            throw new RuntimeException("onDataSetupComplete: No apnContext");
1622cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1623cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1624cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (ar.exception == null) {
1625454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = apnContext.getDcAc();
1626cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1627cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (RADIO_TESTS) {
1628cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Note: To change radio.test.onDSC.null.dcac from command line you need to
1629cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // adb root and adb remount and from the command line you can only change the
1630cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // value to 1 once. To change it a second time you can reboot or execute
1631cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // adb shell stop and then adb shell start. The command line to set the value is:
1632ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink 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');"
1633cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ContentResolver cr = mPhone.getContext().getContentResolver();
1634cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                String radioTestProperty = "radio.test.onDSC.null.dcac";
1635cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (Settings.System.getInt(cr, radioTestProperty, 0) == 1) {
1636cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: " + radioTestProperty +
1637cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            " is true, set dcac to null and reset property to false");
1638cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    dcac = null;
1639cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    Settings.System.putInt(cr, radioTestProperty, 0);
1640cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: " + radioTestProperty + "=" +
1641cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            Settings.System.getInt(mPhone.getContext().getContentResolver(),
1642cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                    radioTestProperty, -1));
1643cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1644c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1645cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac == null) {
1646cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("onDataSetupComplete: no connection to DC, handle as error");
1647ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                cause = DcFailCause.CONNECTION_TO_DATACONNECTIONAC_BROKEN;
1648cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                handleError = true;
1649cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1650cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ApnSetting apn = apnContext.getApnSetting();
1651cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
1652cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: success apn=" + (apn == null ? "unknown" : apn.apn));
1653cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1654cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn != null && apn.proxy != null && apn.proxy.length() != 0) {
1655cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    try {
1656cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        String port = apn.port;
1657cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (TextUtils.isEmpty(port)) port = "8080";
16589c180aedfc9f0d20525c0128487d3500e6c0a715Jason Monk                        ProxyInfo proxy = new ProxyInfo(apn.proxy,
1659cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                Integer.parseInt(port), null);
1660cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        dcac.setLinkPropertiesHttpProxySync(proxy);
1661cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    } catch (NumberFormatException e) {
1662cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        loge("onDataSetupComplete: NumberFormatException making ProxyProperties (" +
1663cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                apn.port + "): " + e);
1664cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1665cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1666cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1667cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // everything is setup
1668cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if(TextUtils.equals(apnContext.getApnType(),PhoneConstants.APN_TYPE_DEFAULT)) {
1669ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "true");
167022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mCanSetPreferApn && mPreferredApn == null) {
1671cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (DBG) log("onDataSetupComplete: PREFERED APN is null");
1672cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mPreferredApn = apn;
1673cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (mPreferredApn != null) {
1674cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            setPreferredApn(mPreferredApn.id);
1675cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
1676cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1677cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1678ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
1679cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1680c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1681c9b81a0c05128694c617fcdd67e73821895822feWink Saville                // A connection is setup
1682c9b81a0c05128694c617fcdd67e73821895822feWink Saville                apnContext.setState(DctConstants.State.CONNECTED);
1683c9b81a0c05128694c617fcdd67e73821895822feWink Saville                boolean isProvApn = apnContext.isProvisioningApn();
1684c9b81a0c05128694c617fcdd67e73821895822feWink Saville                if ((!isProvApn) || mIsProvisioning) {
1685c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // Complete the connection normally notifying the world we're connected.
1686c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // We do this if this isn't a special provisioning apn or if we've been
1687c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // told its time to provision.
1688c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    completeConnection(apnContext);
1689c9b81a0c05128694c617fcdd67e73821895822feWink Saville                } else {
1690c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // This is a provisioning APN that we're reporting as connected. Later
1691c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // when the user desires to upgrade this to a "default" connection,
1692c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // mIsProvisioning == true, we'll go through the code path above.
1693c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // mIsProvisioning becomes true when CMD_ENABLE_MOBILE_PROVISIONING
1694c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // is sent to the DCT.
1695c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    if (DBG) {
1696c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        log("onDataSetupComplete: successful, BUT send connected to prov apn as"
1697c9b81a0c05128694c617fcdd67e73821895822feWink Saville                                + " mIsProvisioning:" + mIsProvisioning + " == false"
1698c9b81a0c05128694c617fcdd67e73821895822feWink Saville                                + " && (isProvisioningApn:" + isProvApn + " == true");
1699c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    }
1700c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1701c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    Intent intent = new Intent(
1702c9b81a0c05128694c617fcdd67e73821895822feWink Saville                            TelephonyIntents.ACTION_DATA_CONNECTION_CONNECTED_TO_PROVISIONING_APN);
1703c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    intent.putExtra(PhoneConstants.DATA_APN_KEY, apnContext.getApnSetting().apn);
1704c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnContext.getApnType());
1705c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1706c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    String apnType = apnContext.getApnType();
1707c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    LinkProperties linkProperties = getLinkProperties(apnType);
1708c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    if (linkProperties != null) {
1709c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties);
1710c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        String iface = linkProperties.getInterfaceName();
1711c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        if (iface != null) {
1712c9b81a0c05128694c617fcdd67e73821895822feWink Saville                            intent.putExtra(PhoneConstants.DATA_IFACE_NAME_KEY, iface);
1713c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        }
1714c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    }
1715f3ab6ab303e1da929ce26b7c5d63565bff136221Robert Greenwalt                    NetworkCapabilities networkCapabilities = getNetworkCapabilities(apnType);
171696cce86cf08e37e0f09ed5057b1196e26b302743Robert Greenwalt                    if (networkCapabilities != null) {
171796cce86cf08e37e0f09ed5057b1196e26b302743Robert Greenwalt                        intent.putExtra(PhoneConstants.DATA_NETWORK_CAPABILITIES_KEY,
171896cce86cf08e37e0f09ed5057b1196e26b302743Robert Greenwalt                                networkCapabilities);
1719c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    }
1720c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1721c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    mPhone.getContext().sendBroadcastAsUser(intent, UserHandle.ALL);
1722c9b81a0c05128694c617fcdd67e73821895822feWink Saville                }
1723c9b81a0c05128694c617fcdd67e73821895822feWink Saville                if (DBG) {
1724c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    log("onDataSetupComplete: SETUP complete type=" + apnContext.getApnType()
1725c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        + ", reason:" + apnContext.getReason());
1726c9b81a0c05128694c617fcdd67e73821895822feWink Saville                }
1727c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1728cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1729ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            cause = (DcFailCause) (ar.result);
1730cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
1731cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ApnSetting apn = apnContext.getApnSetting();
1732cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log(String.format("onDataSetupComplete: error apn=%s cause=%s",
1733cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        (apn == null ? "unknown" : apn.apn), cause));
1734c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1735cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cause.isEventLoggable()) {
1736cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Log this failure to the Event Logs.
1737cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                int cid = getCellLocationId();
1738cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                EventLog.writeEvent(EventLogTags.PDP_SETUP_FAIL,
1739cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        cause.ordinal(), cid, TelephonyManager.getDefault().getNetworkType());
1740c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
17410742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela            ApnSetting apn = apnContext.getApnSetting();
17420742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela            mPhone.notifyPreciseDataConnectionFailed(apnContext.getReason(),
17430742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela                    apnContext.getApnType(), apn != null ? apn.apn : "unknown", cause.toString());
1744cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1745cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Count permanent failures and remove the APN we just tried
1746cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cause.isPermanentFail()) apnContext.decWaitingApnsPermFailCount();
1747cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1748cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.removeWaitingApn(apnContext.getApnSetting());
1749cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
1750cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log(String.format("onDataSetupComplete: WaitingApns.size=%d" +
1751cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        " WaitingApnsPermFailureCountDown=%d",
1752cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.getWaitingApns().size(),
1753cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.getWaitingApnsPermFailCount()));
1754c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1755cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            handleError = true;
1756cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1757cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1758cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (handleError) {
1759ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            onDataSetupCompleteError(ar);
1760ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
1761ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
1762cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1763ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
1764ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville     * @return number of milli-seconds to delay between trying apns'
1765ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville     */
1766ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville    private int getApnDelay() {
1767ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        if (mFailFast) {
1768ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville            return SystemProperties.getInt("persist.radio.apn_ff_delay",
1769ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville                    APN_FAIL_FAST_DELAY_DEFAULT_MILLIS);
1770ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        } else {
1771ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville            return SystemProperties.getInt("persist.radio.apn_delay", APN_DELAY_DEFAULT_MILLIS);
1772ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        }
1773ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville    }
1774ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville
1775ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville    /**
1776ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Error has occurred during the SETUP {aka bringUP} request and the DCT
1777ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * should either try the next waiting APN or start over from the
1778ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * beginning if the list is empty. Between each SETUP request there will
1779ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville     * be a delay defined by {@link #getApnDelay()}.
1780ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
1781ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    @Override
1782ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    protected void onDataSetupCompleteError(AsyncResult ar) {
1783ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        String reason = "";
1784ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnContext apnContext = null;
1785ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
1786ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if(ar.userObj instanceof ApnContext){
1787ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext = (ApnContext)ar.userObj;
1788ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        } else {
1789ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            throw new RuntimeException("onDataSetupCompleteError: No apnContext");
1790ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
1791ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
1792ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // See if there are more APN's to try
1793ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnContext.getWaitingApns().isEmpty()) {
1794ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext.setState(DctConstants.State.FAILED);
1795ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType());
1796ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
1797ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext.setDataConnectionAc(null);
1798ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
1799ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getWaitingApnsPermFailCount() == 0) {
1800ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) {
1801017166876a51eda9ae6b3254119023604e249bc5Wink Saville                    log("onDataSetupCompleteError: All APN's had permanent failures, stop retrying");
1802c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1803cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1804e056c8263473f67dc78630f5535c3664fabacd23Wink Saville                int delay = getApnDelay();
1805ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) {
1806da1dd2e1bccb6141109a65d4e40253f39c405537Wink Saville                    log("onDataSetupCompleteError: Not all APN's had permanent failures delay="
1807da1dd2e1bccb6141109a65d4e40253f39c405537Wink Saville                            + delay);
1808ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                }
1809017166876a51eda9ae6b3254119023604e249bc5Wink Saville                startAlarmForRestartTrySetup(delay, apnContext);
1810c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1811ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        } else {
1812da1dd2e1bccb6141109a65d4e40253f39c405537Wink Saville            if (DBG) log("onDataSetupCompleteError: Try next APN");
1813ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext.setState(DctConstants.State.SCANNING);
1814ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // Wait a bit before trying the next APN, so that
1815ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // we're not tying up the RIL command channel
1816ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville            startAlarmForReconnect(getApnDelay(), apnContext);
1817c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1818c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1819c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1820c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1821cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Called when EVENT_DISCONNECT_DONE is received.
1822c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1823cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1824cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onDisconnectDone(int connId, AsyncResult ar) {
1825cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = null;
1826cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1827cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (ar.userObj instanceof ApnContext) {
1828cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext = (ApnContext) ar.userObj;
1829cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1830cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onDisconnectDone: Invalid ar in onDisconnectDone, ignore");
1831cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
1832c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1833c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1834cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE apnContext=" + apnContext);
1835cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setState(DctConstants.State.IDLE);
1836cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1837cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1838cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1839cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // if all data connection are gone, check whether Airplane mode request was
1840cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // pending.
1841cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isDisconnected()) {
1842cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPhone.getServiceStateTracker().processPendingRadioPowerOffAfterDataOff()) {
1843449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                if(DBG) log("onDisconnectDone: radio will be turned off, no retries");
1844cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Radio will be turned off. No need to retry data setup
1845cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setApnSetting(null);
1846cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setDataConnectionAc(null);
1847cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return;
1848cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1849c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1850c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1851cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // If APN is still enabled, try to bring it back up automatically
18523fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (mAttached.get() && apnContext.isReady() && retryAfterDisconnected(apnContext)) {
1853ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
1854cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Wait a bit before trying the next APN, so that
1855cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // we're not tying up the RIL command channel.
1856cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // This also helps in any external dependency to turn off the context.
1857449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            if(DBG) log("onDisconnectDone: attached, ready and retry after disconnect");
1858ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville            startAlarmForReconnect(getApnDelay(), apnContext);
1859c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
1860449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            boolean restartRadioAfterProvisioning = mPhone.getContext().getResources().getBoolean(
1861449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                    com.android.internal.R.bool.config_restartRadioAfterProvisioning);
1862449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville
1863449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            if (apnContext.isProvisioningApn() && restartRadioAfterProvisioning) {
1864449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                log("onDisconnectDone: restartRadio after provisioning");
1865449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                restartRadio();
1866449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            }
1867cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setApnSetting(null);
1868cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setDataConnectionAc(null);
18693fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())) {
1870449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                if(DBG) log("onDisconnectDone: isOnlySigneDcAllowed true so setup single apn");
18713fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                setupDataOnConnectableApns(Phone.REASON_SINGLE_PDN_ARBITRATION);
1872449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            } else {
1873449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                if(DBG) log("onDisconnectDone: not retrying");
18743fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
1875c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1876c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1877c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1878ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
1879ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Called when EVENT_DISCONNECT_DC_RETRYING is received.
1880ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
1881ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    @Override
1882ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    protected void onDisconnectDcRetrying(int connId, AsyncResult ar) {
1883ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // We could just do this in DC!!!
1884ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnContext apnContext = null;
1885ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
1886ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (ar.userObj instanceof ApnContext) {
1887ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext = (ApnContext) ar.userObj;
1888ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        } else {
1889ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            loge("onDisconnectDcRetrying: Invalid ar in onDisconnectDone, ignore");
1890ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            return;
1891ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
1892ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
1893ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setState(DctConstants.State.RETRYING);
1894ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if(DBG) log("onDisconnectDcRetrying: apnContext=" + apnContext);
1895ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
1896ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1897ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
1898ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
1899c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1900cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1901cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onVoiceCallStarted() {
1902cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onVoiceCallStarted");
1903ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        mInVoiceCall = true;
1904cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnected() && ! mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
1905cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onVoiceCallStarted stop polling");
1906cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            stopNetStatPoll();
1907cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            stopDataStallAlarm();
1908cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
1909c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1910c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1911c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1912cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1913cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onVoiceCallEnded() {
1914cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onVoiceCallEnded");
1915ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        mInVoiceCall = false;
1916cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnected()) {
1917cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
1918cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                startNetStatPoll();
1919cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
1920cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
1921cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1922cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // clean slate after call end.
1923cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                resetPollStats();
1924c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1925c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1926cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // reset reconnect timer
1927ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(Phone.REASON_VOICE_CALL_ENDED);
1928c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1929c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1930cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1931cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onCleanUpConnection(boolean tearDown, int apnId, String reason) {
1932cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onCleanUpConnection");
1933cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnIdToType(apnId));
1934cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
1935cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setReason(reason);
1936cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpConnection(tearDown, apnContext);
1937c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1938c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1939c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1940cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1941cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean isConnected() {
1942cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1943ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getState() == DctConstants.State.CONNECTED) {
1944cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // At least one context is connected, return true
1945cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return true;
1946c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1947c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1948cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // There are not any contexts connected, return false
1949cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return false;
1950c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1951c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1952cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1953cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isDisconnected() {
1954cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1955cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!apnContext.isDisconnected()) {
1956cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // At least one context was not disconnected return false
1957cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
1958cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1959c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1960cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // All contexts were disconnected so return true
1961cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
1962c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1963c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1964cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1965cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void notifyDataConnection(String reason) {
1966cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("notifyDataConnection: reason=" + reason);
1967cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1968187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (mAttached.get() && apnContext.isReady()) {
1969187a39f896f88eb6c5e4306d9595546654825976Wink Saville                if (DBG) log("notifyDataConnection: type:" + apnContext.getApnType());
1970cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
1971cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.getApnType());
1972cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1973c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1974cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyOffApnsOfAvailability(reason);
1975c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1976c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1977c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1978cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Based on the sim operator numeric, create a list for all possible
1979cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Data Connections and setup the preferredApn.
1980c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1981cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void createAllApnList() {
1982ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mAllApnSettings = new ArrayList<ApnSetting>();
1983cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
1984cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String operator = (r != null) ? r.getOperatorNumeric() : "";
1985cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (operator != null) {
1986cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            String selection = "numeric = '" + operator + "'";
1987cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // query only enabled apn.
1988cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // carrier_enabled : 1 means enabled apn, 0 disabled apn.
1989cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            selection += " and carrier_enabled = 1";
1990cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: selection=" + selection);
1991cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1992cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            Cursor cursor = mPhone.getContext().getContentResolver().query(
1993cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    Telephony.Carriers.CONTENT_URI, null, selection, null, null);
1994cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1995cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cursor != null) {
1996cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (cursor.getCount() > 0) {
1997ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    mAllApnSettings = createApnList(cursor);
1998cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1999cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cursor.close();
2000cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2001c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2002c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2003ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings.isEmpty()) {
2004cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: No APN found for carrier: " + operator);
2005cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPreferredApn = null;
2006ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // TODO: What is the right behavior?
2007cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            //notifyNoData(DataConnection.FailCause.MISSING_UNKNOWN_APN);
2008c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
2009cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPreferredApn = getPreferredApn();
2010cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator)) {
2011cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn = null;
2012cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                setPreferredApn(-1);
2013cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2014cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: mPreferredApn=" + mPreferredApn);
2015c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2016ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("createAllApnList: X mAllApnSettings=" + mAllApnSettings);
2017c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2018c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2019ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /** Return the DC AsyncChannel for the new data connection */
2020454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel createDataConnection() {
2021cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createDataConnection E");
2022cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2023cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int id = mUniqueIdGenerator.getAndIncrement();
2024ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        DataConnection conn = DataConnection.makeDataConnection(mPhone, id,
2025ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                                this, mDcTesterFailBringUpAll, mDcc);
2026cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mDataConnections.put(id, conn);
2027454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac = new DcAsyncChannel(conn, LOG_TAG);
2028cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int status = dcac.fullyConnectSync(mPhone.getContext(), this, conn.getHandler());
2029cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (status == AsyncChannel.STATUS_SUCCESSFUL) {
2030ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            mDataConnectionAcHashMap.put(dcac.getDataConnectionIdSync(), dcac);
2031c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
2032ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            loge("createDataConnection: Could not connect to dcac=" + dcac + " status=" + status);
2033c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2034cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2035cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createDataConnection() X id=" + id + " dc=" + conn);
2036ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        return dcac;
2037c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2038c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2039cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void destroyDataConnections() {
2040cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(mDataConnections != null) {
2041cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("destroyDataConnections: clear mDataConnectionList");
2042cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mDataConnections.clear();
2043cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2044cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("destroyDataConnections: mDataConnecitonList is empty, ignore");
2045c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2046c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2047c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2048c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
2049cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Build a list of APNs to be used to create PDP's.
2050c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
2051cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param requestedApnType
2052cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return waitingApns list to be used to create PDP
2053cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *          error when waitingApns.isEmpty()
2054c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
2055203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    private ArrayList<ApnSetting> buildWaitingApns(String requestedApnType, int radioTech) {
2056cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("buildWaitingApns: E requestedApnType=" + requestedApnType);
2057cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ArrayList<ApnSetting> apnList = new ArrayList<ApnSetting>();
2058cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2059cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (requestedApnType.equals(PhoneConstants.APN_TYPE_DUN)) {
2060cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ApnSetting dun = fetchDunApn();
2061cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dun != null) {
2062cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnList.add(dun);
2063cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: X added APN_TYPE_DUN apnList=" + apnList);
2064cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return apnList;
2065c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2066c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2067c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2068cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
2069cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String operator = (r != null) ? r.getOperatorNumeric() : "";
2070c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2071cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // This is a workaround for a bug (7305641) where we don't failover to other
2072cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // suitable APNs if our preferred APN fails.  On prepaid ATT sims we need to
2073cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // failover to a provisioning APN, but once we've used their default data
2074cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // connection we are locked to it for life.  This change allows ATT devices
2075cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // to say they don't want to use preferred at all.
2076cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean usePreferred = true;
2077cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        try {
2078cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            usePreferred = ! mPhone.getContext().getResources().getBoolean(com.android.
2079cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    internal.R.bool.config_dontPreferApn);
2080cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } catch (Resources.NotFoundException e) {
2081cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("buildWaitingApns: usePreferred NotFoundException set to true");
2082cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            usePreferred = true;
2083cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2084cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
2085cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("buildWaitingApns: usePreferred=" + usePreferred
208622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    + " canSetPreferApn=" + mCanSetPreferApn
2087cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " mPreferredApn=" + mPreferredApn
2088cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " operator=" + operator + " radioTech=" + radioTech
2089cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " IccRecords r=" + r);
2090cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2091c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
209222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (usePreferred && mCanSetPreferApn && mPreferredApn != null &&
2093cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn.canHandleType(requestedApnType)) {
2094cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
2095cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("buildWaitingApns: Preferred APN:" + operator + ":"
2096cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        + mPreferredApn.numeric + ":" + mPreferredApn);
2097cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2098cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPreferredApn.numeric.equals(operator)) {
2099cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (mPreferredApn.bearer == 0 || mPreferredApn.bearer == radioTech) {
2100cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnList.add(mPreferredApn);
2101cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
2102cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return apnList;
2103cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2104cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("buildWaitingApns: no preferred APN");
2105cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    setPreferredApn(-1);
2106cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mPreferredApn = null;
2107c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
2108cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
2109cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: no preferred APN");
2110cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                setPreferredApn(-1);
2111cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn = null;
2112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2113c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2114ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings != null) {
2115ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (DBG) log("buildWaitingApns: mAllApnSettings=" + mAllApnSettings);
2116ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for (ApnSetting apn : mAllApnSettings) {
2117cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: apn=" + apn);
2118cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn.canHandleType(requestedApnType)) {
2119cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (apn.bearer == 0 || apn.bearer == radioTech) {
2120cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (DBG) log("buildWaitingApns: adding apn=" + apn.toString());
2121cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnList.add(apn);
2122c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else {
2123cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (DBG) {
2124cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            log("buildWaitingApns: bearer:" + apn.bearer + " != "
2125cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                    + "radioTech:" + radioTech);
2126cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
2127c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
2128cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2129cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
2130cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("buildWaitingApns: couldn't handle requesedApnType="
2131cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            + requestedApnType);
2132c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
2133c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2134c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2135cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2136ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            loge("mAllApnSettings is empty!");
2137c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2138cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("buildWaitingApns: X apnList=" + apnList);
2139cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return apnList;
2140c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2141c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2142cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private String apnListToString (ArrayList<ApnSetting> apns) {
2143cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        StringBuilder result = new StringBuilder();
2144cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (int i = 0, size = apns.size(); i < size; i++) {
2145cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result.append('[')
2146cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                  .append(apns.get(i).toString())
2147cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                  .append(']');
2148c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2149cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result.toString();
2150c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2151c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2152cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void setPreferredApn(int pos) {
215322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (!mCanSetPreferApn) {
2154cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("setPreferredApn: X !canSEtPreferApn");
2155cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
2156cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2157cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2158cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("setPreferredApn: delete");
2159cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ContentResolver resolver = mPhone.getContext().getContentResolver();
2160cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        resolver.delete(PREFERAPN_NO_UPDATE_URI, null, null);
2161cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2162cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (pos >= 0) {
2163cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("setPreferredApn: insert");
2164cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ContentValues values = new ContentValues();
2165cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            values.put(APN_ID, pos);
2166cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            resolver.insert(PREFERAPN_NO_UPDATE_URI, values);
2167cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2168cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2169cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2170cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ApnSetting getPreferredApn() {
2171ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings.isEmpty()) {
2172ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            log("getPreferredApn: X not found mAllApnSettings.isEmpty");
2173cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return null;
2174cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2175cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2176cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Cursor cursor = mPhone.getContext().getContentResolver().query(
2177cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                PREFERAPN_NO_UPDATE_URI, new String[] { "_id", "name", "apn" },
2178cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
2179cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2180cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor != null) {
218122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCanSetPreferApn = true;
2182cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
218322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCanSetPreferApn = false;
2184cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2185cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("getPreferredApn: mRequestedApnType=" + mRequestedApnType + " cursor=" + cursor
2186cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                + " cursor.count=" + ((cursor != null) ? cursor.getCount() : 0));
2187cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
218822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mCanSetPreferApn && cursor.getCount() > 0) {
2189cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            int pos;
2190cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cursor.moveToFirst();
2191cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            pos = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID));
2192ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for(ApnSetting p : mAllApnSettings) {
2193cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("getPreferredApn: apnSetting=" + p);
2194cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (p.id == pos && p.canHandleType(mRequestedApnType)) {
2195cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("getPreferredApn: X found apnSetting" + p);
2196cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    cursor.close();
2197cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return p;
2198cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2199cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
2200cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2201cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2202cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor != null) {
2203cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cursor.close();
2204cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2205cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2206cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("getPreferredApn: X not found");
2207cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
2208cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
2209cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2210cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2211cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void handleMessage (Message msg) {
2212cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("handleMessage msg=" + msg);
2213cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2214cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (!mPhone.mIsTheCurrentActivePhone || mIsDisposed) {
2215cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("handleMessage: Ignore GSM msgs since GSM phone is inactive");
2216cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
2217cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2218cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2219cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        switch (msg.what) {
2220cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_RECORDS_LOADED:
2221cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onRecordsLoaded();
2222cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2223cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2224cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_CONNECTION_DETACHED:
2225cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onDataConnectionDetached();
2226cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2227cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2228cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_CONNECTION_ATTACHED:
2229cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onDataConnectionAttached();
2230cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2231cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2232cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DO_RECOVERY:
2233cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                doRecovery();
2234cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2235cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2236cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_APN_CHANGED:
2237cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onApnChanged();
2238cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2239cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2240cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_PS_RESTRICT_ENABLED:
2241cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                /**
2242cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * We don't need to explicitly to tear down the PDP context
2243cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * when PS restricted is enabled. The base band will deactive
2244cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * PDP context and notify us with PDP_CONTEXT_CHANGED.
2245cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * But we should stop the network polling and prevent reset PDP.
2246cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 */
2247cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
2248cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                stopNetStatPoll();
2249cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                stopDataStallAlarm();
2250cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsPsRestricted = true;
2251cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
2252cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2253cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_PS_RESTRICT_DISABLED:
2254cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                /**
2255cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * When PS restrict is removed, we need setup PDP connection if
2256cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * PDP connection is down.
2257cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 */
2258cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_PS_RESTRICT_DISABLED " + mIsPsRestricted);
2259cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsPsRestricted  = false;
2260cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (isConnected()) {
2261cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    startNetStatPoll();
2262cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
2263cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2264cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // TODO: Should all PDN states be checked to fail?
2265ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    if (mState == DctConstants.State.FAILED) {
2266cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        cleanUpAllConnections(false, Phone.REASON_PS_RESTRICT_ENABLED);
2267cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mReregisterOnReconnectFailure = false;
2268cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
22693fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    ApnContext apnContext = mApnContexts.get(PhoneConstants.APN_TYPE_DEFAULT);
22703fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (apnContext != null) {
22713fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        apnContext.setReason(Phone.REASON_PS_RESTRICT_ENABLED);
22723fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        trySetupData(apnContext);
22733fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    } else {
22743fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        loge("**** Default ApnContext not found ****");
22753fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        if (Build.IS_DEBUGGABLE) {
22763fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                            throw new RuntimeException("Default ApnContext not found");
22773fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        }
22783fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    }
2279cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2280cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
2281ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
2282cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_TRY_SETUP_DATA:
2283cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (msg.obj instanceof ApnContext) {
2284cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    onTrySetupData((ApnContext)msg.obj);
2285cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else if (msg.obj instanceof String) {
2286cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    onTrySetupData((String)msg.obj);
2287cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2288cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    loge("EVENT_TRY_SETUP request w/o apnContext or String");
2289cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2290cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
2291cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2292cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_CLEAN_UP_CONNECTION:
2293cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                boolean tearDown = (msg.arg1 == 0) ? false : true;
2294cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_CLEAN_UP_CONNECTION tearDown=" + tearDown);
2295cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (msg.obj instanceof ApnContext) {
2296cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    cleanUpConnection(tearDown, (ApnContext)msg.obj);
2297cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2298ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    loge("EVENT_CLEAN_UP_CONNECTION request w/o apn context, call super");
2299ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    super.handleMessage(msg);
2300cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2301cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
2302ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
2303cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            default:
2304cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // handle the message in the super class DataConnectionTracker
2305cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                super.handleMessage(msg);
2306cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
2307cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2308cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
2309cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2310cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected int getApnProfileID(String apnType) {
2311cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IMS)) {
2312cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_IMS;
2313cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_FOTA)) {
2314cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_FOTA;
2315cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_CBS)) {
2316cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_CBS;
23171b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IA)) {
23181b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            return RILConstants.DATA_PROFILE_DEFAULT; // DEFAULT for now
231945df26444864daad60afdd4d121ab4043da3834bSungmin Choi        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_DUN)) {
232045df26444864daad60afdd4d121ab4043da3834bSungmin Choi            return RILConstants.DATA_PROFILE_TETHERED;
2321cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2322cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_DEFAULT;
2323cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2324cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2325cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2326cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private int getCellLocationId() {
2327cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int cid = -1;
2328cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        CellLocation loc = mPhone.getCellLocation();
2329cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2330cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (loc != null) {
2331cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (loc instanceof GsmCellLocation) {
2332cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cid = ((GsmCellLocation)loc).getCid();
2333cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else if (loc instanceof CdmaCellLocation) {
2334cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cid = ((CdmaCellLocation)loc).getBaseStationId();
2335cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
2336cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2337cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return cid;
2338cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
2339cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2340cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2341cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onUpdateIcc() {
2342cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mUiccController == null ) {
2343cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            return;
2344cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
2345cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2346cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords newIccRecords = mUiccController.getIccRecords(UiccController.APP_FAM_3GPP);
2347cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2348cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
2349cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (r != newIccRecords) {
2350cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (r != null) {
2351cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("Removing stale icc objects.");
2352cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                r.unregisterForRecordsLoaded(this);
2353cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIccRecords.set(null);
23549aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan            }
2355cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (newIccRecords != null) {
2356cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("New records found");
2357cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIccRecords.set(newIccRecords);
2358cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                newIccRecords.registerForRecordsLoaded(
2359cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        this, DctConstants.EVENT_RECORDS_LOADED, null);
23609aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan            }
23619aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan        }
2362cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
2363cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2364cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2365cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void log(String s) {
2366ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        Rlog.d(LOG_TAG, s);
2367cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
2368cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2369cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2370cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void loge(String s) {
2371ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        Rlog.e(LOG_TAG, s);
2372cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
2373cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
2374cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2375c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2376cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println("DataConnectionTracker extends:");
2377cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        super.dump(fd, pw, args);
2378cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mReregisterOnReconnectFailure=" + mReregisterOnReconnectFailure);
237922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" canSetPreferApn=" + mCanSetPreferApn);
2380cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mApnObserver=" + mApnObserver);
2381cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" getOverallState=" + getOverallState());
2382ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        pw.println(" mDataConnectionAsyncChannels=%s\n" + mDataConnectionAcHashMap);
2383187a39f896f88eb6c5e4306d9595546654825976Wink Saville        pw.println(" mAttached=" + mAttached.get());
2384c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2385c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville}
2386