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
1964928c72f74688d63a20cd233c28fc089d336a7aJayachandran Cimport static android.Manifest.permission.READ_PHONE_STATE;
2064928c72f74688d63a20cd233c28fc089d336a7aJayachandran C
212abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liuimport android.annotation.NonNull;
22cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kallaimport android.app.AlarmManager;
23c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.app.PendingIntent;
242b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensenimport android.app.ProgressDialog;
25c9b81a0c05128694c617fcdd67e73821895822feWink Savilleimport android.content.ActivityNotFoundException;
26b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensenimport android.content.BroadcastReceiver;
27c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.ContentResolver;
28cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.content.ContentValues;
29c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Context;
30c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Intent;
31c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.IntentFilter;
321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.content.SharedPreferences;
33cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.content.res.Resources;
34c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.database.ContentObserver;
35cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.database.Cursor;
36cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.ConnectivityManager;
37c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.net.LinkProperties;
3896cce86cf08e37e0f09ed5057b1196e26b302743Robert Greenwaltimport android.net.NetworkCapabilities;
39cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.NetworkConfig;
40af5593594070f825032be46dced573cd195956e1Robert Greenwaltimport android.net.NetworkRequest;
41cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.NetworkUtils;
429c180aedfc9f0d20525c0128487d3500e6c0a715Jason Monkimport android.net.ProxyInfo;
431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.net.TrafficStats;
44cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.Uri;
45c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.AsyncResult;
463fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwaltimport android.os.Build;
47b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensenimport android.os.Bundle;
48a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.Handler;
491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.os.HandlerThread;
50c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Message;
51bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liuimport android.os.PersistableBundle;
52a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.RegistrantList;
53b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensenimport android.os.ServiceManager;
54c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemClock;
55c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemProperties;
561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.preference.PreferenceManager;
57c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.provider.Settings;
581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.provider.Settings.SettingNotFoundException;
59cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.provider.Telephony;
6071f909237a9921f52d91440fb8f9c6fc97465a52Jack Yuimport android.telephony.AccessNetworkConstants.TransportType;
61bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liuimport android.telephony.CarrierConfigManager;
62cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.CellLocation;
632e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwaltimport android.telephony.PcoData;
644c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport android.telephony.Rlog;
650e776303ca82b5bec5db19bb44e0f13b0c7c6400Etan Cohenimport android.telephony.ServiceState;
66a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.SubscriptionManager;
671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
684c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport android.telephony.TelephonyManager;
69cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.cdma.CdmaCellLocation;
70886183cde1263ea524cdf08524442724e246ed42Jack Yuimport android.telephony.data.DataProfile;
71cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.gsm.GsmCellLocation;
72c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.text.TextUtils;
73cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kallaimport android.util.EventLog;
742dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwaltimport android.util.LocalLog;
75ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwaltimport android.util.Pair;
76af5593594070f825032be46dced573cd195956e1Robert Greenwaltimport android.util.SparseArray;
772b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensenimport android.view.WindowManager;
78c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport com.android.internal.R;
80af5593594070f825032be46dced573cd195956e1Robert Greenwaltimport com.android.internal.annotations.VisibleForTesting;
816a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxuimport com.android.internal.telephony.CarrierActionAgent;
82cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.DctConstants;
83cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.EventLogTags;
844c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport com.android.internal.telephony.GsmCdmaPhone;
85b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensenimport com.android.internal.telephony.ITelephony;
864c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport com.android.internal.telephony.Phone;
874918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savilleimport com.android.internal.telephony.PhoneConstants;
886a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Guttaimport com.android.internal.telephony.PhoneFactory;
89cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.RILConstants;
90b8fa5c7082deeeb17434b42ed4838a5891a38769Jack Yuimport com.android.internal.telephony.SettingsObserver;
91a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxuimport com.android.internal.telephony.TelephonyIntents;
9299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yuimport com.android.internal.telephony.dataconnection.DataConnectionReasons.DataAllowedReasonType;
9399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yuimport com.android.internal.telephony.dataconnection.DataConnectionReasons.DataDisallowedReasonType;
94f2d0fa64860a12423fb8709766d6af90fba5e6cfJack Yuimport com.android.internal.telephony.metrics.TelephonyMetrics;
95d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccRecords;
96bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenkaimport com.android.internal.telephony.uicc.UiccController;
9776f43316a5a6082d601bffd4b6898d0bd81e11fcramimport com.android.internal.util.ArrayUtils;
984c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport com.android.internal.util.AsyncChannel;
99c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
100c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.io.FileDescriptor;
101c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.io.PrintWriter;
102c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.ArrayList;
10329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwaltimport java.util.Arrays;
1041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.Comparator;
1051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.HashMap;
1061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.Map.Entry;
1071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.PriorityQueue;
1081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.Set;
1091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.concurrent.ConcurrentHashMap;
1101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.concurrent.atomic.AtomicBoolean;
1111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.concurrent.atomic.AtomicInteger;
1121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.concurrent.atomic.AtomicReference;
113c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/**
114c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * {@hide}
115c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
1160c3ec24396bb8c21b4d89f743b626c13dd35ba7bAmit Mahajanpublic class DcTracker extends Handler {
1171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String LOG_TAG = "DCT";
1181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean DBG = true;
1191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean VDBG = false; // STOPSHIP if true
1201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean VDBG_STALL = false; // STOPSHIP if true
1211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean RADIO_TESTS = false;
1221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1230e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    public AtomicBoolean isCleanupRequired = new AtomicBoolean(false);
1241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final AlarmManager mAlarmManager;
1261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Currently requested APN type (TODO: This should probably be a parameter not a member) */
1281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private String mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
1291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
130a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    // All data enabling/disabling related settings
131985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen    private final DataEnabledSettings mDataEnabledSettings;
132a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
1330a39f581e11eb7b040a5412229164ef72044279fRobert Greenwalt
1341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
1351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * After detecting a potential connection problem, this is the max number
1361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * of subsequent polls before attempting recovery.
1371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
1381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // 1 sec. default polling interval when screen is on.
1391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int POLL_NETSTAT_MILLIS = 1000;
1401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // 10 min. default polling interval when screen is off.
1411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int POLL_NETSTAT_SCREEN_OFF_MILLIS = 1000*60*10;
1421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Default sent packets without ack which triggers initial recovery steps
1431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int NUMBER_SENT_PACKETS_OF_HANG = 10;
1441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Default for the data stall alarm while non-aggressive stall detection
1461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60 * 6;
1471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Default for the data stall alarm for aggressive stall detection
1481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60;
1491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Tag for tracking stale alarms
1501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String DATA_STALL_ALARM_TAG_EXTRA = "data.stall.alram.tag";
1511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean DATA_STALL_SUSPECTED = true;
1531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean DATA_STALL_NOT_SUSPECTED = false;
1541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_RECONNECT_ALARM =
1561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "com.android.internal.telephony.data-reconnect";
1571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_RECONNECT_ALARM_EXTRA_TYPE = "reconnect_alarm_extra_type";
1581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_RECONNECT_ALARM_EXTRA_REASON =
1591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "reconnect_alarm_extra_reason";
1601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_DATA_STALL_ALARM =
1621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "com.android.internal.telephony.data-stall";
1631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DcTesterFailBringUpAll mDcTesterFailBringUpAll;
1651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DcController mDcc;
1661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** kept in sync with mApnContexts
1681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Higher numbers are higher priority and sorted so highest priority is first */
1691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final PriorityQueue<ApnContext>mPrioritySortedApnContexts =
1701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new PriorityQueue<ApnContext>(5,
1711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new Comparator<ApnContext>() {
1721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                public int compare(ApnContext c1, ApnContext c2) {
1731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    return c2.priority - c1.priority;
1741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
1751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } );
1761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** allApns holds all apns */
1781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ArrayList<ApnSetting> mAllApnSettings = null;
1791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** preferred apn */
1811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ApnSetting mPreferredApn = null;
1821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Is packet service restricted by network */
1841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsPsRestricted = false;
1851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** emergency apn Setting*/
1871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ApnSetting mEmergencyApn = null;
1881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Once disposed dont handle any messages */
1901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsDisposed = false;
1911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ContentResolver mResolver;
1931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Set to true with CMD_ENABLE_MOBILE_PROVISIONING */
1951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsProvisioning = false;
1961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* The Url passed as object parameter in CMD_ENABLE_MOBILE_PROVISIONING */
1981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private String mProvisioningUrl = null;
1991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Intent for the provisioning apn alarm */
2011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_PROVISIONING_APN_ALARM =
2021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "com.android.internal.telephony.provisioning_apn_alarm";
2031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Tag for tracking stale alarms */
2051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String PROVISIONING_APN_ALARM_TAG_EXTRA = "provisioning.apn.alarm.tag";
2061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Debug property for overriding the PROVISIONING_APN_ALARM_DELAY_IN_MS */
2081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String DEBUG_PROV_APN_ALARM = "persist.debug.prov_apn_alarm";
2091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Default for the provisioning apn alarm timeout */
2111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int PROVISIONING_APN_ALARM_DELAY_IN_MS_DEFAULT = 1000 * 60 * 15;
2121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* The provision apn alarm intent used to disable the provisioning apn */
2141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private PendingIntent mProvisioningApnAlarmIntent = null;
2151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Used to track stale provisioning apn alarms */
2171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mProvisioningApnAlarmTag = (int) SystemClock.elapsedRealtime();
2181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private AsyncChannel mReplyAc = new AsyncChannel();
2201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
221d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen    private final LocalLog mDataRoamingLeakageLog = new LocalLog(50);
222d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen
2231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver () {
2241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
2251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void onReceive(Context context, Intent intent) {
2261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            String action = intent.getAction();
227c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu
2281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (action.equals(Intent.ACTION_SCREEN_ON)) {
229baecdb610b30a5d4b35345f8fc63fcbc2133c149Jack Yu                // TODO: Evaluate hooking this up with DeviceStateMonitor
230c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("screen on");
2311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mIsScreenOn = true;
2321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                stopNetStatPoll();
2331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                startNetStatPoll();
2341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartDataStallAlarm();
2351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
236c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("screen off");
2371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mIsScreenOn = false;
2381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                stopNetStatPoll();
2391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                startNetStatPoll();
2401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartDataStallAlarm();
2411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.startsWith(INTENT_RECONNECT_ALARM)) {
2421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("Reconnect alarm. Previous state was " + mState);
2431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onActionIntentReconnectAlarm(intent);
2441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(INTENT_DATA_STALL_ALARM)) {
245c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("Data stall alarm");
2461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onActionIntentDataStallAlarm(intent);
2471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(INTENT_PROVISIONING_APN_ALARM)) {
248c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("Provisioning apn alarm");
2491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onActionIntentProvisioningApnAlarm(intent);
25021e6af8d6197a071d025733fffeffc157d0085bcfionaxu            } else if (action.equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
25121e6af8d6197a071d025733fffeffc157d0085bcfionaxu                if (mIccRecords.get() != null && mIccRecords.get().getRecordsLoaded()) {
25221e6af8d6197a071d025733fffeffc157d0085bcfionaxu                    setDefaultDataRoamingEnabled();
25321e6af8d6197a071d025733fffeffc157d0085bcfionaxu                }
254c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            } else {
255c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("onReceive: Unknown action=" + action);
2561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
2571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
2581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    };
2591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final Runnable mPollNetStat = new Runnable() {
2611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
2621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void run() {
2631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            updateDataActivity();
2641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mIsScreenOn) {
2661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mNetStatPollPeriod = Settings.Global.getInt(mResolver,
2671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.PDP_WATCHDOG_POLL_INTERVAL_MS, POLL_NETSTAT_MILLIS);
2681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
2691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mNetStatPollPeriod = Settings.Global.getInt(mResolver,
2701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS,
2711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        POLL_NETSTAT_SCREEN_OFF_MILLIS);
2721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
2731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mNetStatPollEnabled) {
2751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mDataConnectionTracker.postDelayed(this, mNetStatPollPeriod);
2761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
2771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
2781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    };
2791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private SubscriptionManager mSubscriptionManager;
2811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final OnSubscriptionsChangedListener mOnSubscriptionsChangedListener =
2821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new OnSubscriptionsChangedListener() {
2831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                public final AtomicInteger mPreviousSubId =
2841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        new AtomicInteger(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
2851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                /**
2871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                 * Callback invoked when there is any change to any SubscriptionInfo. Typically
2881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                 * this method invokes {@link SubscriptionManager#getActiveSubscriptionInfoList}
2891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                 */
2901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                @Override
2911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                public void onSubscriptionsChanged() {
2921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (DBG) log("SubscriptionListener.onSubscriptionInfoChanged");
2931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // Set the network type, in case the radio does not restore it.
2941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    int subId = mPhone.getSubId();
2951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (SubscriptionManager.isValidSubscriptionId(subId)) {
296f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                        registerSettingsObserver();
2971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
2981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mPreviousSubId.getAndSet(subId) != subId &&
2991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            SubscriptionManager.isValidSubscriptionId(subId)) {
3001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onRecordsLoadedOrSubIdChanged();
3011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
3021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
3031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            };
3041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
305f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    private final SettingsObserver mSettingsObserver;
306f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
307f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    private void registerSettingsObserver() {
308f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.unobserve();
309f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        String simSuffix = "";
310f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu        if (TelephonyManager.getDefault().getSimCount() > 1) {
311f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            simSuffix = Integer.toString(mPhone.getSubId());
312f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        }
313f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu
314f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.observe(
315f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                Settings.Global.getUriFor(Settings.Global.DATA_ROAMING + simSuffix),
316d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                DctConstants.EVENT_ROAMING_SETTING_CHANGE);
317f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.observe(
318f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
319f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE);
320f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.observe(
321f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED),
322f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE);
323f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    }
3241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
3261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Maintain the sum of transmit and receive packets.
3271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     *
3281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * The packet counts are initialized and reset to -1 and
3291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * remain -1 until they can be updated.
3301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
3311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public static class TxRxSum {
3321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public long txPkts;
3331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public long rxPkts;
3341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public TxRxSum() {
3361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            reset();
3371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public TxRxSum(long txPkts, long rxPkts) {
3401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.txPkts = txPkts;
3411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.rxPkts = rxPkts;
3421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public TxRxSum(TxRxSum sum) {
3451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            txPkts = sum.txPkts;
3461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            rxPkts = sum.rxPkts;
3471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void reset() {
3501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            txPkts = -1;
3511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            rxPkts = -1;
3521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
3551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public String toString() {
3561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return "{txSum=" + txPkts + " rxSum=" + rxPkts + "}";
3571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void updateTxRxSum() {
3601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.txPkts = TrafficStats.getMobileTcpTxPackets();
3611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.rxPkts = TrafficStats.getMobileTcpRxPackets();
3621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
3641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onActionIntentReconnectAlarm(Intent intent) {
366e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        Message msg = obtainMessage(DctConstants.EVENT_DATA_RECONNECT);
367e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        msg.setData(intent.getExtras());
368e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        sendMessage(msg);
369e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu    }
370e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu
371e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu    private void onDataReconnect(Bundle bundle) {
372e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        String reason = bundle.getString(INTENT_RECONNECT_ALARM_EXTRA_REASON);
373e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        String apnType = bundle.getString(INTENT_RECONNECT_ALARM_EXTRA_TYPE);
3741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int phoneSubId = mPhone.getSubId();
376e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        int currSubId = bundle.getInt(PhoneConstants.SUBSCRIPTION_KEY,
3771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
378e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        log("onDataReconnect: currSubId = " + currSubId + " phoneSubId=" + phoneSubId);
3791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // Stop reconnect if not current subId is not correct.
3811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // FIXME STOPSHIP - phoneSubId is coming up as -1 way after boot and failing this?
3821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (!SubscriptionManager.isValidSubscriptionId(currSubId) || (currSubId != phoneSubId)) {
3831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("receive ReconnectAlarm but subId incorrect, ignore");
3841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return;
3851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnContext apnContext = mApnContexts.get(apnType);
3881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
390e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu            log("onDataReconnect: mState=" + mState + " reason=" + reason + " apnType=" + apnType
391e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                    + " apnContext=" + apnContext + " mDataConnectionAsyncChannels="
392e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                    + mDataConnectionAcHashMap);
3931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if ((apnContext != null) && (apnContext.isEnabled())) {
3961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            apnContext.setReason(reason);
3971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            DctConstants.State apnContextState = apnContext.getState();
3981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
399e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                log("onDataReconnect: apnContext state=" + apnContextState);
4001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
4011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if ((apnContextState == DctConstants.State.FAILED)
4021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    || (apnContextState == DctConstants.State.IDLE)) {
4031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
404e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                    log("onDataReconnect: state is FAILED|IDLE, disassociate");
4051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
4061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DcAsyncChannel dcac = apnContext.getDcAc();
4071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (dcac != null) {
4081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (DBG) {
409e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                        log("onDataReconnect: tearDown apnContext=" + apnContext);
4101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
4111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    dcac.tearDown(apnContext, "", null);
4121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
4131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                apnContext.setDataConnectionAc(null);
4141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                apnContext.setState(DctConstants.State.IDLE);
4151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
416e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                if (DBG) log("onDataReconnect: keep associated");
4171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
4181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // TODO: IF already associated should we send the EVENT_TRY_SETUP_DATA???
4191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            sendMessage(obtainMessage(DctConstants.EVENT_TRY_SETUP_DATA, apnContext));
4201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            apnContext.setReconnectIntent(null);
4221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
4241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onActionIntentDataStallAlarm(Intent intent) {
4261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("onActionIntentDataStallAlarm: action=" + intent.getAction());
4271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_DATA_STALL_ALARM,
4281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                intent.getAction());
4291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = intent.getIntExtra(DATA_STALL_ALARM_TAG_EXTRA, 0);
4301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
4311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
4321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final ConnectivityManager mCm;
434c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
435b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla    /**
436a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * List of messages that are waiting to be posted, when data call disconnect
437a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * is complete
438a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
439a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ArrayList<Message> mDisconnectAllCompleteMsgList = new ArrayList<Message>();
440a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
441a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private RegistrantList mAllDataDisconnectedRegistrants = new RegistrantList();
442a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // member variables
4441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final Phone mPhone;
4451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final UiccController mUiccController;
4461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
4471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DctConstants.Activity mActivity = DctConstants.Activity.NONE;
4481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DctConstants.State mState = DctConstants.State.IDLE;
4491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final Handler mDataConnectionTracker;
4501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private long mTxPkts;
4521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private long mRxPkts;
4531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mNetStatPollPeriod;
4541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mNetStatPollEnabled = false;
4551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private TxRxSum mDataStallTxRxSum = new TxRxSum(0, 0);
4571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Used to track stale data stall alarms.
4581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mDataStallAlarmTag = (int) SystemClock.elapsedRealtime();
4591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // The current data stall alarm intent
4601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private PendingIntent mDataStallAlarmIntent = null;
4611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Number of packets sent since the last received packet
4621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private long mSentSinceLastRecv;
4631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Controls when a simple recovery attempt it to be tried
4641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mNoRecvPollCount = 0;
4650e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    // Reference counter for enabling fail fast
4661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static int sEnableFailFastRefCounter = 0;
4671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // True if data stall detection is enabled
4681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private volatile boolean mDataStallDetectionEnabled = true;
4691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private volatile boolean mFailFast = false;
4711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // True when in voice call
4731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mInVoiceCall = false;
4741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Intent sent when the reconnect alarm fires. */
4761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private PendingIntent mReconnectIntent = null;
4771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // When false we will not auto attach and manually attaching is required.
4791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mAutoAttachOnCreationConfig = false;
4801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private AtomicBoolean mAutoAttachOnCreation = new AtomicBoolean(false);
4811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // State of screen
4831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // (TODO: Reconsider tying directly to screen, maybe this is
4841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    //        really a lower power mode")
4851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsScreenOn = true;
4861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Indicates if we found mvno-specific APNs in the full APN list.
4881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // used to determine if we can accept mno-specific APN for tethering.
4891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mMvnoMatched = false;
4901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Allows the generation of unique Id's for DataConnection objects */
4921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private AtomicInteger mUniqueIdGenerator = new AtomicInteger(0);
4931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** The data connections. */
4951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private HashMap<Integer, DataConnection> mDataConnections =
4961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new HashMap<Integer, DataConnection>();
4971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** The data connection async channels */
4991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private HashMap<Integer, DcAsyncChannel> mDataConnectionAcHashMap =
5001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new HashMap<Integer, DcAsyncChannel>();
5011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Convert an ApnType string to Id (TODO: Use "enumeration" instead of String for ApnType) */
5031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private HashMap<String, Integer> mApnToDataConnectionId = new HashMap<String, Integer>();
5041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Phone.APN_TYPE_* ===> ApnContext */
5061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final ConcurrentHashMap<String, ApnContext> mApnContexts =
5071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new ConcurrentHashMap<String, ApnContext>();
5081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
509af5593594070f825032be46dced573cd195956e1Robert Greenwalt    private final SparseArray<ApnContext> mApnContextsById = new SparseArray<ApnContext>();
510af5593594070f825032be46dced573cd195956e1Robert Greenwalt
5111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mDisconnectPendingCount = 0;
512a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
5134c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu    /** Indicate if metered APNs are disabled.
5144c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu     *  set to block all the metered APNs from continuously sending requests, which causes
5154c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu     *  undesired network load */
5164c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu    private boolean mMeteredApnDisabled = false;
51768f4f4a0bc8d4060b5775e7a24a97ea5b485989efionaxu
518a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
5194b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * int to remember whether has setDataProfiles and with roaming or not.
5204b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * 0: default, has never set data profile
5214b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * 1: has set data profile with home protocol
5224b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * 2: has set data profile with roaming protocol
5234b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * This is not needed once RIL command is updated to support both home and roaming protocol.
5244b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     */
5254b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu    private int mSetDataProfileStatus = 0;
5264b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu
5274b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu    /**
528cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Handles changes to the APN db.
529b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla     */
530cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private class ApnChangeObserver extends ContentObserver {
531cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public ApnChangeObserver () {
532cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            super(mDataConnectionTracker);
533cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
534c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
535cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
536cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public void onChange(boolean selfChange) {
537cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            sendMessage(obtainMessage(DctConstants.EVENT_APN_CHANGED));
538cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
539cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
540c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
541cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Instance Variables
542c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
543cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean mReregisterOnReconnectFailure = false;
544c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
545c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
546cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Constants
547c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
548ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    // Used by puppetmaster/*/radio_stress.py
549ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private static final String PUPPET_MASTER_RADIO_STRESS_TEST = "gsm.defaultpdpcontext.active";
550c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
551ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private static final int POLL_PDP_MILLIS = 5 * 1000;
552c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
5532b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen    private static final int PROVISIONING_SPINNER_TIMEOUT_MILLIS = 120 * 1000;
5542b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen
5556bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville    static final Uri PREFERAPN_NO_UPDATE_URI_USING_SUBID =
5566bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville                        Uri.parse("content://telephony/carriers/preferapn_no_update/subId/");
557cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final String APN_ID = "apn_id";
558cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
559ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private boolean mCanSetPreferApn = false;
560c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
561187a39f896f88eb6c5e4306d9595546654825976Wink Saville    private AtomicBoolean mAttached = new AtomicBoolean(false);
562187a39f896f88eb6c5e4306d9595546654825976Wink Saville
563cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** Watches for changes to the APN db. */
564cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ApnChangeObserver mApnObserver;
565cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
566b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private final String mProvisionActionName;
567b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private BroadcastReceiver mProvisionBroadcastReceiver;
5682b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen    private ProgressDialog mProvisioningSpinner;
569b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
57071f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu    private final DataServiceManager mDataServiceManager;
57171f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu
57271f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu    private final int mTransportType;
573a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
574cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Constructor
57571f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu    public DcTracker(Phone phone, int transportType) {
5761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        super();
5771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone = phone;
5781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("DCT.constructor");
57971f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        mTransportType = transportType;
58071f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        mDataServiceManager = new DataServiceManager(phone, transportType);
5811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mResolver = mPhone.getContext().getContentResolver();
5831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mUiccController = UiccController.getInstance();
5841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mUiccController.registerForIccChanged(this, DctConstants.EVENT_ICC_CHANGED, null);
5851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mAlarmManager =
5861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
5871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mCm = (ConnectivityManager) mPhone.getContext().getSystemService(
5881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Context.CONNECTIVITY_SERVICE);
5891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        IntentFilter filter = new IntentFilter();
5921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(Intent.ACTION_SCREEN_ON);
5931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(Intent.ACTION_SCREEN_OFF);
5941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(INTENT_DATA_STALL_ALARM);
5951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(INTENT_PROVISIONING_APN_ALARM);
59621e6af8d6197a071d025733fffeffc157d0085bcfionaxu        filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
597985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen
598985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen        mDataEnabledSettings = new DataEnabledSettings(phone);
5991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
6011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
6031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mAutoAttachOnCreation.set(sp.getBoolean(Phone.DATA_DISABLED_ON_BOOT_KEY, false));
6041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mSubscriptionManager = SubscriptionManager.from(mPhone.getContext());
6061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
6071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        HandlerThread dcHandlerThread = new HandlerThread("DcHandlerThread");
6091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        dcHandlerThread.start();
6101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Handler dcHandler = new Handler(dcHandlerThread.getLooper());
61171f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        mDcc = DcController.makeDcc(mPhone, this, mDataServiceManager, dcHandler);
6121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcTesterFailBringUpAll = new DcTesterFailBringUpAll(mPhone, dcHandler);
613cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
614cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mDataConnectionTracker = this;
615c374098c17a81f73f51e9d7df99eba574882949bYifan Bai        registerForAllEvents();
616a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        update();
617cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mApnObserver = new ApnChangeObserver();
6181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        phone.getContext().getContentResolver().registerContentObserver(
619cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                Telephony.Carriers.CONTENT_URI, true, mApnObserver);
620cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
621d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        initApnContexts();
622d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
623d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        for (ApnContext apnContext : mApnContexts.values()) {
624d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            // Register the reconnect and restart actions.
6251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            filter = new IntentFilter();
626d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            filter.addAction(INTENT_RECONNECT_ALARM + '.' + apnContext.getApnType());
627d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
628d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        }
629d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
63076f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Add Emergency APN to APN setting list by default to support EPDN in sim absent cases
63176f43316a5a6082d601bffd4b6898d0bd81e11fcram        initEmergencyApnSetting();
63276f43316a5a6082d601bffd4b6898d0bd81e11fcram        addEmergencyApnSetting();
633b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
6341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisionActionName = "com.android.internal.telephony.PROVISION" + phone.getPhoneId();
635f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
636f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver = new SettingsObserver(mPhone.getContext(), this);
637f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        registerSettingsObserver();
6381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
6391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
640af5593594070f825032be46dced573cd195956e1Robert Greenwalt    @VisibleForTesting
641af5593594070f825032be46dced573cd195956e1Robert Greenwalt    public DcTracker() {
642af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mAlarmManager = null;
643af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mCm = null;
644af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mPhone = null;
645af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mUiccController = null;
646af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mDataConnectionTracker = null;
647af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mProvisionActionName = null;
648f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver = new SettingsObserver(null, this);
649985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen        mDataEnabledSettings = null;
65071f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        mTransportType = 0;
65171f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        mDataServiceManager = null;
652af5593594070f825032be46dced573cd195956e1Robert Greenwalt    }
653af5593594070f825032be46dced573cd195956e1Robert Greenwalt
6541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void registerServiceStateTrackerEvents() {
6551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataConnectionAttached(this,
6561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null);
6571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataConnectionDetached(this,
6581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_DATA_CONNECTION_DETACHED, null);
6591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataRoamingOn(this,
6601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_ROAMING_ON, null);
6611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataRoamingOff(this,
6620d6ff7958dac61b9e2d689267c34ddfa0c666d9dfionaxu                DctConstants.EVENT_ROAMING_OFF, null, true);
6631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForPsRestrictedEnabled(this,
6641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_PS_RESTRICT_ENABLED, null);
6651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForPsRestrictedDisabled(this,
6661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_PS_RESTRICT_DISABLED, null);
6671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(this,
6681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_DATA_RAT_CHANGED, null);
669cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
670c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
6711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void unregisterServiceStateTrackerEvents() {
6721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataConnectionAttached(this);
6731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataConnectionDetached(this);
6741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataRoamingOn(this);
6751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataRoamingOff(this);
6761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForPsRestrictedEnabled(this);
6771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForPsRestrictedDisabled(this);
6781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged(this);
6791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
6801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void registerForAllEvents() {
68271f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        if (mTransportType == TransportType.WWAN) {
68371f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu            mPhone.mCi.registerForAvailable(this, DctConstants.EVENT_RADIO_AVAILABLE, null);
68471f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu            mPhone.mCi.registerForOffOrNotAvailable(this,
68571f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
68671f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu            mPhone.mCi.registerForPcoData(this, DctConstants.EVENT_PCO_DATA_RECEIVED, null);
68771f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        }
68871f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu
6890710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // Note, this is fragile - the Phone is now presenting a merged picture
6900710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // of PS (volte) & CS and by diving into its internals you're just seeing
6910710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // the CS data.  This works well for the purposes this is currently used for
6920710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // but that may not always be the case.  Should probably be redesigned to
6930710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // accurately reflect what we're really interested in (registerForCSVoiceCallEnded).
6941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getCallTracker().registerForVoiceCallEnded(this,
6951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_VOICE_CALL_ENDED, null);
6961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getCallTracker().registerForVoiceCallStarted(this,
6971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_VOICE_CALL_STARTED, null);
6981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        registerServiceStateTrackerEvents();
6992e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        mPhone.mCi.registerForPcoData(this, DctConstants.EVENT_PCO_DATA_RECEIVED, null);
7006a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu        mPhone.getCarrierActionAgent().registerForCarrierAction(
7016a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu                CarrierActionAgent.CARRIER_ACTION_SET_METERED_APNS_ENABLED, this,
7026a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu                DctConstants.EVENT_SET_CARRIER_DATA_ENABLED, null, false);
70371f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        mDataServiceManager.registerForServiceBindingChanged(this,
70471f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                DctConstants.EVENT_DATA_SERVICE_BINDING_CHANGED, null);
705a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
7061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
707cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void dispose() {
7081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("DCT.dispose");
7094dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt
710b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        if (mProvisionBroadcastReceiver != null) {
711b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            mPhone.getContext().unregisterReceiver(mProvisionBroadcastReceiver);
712b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            mProvisionBroadcastReceiver = null;
713b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
7142b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        if (mProvisioningSpinner != null) {
7152b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.dismiss();
7162b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner = null;
7172b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        }
718b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
719cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, null);
720cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
7211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
7221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            dcac.disconnect();
7231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
7241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDataConnectionAcHashMap.clear();
7251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mIsDisposed = true;
7261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getContext().unregisterReceiver(mIntentReceiver);
7271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mUiccController.unregisterForIccChanged(this);
728f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.unobserve();
729f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
7301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mSubscriptionManager
7311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                .removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
7321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcc.dispose();
7331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcTesterFailBringUpAll.dispose();
734cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
735a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getContext().getContentResolver().unregisterContentObserver(mApnObserver);
736a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mApnContexts.clear();
737af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mApnContextsById.clear();
738a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPrioritySortedApnContexts.clear();
739c374098c17a81f73f51e9d7df99eba574882949bYifan Bai        unregisterForAllEvents();
740a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
741a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        destroyDataConnections();
742a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
7431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void unregisterForAllEvents() {
745a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         //Unregister for all events
74671f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        if (mTransportType == TransportType.WWAN) {
74771f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu            mPhone.mCi.unregisterForAvailable(this);
74871f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu            mPhone.mCi.unregisterForOffOrNotAvailable(this);
74971f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu            mPhone.mCi.unregisterForPcoData(this);
75071f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        }
75171f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu
752cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
753a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (r != null) {
754a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            r.unregisterForRecordsLoaded(this);
755a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mIccRecords.set(null);
756a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
757cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getCallTracker().unregisterForVoiceCallEnded(this);
758cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getCallTracker().unregisterForVoiceCallStarted(this);
7591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        unregisterServiceStateTrackerEvents();
7602e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        mPhone.mCi.unregisterForPcoData(this);
7616a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu        mPhone.getCarrierActionAgent().unregisterForCarrierAction(this,
7626a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu                CarrierActionAgent.CARRIER_ACTION_SET_METERED_APNS_ENABLED);
76371f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        mDataServiceManager.unregisterForServiceBindingChanged(this);
7641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
7651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
7671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Modify {@link android.provider.Settings.Global#MOBILE_DATA} value.
7681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
769a64092befe003884c4c8951438ab311ce8f92824Malcolm Chen    public void setUserDataEnabled(boolean enable) {
7701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.CMD_SET_USER_DATA_ENABLE);
7711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = enable ? 1 : 0;
7721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("setDataEnabled: sendMessage: enable=" + enable);
7731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
7741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
7751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetUserDataEnabled(boolean enabled) {
77712161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen        if (mDataEnabledSettings.isUserDataEnabled() != enabled) {
77812161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen            mDataEnabledSettings.setUserDataEnabled(enabled);
77912161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen            if (!getDataRoamingEnabled() && mPhone.getServiceState().getDataRoaming()) {
7801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (enabled) {
78112161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen                    notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
7821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
78312161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen                    notifyOffApnsOfAvailability(Phone.REASON_DATA_DISABLED);
7841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
7851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
78612161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen
78712161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen            mPhone.notifyUserMobileDataStateChanged(enabled);
78812161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen
78912161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen            // TODO: We should register for DataEnabledSetting's data enabled/disabled event and
79012161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen            // handle the rest from there.
79112161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen            if (enabled) {
79212161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen                reevaluateDataConnections();
79312161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen                onTrySetupData(Phone.REASON_DATA_ENABLED);
79412161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen            } else {
79512161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen                onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);
79612161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen            }
7971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
7981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
7991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8005292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt    /**
801120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * Reevaluate existing data connections when conditions change.
802120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     *
803120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * For example, handle reverting restricted networks back to unrestricted. If we're changing
804120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * user data to enabled and this makes data truly enabled (not disabled by other factors) we
805120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * need to tear down any metered apn type that was enabled anyway by a privileged request.
806120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * This allows us to reconnect to it in an unrestricted way.
807120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     *
808120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * Or when we brought up a unmetered data connection while data is off, we only limit this
809120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * data connection for unmetered use only. When data is turned back on, we need to tear that
810120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * down so a full capable data connection can be re-established.
8115292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt     */
812120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu    private void reevaluateDataConnections() {
813120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        if (mDataEnabledSettings.isDataEnabled()) {
8145292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt            for (ApnContext apnContext : mApnContexts.values()) {
815120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                if (apnContext.isConnectedOrConnecting()) {
816120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    final DcAsyncChannel dcac = apnContext.getDcAc();
817120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    if (dcac != null) {
818120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                        final NetworkCapabilities netCaps = dcac.getNetworkCapabilitiesSync();
819120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                        if (netCaps != null && !netCaps.hasCapability(NetworkCapabilities
820ee00c053e0cbbbdb22737c923b1a214e10453646Jack Yu                                .NET_CAPABILITY_NOT_RESTRICTED) && !netCaps.hasCapability(
821ee00c053e0cbbbdb22737c923b1a214e10453646Jack Yu                                NetworkCapabilities.NET_CAPABILITY_NOT_METERED)) {
822120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            if (DBG) {
823ee00c053e0cbbbdb22737c923b1a214e10453646Jack Yu                                log("Tearing down restricted metered net:" + apnContext);
824120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            }
825ee00c053e0cbbbdb22737c923b1a214e10453646Jack Yu                            // Tearing down the restricted metered data call when
826120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // conditions change. This will allow reestablishing a new unrestricted
827120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // data connection.
828120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            apnContext.setReason(Phone.REASON_DATA_ENABLED);
829120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            cleanUpConnection(true, apnContext);
83050734be549285702de00295778b8c2a4360215a0Jack Yu                        } else if (apnContext.getApnSetting().isMetered(mPhone)
831120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                                && (netCaps != null && netCaps.hasCapability(
832120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                                        NetworkCapabilities.NET_CAPABILITY_NOT_METERED))) {
833120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            if (DBG) {
834120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                                log("Tearing down unmetered net:" + apnContext);
835120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            }
836120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // The APN settings is metered, but the data was still marked as
837120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // unmetered data, must be the unmetered data connection brought up when
838120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // data is off. We need to tear that down when data is enabled again.
839120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // This will allow reestablishing a new full capability data connection.
840120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            apnContext.setReason(Phone.REASON_DATA_ENABLED);
841120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            cleanUpConnection(true, apnContext);
84276c5a9479d312139740dcaf7644172f2beb2f7e0Robert Greenwalt                        }
84376c5a9479d312139740dcaf7644172f2beb2f7e0Robert Greenwalt                    }
8445292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt                }
8455292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt            }
8465292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt        }
8475292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt    }
8485292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt
849f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    private void onDeviceProvisionedChange() {
850985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen        if (isDataEnabled()) {
851120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu            reevaluateDataConnections();
852f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            onTrySetupData(Phone.REASON_DATA_ENABLED);
853f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        } else {
854f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);
855f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        }
856f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    }
8571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public long getSubId() {
8601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mPhone.getSubId();
8611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
8621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public DctConstants.Activity getActivity() {
8641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mActivity;
8651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
8661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void setActivity(DctConstants.Activity activity) {
8681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("setActivity = " + activity);
8691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mActivity = activity;
8701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.notifyDataActivity();
8711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
8721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
873af5593594070f825032be46dced573cd195956e1Robert Greenwalt    public void requestNetwork(NetworkRequest networkRequest, LocalLog log) {
874af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final int apnId = ApnContext.apnIdForNetworkRequest(networkRequest);
875af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final ApnContext apnContext = mApnContextsById.get(apnId);
876af5593594070f825032be46dced573cd195956e1Robert Greenwalt        log.log("DcTracker.requestNetwork for " + networkRequest + " found " + apnContext);
877692640f429efa8e292c6261472b2c682e1079f8eRobert Greenwalt        if (apnContext != null) apnContext.requestNetwork(networkRequest, log);
878af5593594070f825032be46dced573cd195956e1Robert Greenwalt    }
879af5593594070f825032be46dced573cd195956e1Robert Greenwalt
880af5593594070f825032be46dced573cd195956e1Robert Greenwalt    public void releaseNetwork(NetworkRequest networkRequest, LocalLog log) {
881af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final int apnId = ApnContext.apnIdForNetworkRequest(networkRequest);
882af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final ApnContext apnContext = mApnContextsById.get(apnId);
883af5593594070f825032be46dced573cd195956e1Robert Greenwalt        log.log("DcTracker.releaseNetwork for " + networkRequest + " found " + apnContext);
884692640f429efa8e292c6261472b2c682e1079f8eRobert Greenwalt        if (apnContext != null) apnContext.releaseNetwork(networkRequest, log);
885af5593594070f825032be46dced573cd195956e1Robert Greenwalt    }
886af5593594070f825032be46dced573cd195956e1Robert Greenwalt
887bda761320929f714951c328bfec6a51a1978db97Wink Saville    public boolean isApnSupported(String name) {
88891bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal        if (name == null) {
88991bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal            loge("isApnSupported: name=null");
89091bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal            return false;
89191bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal        }
892bda761320929f714951c328bfec6a51a1978db97Wink Saville        ApnContext apnContext = mApnContexts.get(name);
893bda761320929f714951c328bfec6a51a1978db97Wink Saville        if (apnContext == null) {
894bda761320929f714951c328bfec6a51a1978db97Wink Saville            loge("Request for unsupported mobile name: " + name);
895bda761320929f714951c328bfec6a51a1978db97Wink Saville            return false;
896071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
897bda761320929f714951c328bfec6a51a1978db97Wink Saville        return true;
898bda761320929f714951c328bfec6a51a1978db97Wink Saville    }
899071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
900bda761320929f714951c328bfec6a51a1978db97Wink Saville    public int getApnPriority(String name) {
901071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        ApnContext apnContext = mApnContexts.get(name);
902071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (apnContext == null) {
903bda761320929f714951c328bfec6a51a1978db97Wink Saville            loge("Request for unsupported mobile name: " + name);
904071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
905bda761320929f714951c328bfec6a51a1978db97Wink Saville        return apnContext.priority;
906071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt    }
907071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
908b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    // Turn telephony radio on or off.
909b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private void setRadio(boolean on) {
910b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        final ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
911b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        try {
912b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            phone.setRadio(on);
913b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        } catch (Exception e) {
914b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            // Ignore.
915b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
916b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    }
917b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
918b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    // Class to handle Intent dispatched with user selects the "Sign-in to network"
919b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    // notification.
920b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private class ProvisionNotificationBroadcastReceiver extends BroadcastReceiver {
9212b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        private final String mNetworkOperator;
922b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        // Mobile provisioning URL.  Valid while provisioning notification is up.
923b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        // Set prior to notification being posted as URL contains ICCID which
924b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        // disappears when radio is off (which is the case when notification is up).
925b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        private final String mProvisionUrl;
926b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
9272b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        public ProvisionNotificationBroadcastReceiver(String provisionUrl, String networkOperator) {
9282b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mNetworkOperator = networkOperator;
929b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            mProvisionUrl = provisionUrl;
930b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
931b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
932b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        private void setEnableFailFastMobileData(int enabled) {
9336395443719ec3ee0257085945e753d02f603886bRobert Greenwalt            sendMessage(obtainMessage(DctConstants.CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA, enabled, 0));
934b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
935b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
936b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        private void enableMobileProvisioning() {
937b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            final Message msg = obtainMessage(DctConstants.CMD_ENABLE_MOBILE_PROVISIONING);
938b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            msg.setData(Bundle.forPair(DctConstants.PROVISIONING_URL_KEY, mProvisionUrl));
939b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            sendMessage(msg);
940b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
941b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
942b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        @Override
943b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        public void onReceive(Context context, Intent intent) {
9442b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // Turning back on the radio can take time on the order of a minute, so show user a
9452b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // spinner so they know something is going on.
946636fbb01fd32e23d1e9ef86497115b2c992b03daSanket Padawe            log("onReceive : ProvisionNotificationBroadcastReceiver");
9472b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner = new ProgressDialog(context);
9482b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setTitle(mNetworkOperator);
9492b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setMessage(
9502b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    // TODO: Don't borrow "Connecting..." i18n string; give Telephony a version.
9512b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    context.getText(com.android.internal.R.string.media_route_status_connecting));
9522b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setIndeterminate(true);
9532b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setCancelable(true);
9542b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // Allow non-Activity Service Context to create a View.
9552b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.getWindow().setType(
9562b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
9572b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.show();
9582b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // After timeout, hide spinner so user can at least use their device.
9592b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // TODO: Indicate to user that it is taking an unusually long time to connect?
9602b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            sendMessageDelayed(obtainMessage(DctConstants.CMD_CLEAR_PROVISIONING_SPINNER,
9612b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner), PROVISIONING_SPINNER_TIMEOUT_MILLIS);
962b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            // This code is almost identical to the old
963b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            // ConnectivityService.handleMobileProvisioningAction code.
964b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            setRadio(true);
965b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            setEnableFailFastMobileData(DctConstants.ENABLED);
966b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            enableMobileProvisioning();
967b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
968b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    }
969b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
970cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
971cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void finalize() {
9727e9240253edb59e0aa657de434faa1ccdf17a742Amit Mahajan        if(DBG && mPhone != null) log("finalize");
973cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
974cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
9754a9b3afeb2ec4d573eca335a3706392ecf9f281eWink Saville    private ApnContext addApnContext(String type, NetworkConfig networkConfig) {
9760e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        ApnContext apnContext = new ApnContext(mPhone, type, LOG_TAG, networkConfig, this);
977cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mApnContexts.put(type, apnContext);
978af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mApnContextsById.put(ApnContext.apnIdForApnName(type), apnContext);
9793fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        mPrioritySortedApnContexts.add(apnContext);
980bce3d2575122929bb27ec8a37d56e96da39a3ca2Robert Greenwalt        return apnContext;
981cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
982c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
9831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void initApnContexts() {
984d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        log("initApnContexts: E");
985d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        // Load device network attributes from resources
986d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        String[] networkConfigStrings = mPhone.getContext().getResources().getStringArray(
987d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                com.android.internal.R.array.networkAttributes);
988d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        for (String networkConfigString : networkConfigStrings) {
989d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            NetworkConfig networkConfig = new NetworkConfig(networkConfigString);
990d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            ApnContext apnContext = null;
991d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
992d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            switch (networkConfig.type) {
993d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE:
994d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_DEFAULT, networkConfig);
995d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
996d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_MMS:
997d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_MMS, networkConfig);
998d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
999d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_SUPL:
1000d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_SUPL, networkConfig);
1001d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1002d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_DUN:
1003d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_DUN, networkConfig);
1004d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1005d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_HIPRI:
1006d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_HIPRI, networkConfig);
1007d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1008d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_FOTA:
1009d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_FOTA, networkConfig);
1010d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1011d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_IMS:
1012d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_IMS, networkConfig);
1013d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1014d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_CBS:
1015d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_CBS, networkConfig);
1016d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1017d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_IA:
1018d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_IA, networkConfig);
1019d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1020cf5205f70eb1eac497164124187a088ecb03fff5Ram            case ConnectivityManager.TYPE_MOBILE_EMERGENCY:
1021cf5205f70eb1eac497164124187a088ecb03fff5Ram                apnContext = addApnContext(PhoneConstants.APN_TYPE_EMERGENCY, networkConfig);
1022cf5205f70eb1eac497164124187a088ecb03fff5Ram                break;
1023d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            default:
1024d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                log("initApnContexts: skipping unknown type=" + networkConfig.type);
1025d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                continue;
1026d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            }
1027d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            log("initApnContexts: apnContext=" + apnContext);
1028d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        }
1029092e6bd60f1a4a3a55fb73ad0efca1122b8e15e2Jack Yu
1030092e6bd60f1a4a3a55fb73ad0efca1122b8e15e2Jack Yu        if (VDBG) log("initApnContexts: X mApnContexts=" + mApnContexts);
1031d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt    }
1032d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
1033cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public LinkProperties getLinkProperties(String apnType) {
1034cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1035cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
1036454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = apnContext.getDcAc();
1037cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac != null) {
1038cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("return link properites for " + apnType);
1039cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return dcac.getLinkPropertiesSync();
1040cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1041cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1042cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("return new LinkProperties");
1043cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return new LinkProperties();
1044cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1045cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1046608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt    public NetworkCapabilities getNetworkCapabilities(String apnType) {
1047608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        ApnContext apnContext = mApnContexts.get(apnType);
1048608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        if (apnContext!=null) {
1049608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            DcAsyncChannel dataConnectionAc = apnContext.getDcAc();
1050608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            if (dataConnectionAc != null) {
1051608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                if (DBG) {
1052608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                    log("get active pdp is not null, return NetworkCapabilities for " + apnType);
1053608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                }
1054608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                return dataConnectionAc.getNetworkCapabilitiesSync();
1055608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            }
1056608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        }
1057608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        if (DBG) log("return new NetworkCapabilities");
1058608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        return new NetworkCapabilities();
1059608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt    }
1060cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1061cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return all active apn types
1062cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public String[] getActiveApnTypes() {
1063cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("get all active apn types");
1064cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ArrayList<String> result = new ArrayList<String>();
1065cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1066cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1067187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (mAttached.get() && apnContext.isReady()) {
1068cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                result.add(apnContext.getApnType());
1069cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
1070cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1071c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1072cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result.toArray(new String[0]);
1073cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1074cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1075cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return active apn of specific apn type
1076cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public String getActiveApnString(String apnType) {
1077ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (VDBG) log( "get active apn string for type:" + apnType);
1078cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1079cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
1080cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ApnSetting apnSetting = apnContext.getApnSetting();
1081cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnSetting != null) {
1082cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return apnSetting.apn;
1083cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1084cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1085cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
1086cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1087cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
10880eff7e1722a2478619221572e0eba6c95a30a195Pengquan Meng    /**
10890eff7e1722a2478619221572e0eba6c95a30a195Pengquan Meng     * Returns {@link DctConstants.State} based on the state of the {@link DataConnection} that
10900eff7e1722a2478619221572e0eba6c95a30a195Pengquan Meng     * contains a {@link ApnSetting} that supported the given apn type {@code anpType}.
10910eff7e1722a2478619221572e0eba6c95a30a195Pengquan Meng     *
10920eff7e1722a2478619221572e0eba6c95a30a195Pengquan Meng     * <p>
10930eff7e1722a2478619221572e0eba6c95a30a195Pengquan Meng     * Assumes there is less than one {@link ApnSetting} can support the given apn type.
10940eff7e1722a2478619221572e0eba6c95a30a195Pengquan Meng     */
1095cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public DctConstants.State getState(String apnType) {
10960eff7e1722a2478619221572e0eba6c95a30a195Pengquan Meng        for (DataConnection dc : mDataConnections.values()) {
10970eff7e1722a2478619221572e0eba6c95a30a195Pengquan Meng            ApnSetting apnSetting = dc.getApnSetting();
10980eff7e1722a2478619221572e0eba6c95a30a195Pengquan Meng            if (apnSetting != null && apnSetting.canHandleType(apnType)) {
10990eff7e1722a2478619221572e0eba6c95a30a195Pengquan Meng                if (dc.isActive()) {
11000eff7e1722a2478619221572e0eba6c95a30a195Pengquan Meng                    return DctConstants.State.CONNECTED;
11010eff7e1722a2478619221572e0eba6c95a30a195Pengquan Meng                } else if (dc.isActivating()) {
11020eff7e1722a2478619221572e0eba6c95a30a195Pengquan Meng                    return DctConstants.State.CONNECTING;
11030eff7e1722a2478619221572e0eba6c95a30a195Pengquan Meng                } else if (dc.isInactive()) {
11040eff7e1722a2478619221572e0eba6c95a30a195Pengquan Meng                    return DctConstants.State.IDLE;
11050eff7e1722a2478619221572e0eba6c95a30a195Pengquan Meng                } else if (dc.isDisconnecting()) {
11060eff7e1722a2478619221572e0eba6c95a30a195Pengquan Meng                    return DctConstants.State.DISCONNECTING;
11070eff7e1722a2478619221572e0eba6c95a30a195Pengquan Meng                }
11080eff7e1722a2478619221572e0eba6c95a30a195Pengquan Meng            }
1109c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
11100eff7e1722a2478619221572e0eba6c95a30a195Pengquan Meng
11110eff7e1722a2478619221572e0eba6c95a30a195Pengquan Meng        return DctConstants.State.IDLE;
1112cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1113c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1114c9b81a0c05128694c617fcdd67e73821895822feWink Saville    // Return if apn type is a provisioning apn.
11151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean isProvisioningApn(String apnType) {
1116c9b81a0c05128694c617fcdd67e73821895822feWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1117c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (apnContext != null) {
1118c9b81a0c05128694c617fcdd67e73821895822feWink Saville            return apnContext.isProvisioningApn();
1119c9b81a0c05128694c617fcdd67e73821895822feWink Saville        }
1120c9b81a0c05128694c617fcdd67e73821895822feWink Saville        return false;
1121c9b81a0c05128694c617fcdd67e73821895822feWink Saville    }
1122c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1123cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return state of overall
1124cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public DctConstants.State getOverallState() {
1125cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isConnecting = false;
1126cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isFailed = true; // All enabled Apns should be FAILED.
1127cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isAnyEnabled = false;
1128cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1129cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1130cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.isEnabled()) {
1131cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                isAnyEnabled = true;
1132cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                switch (apnContext.getState()) {
1133cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case CONNECTED:
1134cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case DISCONNECTING:
11351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (VDBG) log("overall state is CONNECTED");
1136cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return DctConstants.State.CONNECTED;
1137ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                case RETRYING:
1138cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case CONNECTING:
1139cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isConnecting = true;
1140cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isFailed = false;
1141cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
1142cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case IDLE:
1143cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case SCANNING:
1144cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isFailed = false;
1145cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
1146cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                default:
1147cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isAnyEnabled = true;
1148cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
1149cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1150cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1151c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1152c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1153cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (!isAnyEnabled) { // Nothing enabled. return IDLE.
11541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is IDLE");
1155cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.IDLE;
1156c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1157c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1158cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnecting) {
11591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is CONNECTING");
1160cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.CONNECTING;
1161cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (!isFailed) {
11621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is IDLE");
1163cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.IDLE;
1164cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
11651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is FAILED");
1166cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.FAILED;
1167c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1168c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1169c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1170a64092befe003884c4c8951438ab311ce8f92824Malcolm Chen    /**
1171a64092befe003884c4c8951438ab311ce8f92824Malcolm Chen     * Whether data is enabled. This does not only check isUserDataEnabled(), but also
1172a64092befe003884c4c8951438ab311ce8f92824Malcolm Chen     * others like CarrierDataEnabled and internalDataEnabled.
1173a64092befe003884c4c8951438ab311ce8f92824Malcolm Chen     */
11740b03bcd1eccc833d5cac5ecf937cf0e037375561Jack Yu    @VisibleForTesting
1175120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu    public boolean isDataEnabled() {
1176120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        return mDataEnabledSettings.isDataEnabled();
1177a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1178a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1179cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //****** Called from ServiceStateTracker
1180c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1181cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Invoked when ServiceStateTracker observes a transition from GPRS
1182cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * attach to detach.
1183c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
11841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataConnectionDetached() {
1185cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        /*
1186cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * We presently believe it is unnecessary to tear down the PDP context
1187cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * when GPRS detaches, but we should stop the network polling.
1188cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         */
1189cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log ("onDataConnectionDetached: stop polling and notify detached");
1190cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopNetStatPoll();
1191cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopDataStallAlarm();
1192cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyDataConnection(Phone.REASON_DATA_DETACHED);
1193187a39f896f88eb6c5e4306d9595546654825976Wink Saville        mAttached.set(false);
1194cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1195c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1196cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onDataConnectionAttached() {
1197cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onDataConnectionAttached");
11987ab10e4710bdb54c6d9a5ee01cd443a42a2689f5Sungmin Choi        mAttached.set(true);
1199cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getOverallState() == DctConstants.State.CONNECTED) {
1200cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onDataConnectionAttached: start polling notify attached");
1201cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            startNetStatPoll();
1202cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
1203cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_DATA_ATTACHED);
1204cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1205cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // update APN availability so that APN can be enabled.
1206cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_DATA_ATTACHED);
1207cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
120812fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        if (mAutoAttachOnCreationConfig) {
1209aacc11b299ac047e73e1e712aa396ea0a6a80158Robert Greenwalt            mAutoAttachOnCreation.set(true);
121012fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        }
1211ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(Phone.REASON_DATA_ATTACHED);
1212cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1213c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
121499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu    /**
121599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * Check if it is allowed to make a data connection (without checking APN context specific
121699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * conditions).
121799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *
121899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @param dataConnectionReasons Data connection allowed or disallowed reasons as the output
121999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *                              param. It's okay to pass null here and no reasons will be
122099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *                              provided.
122199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @return True if data connection is allowed, otherwise false.
122299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     */
122399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu    public boolean isDataAllowed(DataConnectionReasons dataConnectionReasons) {
122499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        return isDataAllowed(null, dataConnectionReasons);
122599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu    }
122699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
122799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu    /**
122899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * Check if it is allowed to make a data connection for a given APN type.
122999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *
123099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @param apnContext APN context. If passing null, then will only check general but not APN
123199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *                   specific conditions (e.g. APN state, metered/unmetered APN).
123299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @param dataConnectionReasons Data connection allowed or disallowed reasons as the output
123399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *                              param. It's okay to pass null here and no reasons will be
123499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *                              provided.
123599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @return True if data connection is allowed, otherwise false.
123699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     */
123799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu    boolean isDataAllowed(ApnContext apnContext, DataConnectionReasons dataConnectionReasons) {
123899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 1: Get all environment conditions.
123999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 2: Special handling for emergency APN.
124099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 3. Build disallowed reasons.
124199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 4: Determine if data should be allowed in some special conditions.
124299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
124399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        DataConnectionReasons reasons = new DataConnectionReasons();
1244cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
124599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 1: Get all environment conditions.
124699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        final boolean internalDataEnabled = mDataEnabledSettings.isInternalDataEnabled();
12479894b3fb2f35e21d9cfd45f233ed093589e14c26sy.yun        boolean attachedState = mAttached.get();
1248cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
12490d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu        boolean radioStateFromCarrier = mPhone.getServiceStateTracker().getPowerStateFromCarrier();
125099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // TODO: Remove this hack added by ag/641832.
12510e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
12520e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        if (radioTech == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN) {
12530e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            desiredPowerState = true;
12540d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu            radioStateFromCarrier = true;
12550e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        }
12560e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh
125799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        boolean recordsLoaded = mIccRecords.get() != null && mIccRecords.get().getRecordsLoaded();
125899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
125999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        boolean defaultDataSelected = SubscriptionManager.isValidSubscriptionId(
126099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                SubscriptionManager.getDefaultDataSubscriptionId());
1261cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
126299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        boolean isMeteredApnType = apnContext == null
126350734be549285702de00295778b8c2a4360215a0Jack Yu                || ApnSetting.isMeteredApnType(apnContext.getApnType(), mPhone);
12643d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
126599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        PhoneConstants.State phoneState = PhoneConstants.State.IDLE;
12660710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // Note this is explicitly not using mPhone.getState.  See b/19090488.
12670710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // mPhone.getState reports the merge of CS and PS (volte) voice call state
12680710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // but we only care about CS calls here for data/voice concurrency issues.
12690710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // Calling getCallTracker currently gives you just the CS side where the
12700710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // ImsCallTracker is held internally where applicable.
12710710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // This should be redesigned to ask explicitly what we want:
12720710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // voiceCallStateAllowDataCall, or dataCallAllowed or something similar.
1273b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com        if (mPhone.getCallTracker() != null) {
127499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            phoneState = mPhone.getCallTracker().getState();
127599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
127699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
127799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 2: Special handling for emergency APN.
127899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (apnContext != null
127999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                && apnContext.getApnType().equals(PhoneConstants.APN_TYPE_EMERGENCY)
128099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                && apnContext.isConnectable()) {
128199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            // If this is an emergency APN, as long as the APN is connectable, we
128299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            // should allow it.
128399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            if (dataConnectionReasons != null) {
128499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                dataConnectionReasons.add(DataAllowedReasonType.EMERGENCY_APN);
128599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            }
128699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            // Bail out without further checks.
128799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            return true;
128899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
128999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
129099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 3. Build disallowed reasons.
129199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (apnContext != null && !apnContext.isConnectable()) {
129299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.APN_NOT_CONNECTABLE);
129399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
129499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
129599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // If RAT is IWLAN then don't allow default/IA PDP at all.
129699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Rest of APN types can be evaluated for remaining conditions.
129799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if ((apnContext != null && (apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
129899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                || apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IA)))
129999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                && (radioTech == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN)) {
130099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.ON_IWLAN);
130199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
130299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
130399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (isEmergency()) {
130499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.IN_ECBM);
1305b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com        }
13061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
13073d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!(attachedState || mAutoAttachOnCreation.get())) {
130899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.NOT_ATTACHED);
13093d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13103d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!recordsLoaded) {
131199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.RECORD_NOT_LOADED);
13123d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
131399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (phoneState != PhoneConstants.State.IDLE
131499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                && !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
131599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.INVALID_PHONE_STATE);
131699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.CONCURRENT_VOICE_DATA_NOT_ALLOWED);
13173d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13183d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!internalDataEnabled) {
131999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.INTERNAL_DATA_DISABLED);
13203d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13213d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!defaultDataSelected) {
132299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.DEFAULT_DATA_UNSELECTED);
13233d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13245b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (mPhone.getServiceState().getDataRoaming() && !getDataRoamingEnabled()) {
132599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.ROAMING_DISABLED);
1326c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
13273d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (mIsPsRestricted) {
132899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.PS_RESTRICTED);
13293d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13303d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!desiredPowerState) {
133199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.UNDESIRED_POWER_STATE);
13323d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13330d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu        if (!radioStateFromCarrier) {
133499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.RADIO_DISABLED_BY_CARRIER);
133599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
133699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (!mDataEnabledSettings.isDataEnabled()) {
133799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.DATA_DISABLED);
13380d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu        }
13393d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
134099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // If there are hard disallowed reasons, we should not allow data connection no matter what.
134199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (reasons.containsHardDisallowedReasons()) {
134299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            if (dataConnectionReasons != null) {
134399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                dataConnectionReasons.copyFrom(reasons);
134499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            }
134599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            return false;
134699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
134799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
134899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 4: Determine if data should be allowed in some special conditions.
134999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
135099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // At this point, if data is not allowed, it must be because of the soft reasons. We
135199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // should start to check some special conditions that data will be allowed.
135299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
135399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // If the request APN type is unmetered and there are soft disallowed reasons (e.g. data
135499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // disabled, data roaming disabled) existing, we should allow the data because the user
135599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // won't be charged anyway.
135699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (!isMeteredApnType && !reasons.allowed()) {
135799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataAllowedReasonType.UNMETERED_APN);
135899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
135999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
13601fcdbab4cb564eb9f3f0865bab7d1ab5ab18199dfionaxu        // If the request is restricted and there are only disallowed reasons due to data
13611fcdbab4cb564eb9f3f0865bab7d1ab5ab18199dfionaxu        // disabled, we should allow the data.
136299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (apnContext != null
136399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                && !apnContext.hasNoRestrictedRequests(true)
13641fcdbab4cb564eb9f3f0865bab7d1ab5ab18199dfionaxu                && reasons.contains(DataDisallowedReasonType.DATA_DISABLED)) {
136599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataAllowedReasonType.RESTRICTED_REQUEST);
136699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
136799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
136899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // If at this point, we still haven't built any disallowed reasons, we should allow data.
136999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (reasons.allowed()) {
137099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataAllowedReasonType.NORMAL);
137199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
137299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
137399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (dataConnectionReasons != null) {
137499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            dataConnectionReasons.copyFrom(reasons);
137599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
137699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
137799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        return reasons.allowed();
1378cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1379c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1380c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    // arg for setupDataOnConnectableApns
1381c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    private enum RetryFailures {
1382c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        // retry failed networks always (the old default)
1383c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        ALWAYS,
13840e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        // retry only when a substantial change has occurred.  Either:
1385c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        // 1) we were restricted by voice/data concurrency and aren't anymore
1386c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        // 2) our apn list has change
1387c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        ONLY_ON_CHANGE
1388c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    };
1389c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt
1390ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void setupDataOnConnectableApns(String reason) {
1391c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        setupDataOnConnectableApns(reason, RetryFailures.ALWAYS);
1392c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    }
1393c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt
1394c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    private void setupDataOnConnectableApns(String reason, RetryFailures retryFailures) {
13959c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        if (VDBG) log("setupDataOnConnectableApns: " + reason);
13963fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
1397c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu        if (DBG && !VDBG) {
1398c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            StringBuilder sb = new StringBuilder(120);
1399c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            for (ApnContext apnContext : mPrioritySortedApnContexts) {
1400c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(apnContext.getApnType());
1401c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(":[state=");
1402c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(apnContext.getState());
1403c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(",enabled=");
1404c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(apnContext.isEnabled());
1405c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append("] ");
1406c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            }
14079c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            log("setupDataOnConnectableApns: " + reason + " " + sb);
1408c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu        }
1409c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu
14103fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        for (ApnContext apnContext : mPrioritySortedApnContexts) {
1411c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            if (VDBG) log("setupDataOnConnectableApns: apnContext " + apnContext);
1412c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu
1413735bc2f4524d68155765351912ffae11306c3bd5Chris Manton            if (apnContext.getState() == DctConstants.State.FAILED
14140e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                    || apnContext.getState() == DctConstants.State.SCANNING) {
1415c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                if (retryFailures == RetryFailures.ALWAYS) {
1416ee665b78ad648abd98b019a9c9047f206ed22994Robert Greenwalt                    apnContext.releaseDataConnection(reason);
1417c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                } else if (apnContext.isConcurrentVoiceAndDataAllowed() == false &&
14180e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                        mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
1419c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    // RetryFailures.ONLY_ON_CHANGE - check if voice concurrency has changed
1420ee665b78ad648abd98b019a9c9047f206ed22994Robert Greenwalt                    apnContext.releaseDataConnection(reason);
1421c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                }
1422cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1423ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.isConnectable()) {
14249c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                log("isConnectable() call trySetupData");
1425ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setReason(reason);
1426ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                trySetupData(apnContext);
1427cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1428cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1429c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1430c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
14311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    boolean isEmergency() {
1432a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        final boolean result = mPhone.isInEcm() || mPhone.isInEmergencyCall();
14331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("isEmergency: result=" + result);
14341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return result;
14351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
14361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1437cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean trySetupData(ApnContext apnContext) {
1438cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1439cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
1440cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
1441cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
1442cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setState(DctConstants.State.CONNECTED);
1443cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1444cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1445cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("trySetupData: X We're on the simulator; assuming connected retValue=true");
1446cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return true;
1447cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1448cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
144999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        DataConnectionReasons dataConnectionReasons = new DataConnectionReasons();
145099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        boolean isDataAllowed = isDataAllowed(apnContext, dataConnectionReasons);
145199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        String logStr = "trySetupData for APN type " + apnContext.getApnType() + ", reason: "
145299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                + apnContext.getReason() + ". " + dataConnectionReasons.toString();
145399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (DBG) log(logStr);
145499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        apnContext.requestLog(logStr);
1455120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        if (isDataAllowed) {
1456ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getState() == DctConstants.State.FAILED) {
14573d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                String str = "trySetupData: make a FAILED ApnContext IDLE so its reusable";
14582dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                if (DBG) log(str);
14592dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                apnContext.requestLog(str);
1460ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setState(DctConstants.State.IDLE);
1461ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1462203e588e3c42a81aa8a56f595119c181a63b12caWink Saville            int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
146399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            apnContext.setConcurrentVoiceAndDataAllowed(mPhone.getServiceStateTracker()
146499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                    .isConcurrentVoiceAndDataAllowed());
1465cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.getState() == DctConstants.State.IDLE) {
1466ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                ArrayList<ApnSetting> waitingApns =
1467ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                        buildWaitingApns(apnContext.getApnType(), radioTech);
1468cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (waitingApns.isEmpty()) {
1469ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    notifyNoData(DcFailCause.MISSING_UNKNOWN_APN, apnContext);
1470cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    notifyOffApnsOfAvailability(apnContext.getReason());
14712dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    String str = "trySetupData: X No APN found retValue=false";
14722dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    if (DBG) log(str);
14732dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    apnContext.requestLog(str);
1474cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return false;
1475cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1476cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setWaitingApns(waitingApns);
1477cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) {
1478ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        log ("trySetupData: Create from mAllApnSettings : "
1479ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                    + apnListToString(mAllApnSettings));
1480cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1481cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1482cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1483cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
148499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            boolean retValue = setupData(apnContext, radioTech, dataConnectionReasons.contains(
148599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                    DataAllowedReasonType.UNMETERED_APN));
1486cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(apnContext.getReason());
1487cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1488cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("trySetupData: X retValue=" + retValue);
1489cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return retValue;
1490cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1491cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
1492ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    && apnContext.isConnectable()) {
1493cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
1494ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1495cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(apnContext.getReason());
14962e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
14972e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            StringBuilder str = new StringBuilder();
14982e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
149999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            str.append("trySetupData failed. apnContext = [type=" + apnContext.getApnType()
150099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                    + ", mState=" + apnContext.getState() + ", apnEnabled="
150199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                    + apnContext.isEnabled() + ", mDependencyMet="
150299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                    + apnContext.getDependencyMet() + "] ");
15032e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
1504120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu            if (!mDataEnabledSettings.isDataEnabled()) {
150599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                str.append("isDataEnabled() = false. " + mDataEnabledSettings);
15062e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            }
15072e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
15089d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu            // If this is a data retry, we should set the APN state to FAILED so it won't stay
15099d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu            // in SCANNING forever.
15109d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu            if (apnContext.getState() == DctConstants.State.SCANNING) {
15119d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu                apnContext.setState(DctConstants.State.FAILED);
15129d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu                str.append(" Stop retrying.");
15139d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu            }
15149d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu
15152e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            if (DBG) log(str.toString());
15162e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            apnContext.requestLog(str.toString());
1517cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
1518cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1519c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1520c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
15210e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    // Disabled apn's still need avail/unavail notifications - send them out
15221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyOffApnsOfAvailability(String reason) {
1523cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1524187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (!mAttached.get() || !apnContext.isReady()) {
1525ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) log("notifyOffApnOfAvailability type:" + apnContext.getApnType());
1526cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
1527cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                            apnContext.getApnType(),
1528cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                            PhoneConstants.DataState.DISCONNECTED);
1529cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1530ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) {
1531187a39f896f88eb6c5e4306d9595546654825976Wink Saville                    log("notifyOffApnsOfAvailability skipped apn due to attached && isReady " +
1532cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            apnContext.toString());
1533cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1534c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1535c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1536c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1537c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1538cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1539cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * If tearDown is true, this only tears down a CONNECTED session. Presently,
1540cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * there is no mechanism for abandoning an CONNECTING session,
1541cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * but would likely involve cancelling pending async requests or
1542cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * setting a flag or new state to ignore them when they came in
1543cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param tearDown true if the underlying DataConnection should be
1544cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * disconnected.
1545cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param reason reason for the clean up.
15463fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return boolean - true if we did cleanup any connections, false if they
15473fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     *                   were already all disconnected.
1548cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
15491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean cleanUpAllConnections(boolean tearDown, String reason) {
1550cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("cleanUpAllConnections: tearDown=" + tearDown + " reason=" + reason);
15513fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        boolean didDisconnect = false;
15524c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu        boolean disableMeteredOnly = false;
1553a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
15544c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu        // reasons that only metered apn will be torn down
1555a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (!TextUtils.isEmpty(reason)) {
15564c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            disableMeteredOnly = reason.equals(Phone.REASON_DATA_SPECIFIC_DISABLED) ||
15574c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                    reason.equals(Phone.REASON_ROAMING_ON) ||
15582061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala                    reason.equals(Phone.REASON_CARRIER_ACTION_DISABLE_METERED_APN) ||
15592061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala                    reason.equals(Phone.REASON_PDP_RESET);
1560a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1561cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1562cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
15634c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            if (disableMeteredOnly) {
1564783061ca03572618c01ce244d70d82fa4328d45ffionaxu                // Use ApnSetting to decide metered or non-metered.
1565783061ca03572618c01ce244d70d82fa4328d45ffionaxu                // Tear down all metered data connections.
1566783061ca03572618c01ce244d70d82fa4328d45ffionaxu                ApnSetting apnSetting = apnContext.getApnSetting();
156750734be549285702de00295778b8c2a4360215a0Jack Yu                if (apnSetting != null && apnSetting.isMetered(mPhone)) {
15682061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala                    if (apnContext.isDisconnected() == false) didDisconnect = true;
1569783061ca03572618c01ce244d70d82fa4328d45ffionaxu                    if (DBG) log("clean up metered ApnContext Type: " + apnContext.getApnType());
1570a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    apnContext.setReason(reason);
1571a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    cleanUpConnection(tearDown, apnContext);
1572a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1573a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
15742061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala                // Exclude the IMS APN from single DataConenction case.
15752061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala                if (reason.equals(Phone.REASON_SINGLE_PDN_ARBITRATION)
15762061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala                        && apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IMS)) {
15772061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala                    continue;
15782061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala                }
1579a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // TODO - only do cleanup if not disconnected
15802061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala                if (apnContext.isDisconnected() == false) didDisconnect = true;
1581a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                apnContext.setReason(reason);
1582a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                cleanUpConnection(tearDown, apnContext);
1583a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1584c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1585cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1586cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopNetStatPoll();
1587cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopDataStallAlarm();
1588cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1589cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: Do we need mRequestedApnType?
1590cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
1591a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1592a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("cleanUpConnection: mDisconnectPendingCount = " + mDisconnectPendingCount);
1593a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (tearDown && mDisconnectPendingCount == 0) {
1594a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyDataDisconnectComplete();
1595a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
1596a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1597a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
15983fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return didDisconnect;
1599cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1600cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1601cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1602cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Cleanup all connections.
1603cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1604cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * TODO: Cleanup only a specified connection passed as a parameter.
1605cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *       Also, make sure when you clean up a conn, if it is last apply
1606cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *       logic as though it is cleanupAllConnections
1607cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1608cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param cause for the clean up.
1609cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
16101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onCleanUpAllConnections(String cause) {
1611cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, cause);
1612cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1613cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
16141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    void sendCleanUpConnection(boolean tearDown, ApnContext apnContext) {
16151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("sendCleanUpConnection: tearDown=" + tearDown + " apnContext=" + apnContext);
16161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_CLEAN_UP_CONNECTION);
16171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = tearDown ? 1 : 0;
16181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg2 = 0;
16191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.obj = apnContext;
16201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
16211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
1622cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
16231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void cleanUpConnection(boolean tearDown, ApnContext apnContext) {
1624cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
1625cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("cleanUpConnection: apn context is null");
1626cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
1627cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1628cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1629454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac = apnContext.getDcAc();
16302dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        String str = "cleanUpConnection: tearDown=" + tearDown + " reason=" +
16312dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                apnContext.getReason();
16329c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        if (VDBG) log(str + " apnContext=" + apnContext);
16332dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog(str);
1634cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (tearDown) {
1635cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.isDisconnected()) {
1636cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // The request is tearDown and but ApnContext is not connected.
1637cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // If apnContext is not enabled anymore, break the linkage to the DCAC/DC.
1638cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setState(DctConstants.State.IDLE);
1639cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (!apnContext.isReady()) {
16404750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                    if (dcac != null) {
16410e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                        str = "cleanUpConnection: teardown, disconnected, !ready";
16422dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        if (DBG) log(str + " apnContext=" + apnContext);
16432dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        apnContext.requestLog(str);
16444750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                        dcac.tearDown(apnContext, "", null);
16454750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                    }
1646cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setDataConnectionAc(null);
1647cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1648cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1649cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Connection is still there. Try to clean up.
1650cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (dcac != null) {
1651cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (apnContext.getState() != DctConstants.State.DISCONNECTING) {
1652cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        boolean disconnectAll = false;
1653cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (PhoneConstants.APN_TYPE_DUN.equals(apnContext.getApnType())) {
1654a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            // CAF_MSIM is this below condition required.
1655a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            // if (PhoneConstants.APN_TYPE_DUN.equals(PhoneConstants.APN_TYPE_DEFAULT)) {
16561484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                            if (teardownForDun()) {
165745eaa2335e64a8ff1ad8d5e8224c580ef996f370Wink Saville                                if (DBG) {
165845eaa2335e64a8ff1ad8d5e8224c580ef996f370Wink Saville                                    log("cleanUpConnection: disconnectAll DUN connection");
165945eaa2335e64a8ff1ad8d5e8224c580ef996f370Wink Saville                                }
1660cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // we need to tear it down - we brought it up just for dun and
1661cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // other people are camped on it and now dun is done.  We need
1662cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // to stop using it and let the normal apn list get used to find
1663cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // connections for the remaining desired connections
1664cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                disconnectAll = true;
1665cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            }
1666cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
16671a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                        final int generation = apnContext.getConnectionGeneration();
16681a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                        str = "cleanUpConnection: tearing down" + (disconnectAll ? " all" : "") +
16691a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                                " using gen#" + generation;
16702dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        if (DBG) log(str + "apnContext=" + apnContext);
16712dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        apnContext.requestLog(str);
167237cacdfe7ed079d89fb9e80317b5dfd2acb975e5Robert Greenwalt                        Pair<ApnContext, Integer> pair =
16731a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                                new Pair<ApnContext, Integer>(apnContext, generation);
167437cacdfe7ed079d89fb9e80317b5dfd2acb975e5Robert Greenwalt                        Message msg = obtainMessage(DctConstants.EVENT_DISCONNECT_DONE, pair);
1675cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (disconnectAll) {
1676ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            apnContext.getDcAc().tearDownAll(apnContext.getReason(), msg);
1677cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        } else {
1678ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            apnContext.getDcAc()
1679cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                .tearDown(apnContext, apnContext.getReason(), msg);
1680cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
1681cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.setState(DctConstants.State.DISCONNECTING);
1682a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        mDisconnectPendingCount++;
1683cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1684cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1685cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // apn is connected but no reference to dcac.
1686cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // Should not be happen, but reset the state in case.
1687cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setState(DctConstants.State.IDLE);
16882dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    apnContext.requestLog("cleanUpConnection: connected, bug no DCAC");
1689cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mPhone.notifyDataConnection(apnContext.getReason(),
1690cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                                apnContext.getApnType());
1691cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1692cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1693cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1694cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // force clean up the data connection.
1695ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac != null) dcac.reqReset();
1696cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setState(DctConstants.State.IDLE);
1697cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1698cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setDataConnectionAc(null);
1699cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1700cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1701ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // Make sure reconnection alarm is cleaned up if there is no ApnContext
1702cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // associated to the connection.
1703cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (dcac != null) {
1704ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            cancelReconnectAlarm(apnContext);
1705c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
17062dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        str = "cleanUpConnection: X tearDown=" + tearDown + " reason=" + apnContext.getReason();
17072dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        if (DBG) log(str + " apnContext=" + apnContext + " dcac=" + apnContext.getDcAc());
17082dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog(str);
1709cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1710c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
17115fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan    /**
17122abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu     * Fetch the DUN apns
17132abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu     * @return a list of DUN ApnSetting objects
17145fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan     */
17155fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan    @VisibleForTesting
17162abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu    public @NonNull ArrayList<ApnSetting> fetchDunApns() {
17171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (SystemProperties.getBoolean("net.tethering.noprovisioning", false)) {
17182abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu            log("fetchDunApns: net.tethering.noprovisioning=true ret: empty list");
17192abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu            return new ArrayList<ApnSetting>(0);
17201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
17211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int bearer = mPhone.getServiceState().getRilDataRadioTechnology();
1722d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        IccRecords r = mIccRecords.get();
1723d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        String operator = (r != null) ? r.getOperatorNumeric() : "";
1724d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        ArrayList<ApnSetting> dunCandidates = new ArrayList<ApnSetting>();
17252abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu        ArrayList<ApnSetting> retDunSettings = new ArrayList<ApnSetting>();
1726d92c67aa965200385acf3182ffb0af25297a366fJunda Liu
17275fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan        // Places to look for tether APN in order: TETHER_DUN_APN setting (to be deprecated soon),
17285fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan        // APN database, and config_tether_apndata resource (to be deprecated soon).
17291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        String apnData = Settings.Global.getString(mResolver, Settings.Global.TETHER_DUN_APN);
1730d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        if (!TextUtils.isEmpty(apnData)) {
1731d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            dunCandidates.addAll(ApnSetting.arrayFromString(apnData));
17322abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu            if (VDBG) log("fetchDunApns: dunCandidates from Setting: " + dunCandidates);
1733d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        }
17345fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan
17355fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan        // todo: remove this and config_tether_apndata after APNs are moved from overlay to apns xml
17365fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan        // If TETHER_DUN_APN isn't set or APN database doesn't have dun APN,
1737d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        // try the resource as last resort.
1738d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        if (dunCandidates.isEmpty()) {
1739d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            String[] apnArrayData = mPhone.getContext().getResources()
1740d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                .getStringArray(R.array.config_tether_apndata);
1741ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu            if (!ArrayUtils.isEmpty(apnArrayData)) {
1742ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                for (String apnString : apnArrayData) {
1743ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                    ApnSetting apn = ApnSetting.fromString(apnString);
1744ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                    // apn may be null if apnString isn't valid or has error parsing
1745ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                    if (apn != null) dunCandidates.add(apn);
1746ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                }
17472abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                if (VDBG) log("fetchDunApns: dunCandidates from resource: " + dunCandidates);
1748d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            }
17491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
17501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
17515fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan        if (dunCandidates.isEmpty()) {
17525fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan            if (!ArrayUtils.isEmpty(mAllApnSettings)) {
17535fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan                for (ApnSetting apn : mAllApnSettings) {
17545fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan                    if (apn.canHandleType(PhoneConstants.APN_TYPE_DUN)) {
17555fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan                        dunCandidates.add(apn);
17565fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan                    }
17575fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan                }
17582abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                if (VDBG) log("fetchDunApns: dunCandidates from database: " + dunCandidates);
17595fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan            }
17605fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan        }
17615fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan
1762d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        for (ApnSetting dunSetting : dunCandidates) {
1763176f28521fd45bb739709d309e7970b1558c9f61Cassie            if (!ServiceState.bitmaskHasTech(dunSetting.networkTypeBitmask,
1764176f28521fd45bb739709d309e7970b1558c9f61Cassie                    ServiceState.rilRadioTechnologyToNetworkType(bearer))) {
1765176f28521fd45bb739709d309e7970b1558c9f61Cassie                continue;
1766176f28521fd45bb739709d309e7970b1558c9f61Cassie            }
1767d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            if (dunSetting.numeric.equals(operator)) {
17681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (dunSetting.hasMvnoParams()) {
17691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (r != null && ApnSetting.mvnoMatches(r, dunSetting.mvnoType,
17701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            dunSetting.mvnoMatchData)) {
17712abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                        retDunSettings.add(dunSetting);
17721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
17731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else if (mMvnoMatched == false) {
17742abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                    retDunSettings.add(dunSetting);
17751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
17761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
17771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
17781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
17792abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu        if (VDBG) log("fetchDunApns: dunSettings=" + retDunSettings);
17802abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu        return retDunSettings;
17812abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu    }
17822abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu
17832abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu    private int getPreferredApnSetId() {
17842abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu        Cursor c = mPhone.getContext().getContentResolver()
17852abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                .query(Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI,
17862abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                    "preferapnset/subId/" + mPhone.getSubId()),
17872abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                        new String[] {Telephony.Carriers.APN_SET_ID}, null, null, null);
17882abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu        if (c.getCount() < 1) {
17892abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu            loge("getPreferredApnSetId: no APNs found");
17902abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu            return Telephony.Carriers.NO_SET_SET;
17912abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu        } else {
17922abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu            c.moveToFirst();
17932abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu            return c.getInt(0 /* index of Telephony.Carriers.APN_SET_ID */);
17942abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu        }
17951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
17961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
17971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public boolean hasMatchedTetherApnSetting() {
17982abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu        ArrayList<ApnSetting> matches = fetchDunApns();
17992abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu        log("hasMatchedTetherApnSetting: APNs=" + matches);
18002abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu        return matches.size() > 0;
18011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
18021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1803cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
18041484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt     * Determine if DUN connection is special and we need to teardown on start/stop
18051484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt     */
18061484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt    private boolean teardownForDun() {
18071484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // CDMA always needs to do this the profile id is correct
18081484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        final int rilRat = mPhone.getServiceState().getRilDataRadioTechnology();
18091484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        if (ServiceState.isCdma(rilRat)) return true;
18101484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt
18112abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu        ArrayList<ApnSetting> apns = fetchDunApns();
18122abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu        return apns.size() > 0;
18131484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt    }
18141484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt
18151484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt    /**
1816ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Cancels the alarm associated with apnContext.
1817cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1818ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * @param apnContext on which the alarm should be stopped.
1819cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1820ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void cancelReconnectAlarm(ApnContext apnContext) {
1821ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnContext == null) return;
1822cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1823ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        PendingIntent intent = apnContext.getReconnectIntent();
1824cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1825cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (intent != null) {
1826cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                AlarmManager am =
1827cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
1828cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                am.cancel(intent);
1829ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setReconnectIntent(null);
1830cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1831c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1832c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1833cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1834cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param types comma delimited list of APN types
1835cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return array of APN types
1836cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1837cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private String[] parseTypes(String types) {
1838c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String[] result;
1839cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // If unset, set to DEFAULT.
1840cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (types == null || types.equals("")) {
1841c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            result = new String[1];
1842cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result[0] = PhoneConstants.APN_TYPE_ALL;
1843cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1844cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result = types.split(",");
1845c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1846c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
1847c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1848c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1849ccfe5ebaf81c1378e8dbe44e45df26b0dc462a21Jack Yu    boolean isPermanentFailure(DcFailCause dcFailCause) {
1850ccfe5ebaf81c1378e8dbe44e45df26b0dc462a21Jack Yu        return (dcFailCause.isPermanentFailure(mPhone.getContext(), mPhone.getSubId()) &&
1851796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan                (mAttached.get() == false || dcFailCause != DcFailCause.SIGNAL_LOST));
1852796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan    }
1853796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan
1854fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    private ApnSetting makeApnSetting(Cursor cursor) {
1855fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        String[] types = parseTypes(
1856fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.TYPE)));
1857176f28521fd45bb739709d309e7970b1558c9f61Cassie        int networkTypeBitmask = cursor.getInt(
1858176f28521fd45bb739709d309e7970b1558c9f61Cassie                cursor.getColumnIndexOrThrow(Telephony.Carriers.NETWORK_TYPE_BITMASK));
1859176f28521fd45bb739709d309e7970b1558c9f61Cassie
1860fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        ApnSetting apn = new ApnSetting(
1861fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID)),
1862fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NUMERIC)),
1863fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NAME)),
1864fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN)),
1865fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1866fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1867fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY))),
1868fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PORT)),
1869fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1870fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1871fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC))),
1872fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1873fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1874fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY))),
1875fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPORT)),
1876fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)),
1877fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)),
18781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.AUTH_TYPE)),
1879fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                types,
1880fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROTOCOL)),
1881fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(
1882fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        Telephony.Carriers.ROAMING_PROTOCOL)),
1883fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(
1884fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        Telephony.Carriers.CARRIER_ENABLED)) == 1,
1885176f28521fd45bb739709d309e7970b1558c9f61Cassie                networkTypeBitmask,
18869d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROFILE_ID)),
18879d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(
18889d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                        Telephony.Carriers.MODEM_COGNITIVE)) == 1,
18899d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MAX_CONNS)),
18909d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(
18919d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                        Telephony.Carriers.WAIT_TIME)),
1892e9701717e43cc5aacbcf624f77a53be92350662cw                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MAX_CONNS_TIME)),
18933262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MTU)),
18943262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_TYPE)),
189521f6e74b368a7045981cdb718570bf872471ac0bJordan Liu                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_MATCH_DATA)),
189621f6e74b368a7045981cdb718570bf872471ac0bJordan Liu                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN_SET_ID)));
1897fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        return apn;
1898fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    }
1899fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
1900cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ArrayList<ApnSetting> createApnList(Cursor cursor) {
19013262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        ArrayList<ApnSetting> mnoApns = new ArrayList<ApnSetting>();
19023262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        ArrayList<ApnSetting> mvnoApns = new ArrayList<ApnSetting>();
1903fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        IccRecords r = mIccRecords.get();
1904fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
1905cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor.moveToFirst()) {
1906cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            do {
19073262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                ApnSetting apn = makeApnSetting(cursor);
19083262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                if (apn == null) {
19093262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                    continue;
19103262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                }
19113262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
19123262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                if (apn.hasMvnoParams()) {
191363913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan                    if (r != null && ApnSetting.mvnoMatches(r, apn.mvnoType, apn.mvnoMatchData)) {
19143262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                        mvnoApns.add(apn);
1915fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    }
1916fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                } else {
19173262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                    mnoApns.add(apn);
1918fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                }
1919cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } while (cursor.moveToNext());
1920cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
19213262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
19221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ArrayList<ApnSetting> result;
19231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mvnoApns.isEmpty()) {
19241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            result = mnoApns;
19251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mMvnoMatched = false;
19261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
19271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            result = mvnoApns;
19281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mMvnoMatched = true;
19291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
1930cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createApnList: X result=" + result);
1931c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
1932c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1933c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1934454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private boolean dataConnectionNotInUse(DcAsyncChannel dcac) {
1935ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("dataConnectionNotInUse: check if dcac is inuse dcac=" + dcac);
1936cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1937ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getDcAc() == dcac) {
1938cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("dataConnectionNotInUse: in use by apnContext=" + apnContext);
1939cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
1940cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1941cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1942cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: Fix retry handling so free DataConnections have empty apnlists.
1943cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Probably move retry handling into DataConnections and reduce complexity
1944cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // of DCT.
1945cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("dataConnectionNotInUse: tearDownAll");
1946ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        dcac.tearDownAll("No connection", null);
1947cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("dataConnectionNotInUse: not in use return true");
1948cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
1949cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1950cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1951454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel findFreeDataConnection() {
1952454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
1953cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac.isInactiveSync() && dataConnectionNotInUse(dcac)) {
1954cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
1955cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("findFreeDataConnection: found free DataConnection=" +
1956ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        " dcac=" + dcac);
1957cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1958ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                return dcac;
1959cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1960cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1961cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("findFreeDataConnection: NO free DataConnection");
1962cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
1963cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1964cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
196599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu    /**
196699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * Setup a data connection based on given APN type.
196799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *
196899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @param apnContext APN context
196999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @param radioTech RAT of the data connection
197099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @param unmeteredUseOnly True if this data connection should be only used for unmetered
197199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *                         purposes only.
197299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @return True if successful, otherwise false.
197399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     */
1974120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu    private boolean setupData(ApnContext apnContext, int radioTech, boolean unmeteredUseOnly) {
1975cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setupData: apnContext=" + apnContext);
19762dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog("setupData");
1977ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnSetting apnSetting;
19781484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        DcAsyncChannel dcac = null;
1979cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
19800e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        apnSetting = apnContext.getNextApnSetting();
19810e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
1982ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnSetting == null) {
1983cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("setupData: return for no apn found!");
1984cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
1985cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1986cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1987231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        int profileId = apnSetting.profileId;
1988231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        if (profileId == 0) {
1989231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen            profileId = getApnProfileID(apnContext.getApnType());
1990231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        }
1991231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen
19921484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // On CDMA, if we're explicitly asking for DUN, we need have
19931484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // a dun-profiled connection so we can't share an existing one
19941484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // On GSM/LTE we can share existing apn connections provided they support
19951484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // this type.
1996ec74378410bac5105c1c4f10ccbdfe475950322fJack Yu        if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DUN)
1997ec74378410bac5105c1c4f10ccbdfe475950322fJack Yu                || ServiceState.isGsm(mPhone.getServiceState().getRilDataRadioTechnology())) {
19981484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt            dcac = checkForCompatibleConnectedApnContext(apnContext);
19991484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt            if (dcac != null) {
20001484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // Get the dcacApnSetting for the connection we want to share.
20011484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                ApnSetting dcacApnSetting = dcac.getApnSettingSync();
20021484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                if (dcacApnSetting != null) {
20031484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    // Setting is good, so use it.
20041484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    apnSetting = dcacApnSetting;
20051484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                }
2006ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
2007ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
2008ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (dcac == null) {
20093fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (isOnlySingleDcAllowed(radioTech)) {
20103fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (isHigherPriorityApnContextActive(apnContext)) {
20113fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (DBG) {
20123fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        log("setupData: Higher priority ApnContext active.  Ignoring call");
20133fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    }
20143fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    return false;
20153fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                }
20163fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
20172061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala                if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IMS)) {
20182061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala                    // Only lower priority calls left.  Disconnect them all in this single PDP case
20192061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala                    // so that we can bring up the requested higher priority call (once we receive
20202061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala                    // response for deactivate request for the calls we are about to disconnect
20212061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala                    if (cleanUpAllConnections(true, Phone.REASON_SINGLE_PDN_ARBITRATION)) {
20222061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala                        // If any call actually requested to be disconnected, means we can't
20232061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala                        // bring up this connection yet as we need to wait for those data calls
20242061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala                        // to be disconnected.
20252061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala                        if (DBG) log("setupData: Some calls are disconnecting first."
20262061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala                                + " Wait and retry");
20272061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala                        return false;
20282061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala                    }
20293fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                }
20303fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
20313fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // No other calls are active, so proceed
20323fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (DBG) log("setupData: Single pdp. Continue setting up data call.");
20333fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
20343fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
2035ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            dcac = findFreeDataConnection();
2036cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2037ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac == null) {
2038ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                dcac = createDataConnection();
2039cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2040cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2041ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac == null) {
2042ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) log("setupData: No free DataConnection and couldn't create one, WEIRD");
2043cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
2044cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2045cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
20461a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        final int generation = apnContext.incAndGetConnectionGeneration();
20471a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        if (DBG) {
20481a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt            log("setupData: dcac=" + dcac + " apnSetting=" + apnSetting + " gen#=" + generation);
20491a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        }
2050cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2051cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setDataConnectionAc(dcac);
2052ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setApnSetting(apnSetting);
2053cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setState(DctConstants.State.CONNECTING);
2054cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
2055cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2056cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Message msg = obtainMessage();
2057cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        msg.what = DctConstants.EVENT_DATA_SETUP_COMPLETE;
20581a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        msg.obj = new Pair<ApnContext, Integer>(apnContext, generation);
2059120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        dcac.bringUp(apnContext, profileId, radioTech, unmeteredUseOnly, msg, generation);
2060cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2061cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setupData: initing!");
2062cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
2063cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2064cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
20651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void setInitialAttachApn() {
20661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting iaApnSetting = null;
20671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting defaultApnSetting = null;
20681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting firstApnSetting = null;
20691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
20701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("setInitialApn: E mPreferredApn=" + mPreferredApn);
20711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
207240b0e247a4a79e83f10b6410025ef1d7cc537692Robert Greenwalt        if (mPreferredApn != null && mPreferredApn.canHandleType(PhoneConstants.APN_TYPE_IA)) {
207340b0e247a4a79e83f10b6410025ef1d7cc537692Robert Greenwalt              iaApnSetting = mPreferredApn;
207440b0e247a4a79e83f10b6410025ef1d7cc537692Robert Greenwalt        } else if (mAllApnSettings != null && !mAllApnSettings.isEmpty()) {
20751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            firstApnSetting = mAllApnSettings.get(0);
20761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("setInitialApn: firstApnSetting=" + firstApnSetting);
20771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
20781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Search for Initial APN setting and the first apn that can handle default
20791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (ApnSetting apn : mAllApnSettings) {
208040b0e247a4a79e83f10b6410025ef1d7cc537692Robert Greenwalt                if (apn.canHandleType(PhoneConstants.APN_TYPE_IA)) {
20811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // The Initial Attach APN is highest priority so use it if there is one
20821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("setInitialApn: iaApnSetting=" + apn);
20831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    iaApnSetting = apn;
20841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    break;
20851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else if ((defaultApnSetting == null)
20861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        && (apn.canHandleType(PhoneConstants.APN_TYPE_DEFAULT))) {
20871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // Use the first default apn if no better choice
20881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("setInitialApn: defaultApnSetting=" + apn);
20891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    defaultApnSetting = apn;
20901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
20911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
20921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
20931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
20941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // The priority of apn candidates from highest to lowest is:
20950e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        //   1) APN_TYPE_IA (Initial Attach)
20961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        //   2) mPreferredApn, i.e. the current preferred apn
20971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        //   3) The first apn that than handle APN_TYPE_DEFAULT
20981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        //   4) The first APN we can find.
20991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
21001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting initialAttachApnSetting = null;
21011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (iaApnSetting != null) {
21021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using iaApnSetting");
21031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = iaApnSetting;
21041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (mPreferredApn != null) {
21051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using mPreferredApn");
21061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = mPreferredApn;
21071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (defaultApnSetting != null) {
21081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using defaultApnSetting");
21091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = defaultApnSetting;
21101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (firstApnSetting != null) {
21111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using firstApnSetting");
21121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = firstApnSetting;
21131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
21141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
21151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (initialAttachApnSetting == null) {
21161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: X There in no available apn");
21171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
21181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: X selected Apn=" + initialAttachApnSetting);
21191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
212071f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu            mDataServiceManager.setInitialAttachApn(createDataProfile(initialAttachApnSetting),
2121cc40713c49908aeaac0070bf4ea796247f9066b5Jack Yu                    mPhone.getServiceState().getDataRoamingFromRegistration(), null);
21221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
21231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
21241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2125c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
2126cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Handles changes to the APN database.
2127c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
2128cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onApnChanged() {
2129cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        DctConstants.State overallState = getOverallState();
2130cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isDisconnected = (overallState == DctConstants.State.IDLE ||
2131cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                overallState == DctConstants.State.FAILED);
2132cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
21331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mPhone instanceof GsmCdmaPhone) {
2134cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // The "current" may no longer be valid.  MMS depends on this to send properly. TBD
21351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            ((GsmCdmaPhone)mPhone).updateCurrentCarrierInProvider();
2136cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2137cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2138cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: It'd be nice to only do this if the changed entrie(s)
2139cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // match the current operator.
2140cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onApnChanged: createAllApnList and cleanUpAllConnections");
2141cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        createAllApnList();
21425d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi        setInitialAttachApn();
2143ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu        cleanUpConnectionsOnUpdatedApns(!isDisconnected, Phone.REASON_APN_CHANGED);
2144bda761320929f714951c328bfec6a51a1978db97Wink Saville
21458f6f52e4f7598e44cea1f9e5f4781291f9060d1dWink Saville        // FIXME: See bug 17426028 maybe no conditional is needed.
214638ca51d0f643405df51e78fce6c546424e9f410dShishir Agrawal        if (mPhone.getSubId() == SubscriptionManager.getDefaultDataSubscriptionId()) {
2147ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_APN_CHANGED);
2148c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2149c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2150c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2151c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
2152cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param cid Connection id provided from RIL.
2153cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return DataConnectionAc associated with specified cid.
2154c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
2155454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel findDataConnectionAcByCid(int cid) {
2156454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
2157cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac.getCidSync() == cid) {
2158cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return dcac;
2159cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2160c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2161cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
2162c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2163c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
21643fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    /**
21653fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * "Active" here means ApnContext isEnabled() and not in FAILED state
21663fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @param apnContext to compare with
21673fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return true if higher priority active apn found
21683fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     */
21693fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean isHigherPriorityApnContextActive(ApnContext apnContext) {
21702061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala        if (apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IMS)) {
21712061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala            return false;
21722061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala        }
21732061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala
21743fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        for (ApnContext otherContext : mPrioritySortedApnContexts) {
21752061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala            if (otherContext.getApnType().equals(PhoneConstants.APN_TYPE_IMS)) {
21762061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala                continue;
21772061ceba319413bed4d146459c517ca35a4caf8cSusheel Nyamala            }
21783fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (apnContext.getApnType().equalsIgnoreCase(otherContext.getApnType())) return false;
21793fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (otherContext.isEnabled() && otherContext.getState() != DctConstants.State.FAILED) {
21803fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                return true;
21813fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
21823fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
21833fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return false;
21843fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    }
21853fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
21863fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    /**
21873fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * Reports if we support multiple connections or not.
21883fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * This is a combination of factors, based on carrier and RAT.
21893fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @param rilRadioTech the RIL Radio Tech currently in use
21903fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return true if only single DataConnection is allowed
21913fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     */
21923fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean isOnlySingleDcAllowed(int rilRadioTech) {
2193bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        // Default single dc rats with no knowledge of carrier
2194bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        int[] singleDcRats = null;
2195bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        // get the carrier specific value, if it exists, from CarrierConfigManager.
2196bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        // generally configManager and bundle should not be null, but if they are it should be okay
2197bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        // to leave singleDcRats null as well
2198bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        CarrierConfigManager configManager = (CarrierConfigManager)
2199bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu                mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
2200bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        if (configManager != null) {
2201bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu            PersistableBundle bundle = configManager.getConfig();
2202bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu            if (bundle != null) {
2203bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu                singleDcRats = bundle.getIntArray(
2204bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu                        CarrierConfigManager.KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY);
2205bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu            }
2206bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        }
22073fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        boolean onlySingleDcAllowed = false;
22083fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (Build.IS_DEBUGGABLE &&
22093fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                SystemProperties.getBoolean("persist.telephony.test.singleDc", false)) {
22103fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            onlySingleDcAllowed = true;
22113fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
22123fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (singleDcRats != null) {
22133fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            for (int i=0; i < singleDcRats.length && onlySingleDcAllowed == false; i++) {
22143fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (rilRadioTech == singleDcRats[i]) onlySingleDcAllowed = true;
22153fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
22163fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
22173fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
22183fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (DBG) log("isOnlySingleDcAllowed(" + rilRadioTech + "): " + onlySingleDcAllowed);
22193fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return onlySingleDcAllowed;
22203fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    }
22213fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
22221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    void sendRestartRadio() {
22231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG)log("sendRestartRadio:");
22241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_RESTART_RADIO);
22251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
22261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
22271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
22281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void restartRadio() {
2229cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("restartRadio: ************TURN OFF RADIO**************");
2230cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, Phone.REASON_RADIO_TURNED_OFF);
2231cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().powerOffRadioSafely(this);
2232cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        /* Note: no need to call setRadioPower(true).  Assuming the desired
2233cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * radio power state is still ON (as tracked by ServiceStateTracker),
2234cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * ServiceStateTracker will call setRadioPower when it receives the
2235cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * RADIO_STATE_CHANGED notification for the power off.  And if the
2236cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * desired power state has changed in the interim, we don't want to
2237cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * override it with an unconditional power on.
2238cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         */
2239cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2240cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int reset = Integer.parseInt(SystemProperties.get("net.ppp.reset-by-timeout", "0"));
22410e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        SystemProperties.set("net.ppp.reset-by-timeout", String.valueOf(reset + 1));
2242cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2243cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2244cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
2245cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Return true if data connection need to be setup after disconnected due to
2246cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * reason.
2247cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
22480e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu     * @param apnContext APN context
2249cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return true if try setup data connection is need for this reason
2250cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
22513fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean retryAfterDisconnected(ApnContext apnContext) {
2252cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean retry = true;
22533fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        String reason = apnContext.getReason();
2254cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
22553fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) ||
22563fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())
22573fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                 && isHigherPriorityApnContextActive(apnContext))) {
2258cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            retry = false;
2259cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2260cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return retry;
2261cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2262cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
22630e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    private void startAlarmForReconnect(long delay, ApnContext apnContext) {
2264cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String apnType = apnContext.getApnType();
226574672e8ee972f12406b72551261b4cc7e0651933Wink Saville
226674672e8ee972f12406b72551261b4cc7e0651933Wink Saville        Intent intent = new Intent(INTENT_RECONNECT_ALARM + "." + apnType);
226774672e8ee972f12406b72551261b4cc7e0651933Wink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, apnContext.getReason());
2268cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, apnType);
226967d43cfed4b996c20780bfec8fde1ae8c1391779Junda Liu        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
2270cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2271a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // Get current sub id.
22724f580e63be8e5787ce636c3b47335529ceb973b9Susheel nyamala        int subId = mPhone.getSubId();
2273a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
2274a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
227574672e8ee972f12406b72551261b4cc7e0651933Wink Saville        if (DBG) {
227674672e8ee972f12406b72551261b4cc7e0651933Wink Saville            log("startAlarmForReconnect: delay=" + delay + " action=" + intent.getAction()
227774672e8ee972f12406b72551261b4cc7e0651933Wink Saville                    + " apn=" + apnContext);
227874672e8ee972f12406b72551261b4cc7e0651933Wink Saville        }
227974672e8ee972f12406b72551261b4cc7e0651933Wink Saville
22800e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        PendingIntent alarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0,
2281cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                        intent, PendingIntent.FLAG_UPDATE_CURRENT);
2282ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setReconnectIntent(alarmIntent);
22837d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu
22847d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu        // Use the exact timer instead of the inexact one to provide better user experience.
22857d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu        // In some extreme cases, we saw the retry was delayed for few minutes.
22860852a954be5937a1b0bca94df0c2007d7ee3c0c7Jack Yu        // Note that if the stated trigger time is in the past, the alarm will be triggered
22870852a954be5937a1b0bca94df0c2007d7ee3c0c7Jack Yu        // immediately.
22887d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu        mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
2289cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                SystemClock.elapsedRealtime() + delay, alarmIntent);
2290cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2291cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2292ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void notifyNoData(DcFailCause lastFailCauseCode,
2293cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                              ApnContext apnContext) {
2294cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log( "notifyNoData: type=" + apnContext.getApnType());
2295ccfe5ebaf81c1378e8dbe44e45df26b0dc462a21Jack Yu        if (isPermanentFailure(lastFailCauseCode)
2296cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            && (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT))) {
2297cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
2298cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2299cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2300cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
23011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public boolean getAutoAttachOnCreation() {
23021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mAutoAttachOnCreation.get();
23031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
23041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
23051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRecordsLoadedOrSubIdChanged() {
23061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("onRecordsLoadedOrSubIdChanged: createAllApnList");
230712fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        mAutoAttachOnCreationConfig = mPhone.getContext().getResources()
230812fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao                .getBoolean(com.android.internal.R.bool.config_auto_attach_data_on_creation);
2309bda761320929f714951c328bfec6a51a1978db97Wink Saville
2310cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        createAllApnList();
23115d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi        setInitialAttachApn();
231222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPhone.mCi.getRadioState().isOn()) {
23131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("onRecordsLoadedOrSubIdChanged: notifying data availability");
2314cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_SIM_LOADED);
2315cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2316bda761320929f714951c328bfec6a51a1978db97Wink Saville        setupDataOnConnectableApns(Phone.REASON_SIM_LOADED);
2317cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2318cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
23194c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu    /**
23204c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu     * Action set from carrier signalling broadcast receivers to enable/disable metered apns.
23214c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu     */
23226a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu    private void onSetCarrierDataEnabled(AsyncResult ar) {
23236a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu        if (ar.exception != null) {
23246a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu            Rlog.e(LOG_TAG, "CarrierDataEnable exception: " + ar.exception);
23256a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu            return;
23266a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu        }
232712161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen        boolean enabled = (boolean) ar.result;
232812161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen        if (enabled != mDataEnabledSettings.isCarrierDataEnabled()) {
232912161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen            if (DBG) {
233012161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen                log("carrier Action: set metered apns enabled: " + enabled);
233112161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen            }
2332a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
233312161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen            // Disable/enable all metered apns
233412161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen            mDataEnabledSettings.setCarrierDataEnabled(enabled);
2335a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
233612161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen            if (!enabled) {
233712161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen                // Send otasp_sim_unprovisioned so that SuW is able to proceed and notify users
233812161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen                mPhone.notifyOtaspChanged(TelephonyManager.OTASP_SIM_UNPROVISIONED);
233912161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen                // Tear down all metered apns
234012161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen                cleanUpAllConnections(true, Phone.REASON_CARRIER_ACTION_DISABLE_METERED_APN);
234112161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen            } else {
234212161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen                // Re-evaluate Otasp state
234312161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen                int otaspState = mPhone.getServiceStateTracker().getOtasp();
234412161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen                mPhone.notifyOtaspChanged(otaspState);
23454839eb565b4294443a34a93ee2ca93ac70b72b87fionaxu
234612161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen                reevaluateDataConnections();
234712161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen                setupDataOnConnectableApns(Phone.REASON_DATA_ENABLED);
234868f4f4a0bc8d4060b5775e7a24a97ea5b485989efionaxu            }
2349a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        }
2350a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    }
2351a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
23520469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal    private void onSimNotReady() {
23530469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        if (DBG) log("onSimNotReady");
23540469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal
23550469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        cleanUpAllConnections(true, Phone.REASON_SIM_NOT_READY);
23560469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        mAllApnSettings = null;
23570469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        mAutoAttachOnCreationConfig = false;
23587e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C        // Clear auto attach as modem is expected to do a new attach once SIM is ready
23597e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C        mAutoAttachOnCreation.set(false);
23600469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal    }
23610469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal
23621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetDependencyMet(String apnType, boolean met) {
2363cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // don't allow users to tweak hipri to work around default dependency not met
2364cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_HIPRI.equals(apnType)) return;
2365cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2366cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
2367cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
2368cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onSetDependencyMet: ApnContext not found in onSetDependencyMet(" +
2369cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnType + ", " + met + ")");
2370cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
2371cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2372cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        applyNewState(apnContext, apnContext.isEnabled(), met);
2373cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_DEFAULT.equals(apnType)) {
2374cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // tie actions on default to similar actions on HIPRI regarding dependencyMet
2375cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext = mApnContexts.get(PhoneConstants.APN_TYPE_HIPRI);
2376cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext != null) applyNewState(apnContext, apnContext.isEnabled(), met);
2377cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2378cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2379c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2380a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    public void setPolicyDataEnabled(boolean enabled) {
2381a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        if (DBG) log("setPolicyDataEnabled: " + enabled);
2382a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        Message msg = obtainMessage(DctConstants.CMD_SET_POLICY_DATA_ENABLE);
2383a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        msg.arg1 = (enabled ? DctConstants.ENABLED : DctConstants.DISABLED);
2384a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        sendMessage(msg);
2385a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    }
2386a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
23871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetPolicyDataEnabled(boolean enabled) {
238812161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen        final boolean prevEnabled = isDataEnabled();
238912161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen        if (mDataEnabledSettings.isPolicyDataEnabled() != enabled) {
239012161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen            mDataEnabledSettings.setPolicyDataEnabled(enabled);
239112161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen            // TODO: We should register for DataEnabledSetting's data enabled/disabled event and
239212161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen            // handle the rest from there.
239312161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen            if (prevEnabled != isDataEnabled()) {
239412161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen                if (!prevEnabled) {
239512161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen                    reevaluateDataConnections();
239612161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen                    onTrySetupData(Phone.REASON_DATA_ENABLED);
239712161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen                } else {
239812161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen                    onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);
23991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
24001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
24011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
24021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
24031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2404cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void applyNewState(ApnContext apnContext, boolean enabled, boolean met) {
2405cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean cleanup = false;
2406cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean trySetup = false;
24072dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        String str ="applyNewState(" + apnContext.getApnType() + ", " + enabled +
24082dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                "(" + apnContext.isEnabled() + "), " + met + "(" +
24092dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                apnContext.getDependencyMet() +"))";
24102dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        if (DBG) log(str);
24112dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog(str);
24122dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt
2413cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext.isReady()) {
2414305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt            cleanup = true;
24152428693913ae731d4ace3414429f5e91af24ea36Wink Saville            if (enabled && met) {
24162428693913ae731d4ace3414429f5e91af24ea36Wink Saville                DctConstants.State state = apnContext.getState();
24172428693913ae731d4ace3414429f5e91af24ea36Wink Saville                switch(state) {
24182428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case CONNECTING:
24192428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case CONNECTED:
24202428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case DISCONNECTING:
24212428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // We're "READY" and active so just return
24222428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        if (DBG) log("applyNewState: 'ready' so return");
24232dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        apnContext.requestLog("applyNewState state=" + state + ", so return");
24242428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        return;
24252428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case IDLE:
24262428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // fall through: this is unexpected but if it happens cleanup and try setup
24272428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case FAILED:
24289d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu                    case SCANNING:
24292428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case RETRYING: {
24302428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // We're "READY" but not active so disconnect (cleanup = true) and
24312428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // connect (trySetup = true) to be sure we retry the connection.
24322428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        trySetup = true;
24332428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        apnContext.setReason(Phone.REASON_DATA_ENABLED);
24342428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        break;
24352428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    }
24362428693913ae731d4ace3414429f5e91af24ea36Wink Saville                }
2437305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt            } else if (met) {
2438cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setReason(Phone.REASON_DATA_DISABLED);
2439305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // If ConnectivityService has disabled this network, stop trying to bring
2440305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // it up, but do not tear it down - ConnectivityService will do that
2441305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // directly by talking with the DataConnection.
24421484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                //
24431484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // This doesn't apply to DUN, however.  Those connections have special
24441484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // requirements from carriers and we need stop using them when the dun
24451484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // request goes away.  This applies to both CDMA and GSM because they both
24461484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // can declare the DUN APN sharable by default traffic, thus still satisfying
24471484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // those requests and not torn down organically.
24489db4884401d436d0796138f9190079df310cee95Sukanya Rajkhowa                if ((apnContext.getApnType() == PhoneConstants.APN_TYPE_DUN && teardownForDun())
24499db4884401d436d0796138f9190079df310cee95Sukanya Rajkhowa                        || apnContext.getState() != DctConstants.State.CONNECTED) {
24509db4884401d436d0796138f9190079df310cee95Sukanya Rajkhowa                    str = "Clean up the connection. Apn type = " + apnContext.getApnType()
24519db4884401d436d0796138f9190079df310cee95Sukanya Rajkhowa                            + ", state = " + apnContext.getState();
24529db4884401d436d0796138f9190079df310cee95Sukanya Rajkhowa                    if (DBG) log(str);
24539db4884401d436d0796138f9190079df310cee95Sukanya Rajkhowa                    apnContext.requestLog(str);
24541484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    cleanup = true;
24551484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                } else {
24561484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    cleanup = false;
24571484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                }
2458cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
2459cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_UNMET);
2460cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2461cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2462cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (enabled && met) {
2463cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apnContext.isEnabled()) {
2464cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_MET);
2465cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2466cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setReason(Phone.REASON_DATA_ENABLED);
2467c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
2468cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apnContext.getState() == DctConstants.State.FAILED) {
2469cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setState(DctConstants.State.IDLE);
2470cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2471cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                trySetup = true;
2472cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2473cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2474cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setEnabled(enabled);
2475cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setDependencyMet(met);
2476cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cleanup) cleanUpConnection(true, apnContext);
24770d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt        if (trySetup) {
24780d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt            apnContext.resetErrorCodeRetries();
24790d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt            trySetupData(apnContext);
24800d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt        }
2481cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2482c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2483454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel checkForCompatibleConnectedApnContext(ApnContext apnContext) {
2484cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String apnType = apnContext.getApnType();
24852abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu        ArrayList<ApnSetting> dunSettings = null;
2486cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2487cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_DUN.equals(apnType)) {
24882abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu            dunSettings = sortApnListByPreferred(fetchDunApns());
2489cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2490ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) {
2491ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            log("checkForCompatibleConnectedApnContext: apnContext=" + apnContext );
2492ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
2493cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2494454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel potentialDcac = null;
2495ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnContext potentialApnCtx = null;
2496ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        for (ApnContext curApnCtx : mApnContexts.values()) {
2497454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel curDcac = curApnCtx.getDcAc();
2498ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (curDcac != null) {
2499ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                ApnSetting apnSetting = curApnCtx.getApnSetting();
2500a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("apnSetting: " + apnSetting);
25012abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                if (dunSettings != null && dunSettings.size() > 0) {
25022abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                    for (ApnSetting dunSetting : dunSettings) {
25032abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                        if (dunSetting.equals(apnSetting)) {
25042abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                            switch (curApnCtx.getState()) {
25052abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                                case CONNECTED:
25062abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                                    if (DBG) {
25072abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                                        log("checkForCompatibleConnectedApnContext:"
25082abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                                                + " found dun conn=" + curDcac
25092abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                                                + " curApnCtx=" + curApnCtx);
25102abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                                    }
25112abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                                    return curDcac;
25122abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                                case RETRYING:
25132abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                                case CONNECTING:
25142abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                                    potentialDcac = curDcac;
25152abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                                    potentialApnCtx = curApnCtx;
25162abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                                    break;
25172abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                                default:
25182abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                                    // Not connected, potential unchanged
25192abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                                    break;
25202abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                            }
2521cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
2522cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2523cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else if (apnSetting != null && apnSetting.canHandleType(apnType)) {
2524ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    switch (curApnCtx.getState()) {
2525cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        case CONNECTED:
2526cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            if (DBG) {
2527ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                log("checkForCompatibleConnectedApnContext:"
2528ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        + " found canHandle conn=" + curDcac
2529ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        + " curApnCtx=" + curApnCtx);
2530cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            }
2531ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            return curDcac;
2532ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        case RETRYING:
2533cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        case CONNECTING:
2534ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            potentialDcac = curDcac;
2535ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            potentialApnCtx = curApnCtx;
25362abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                            break;
2537cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        default:
2538cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            // Not connected, potential unchanged
2539cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            break;
2540cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2541cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2542ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            } else {
2543ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) {
2544ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    log("checkForCompatibleConnectedApnContext: not conn curApnCtx=" + curApnCtx);
2545ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                }
2546cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2547cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2548ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (potentialDcac != null) {
2549cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
2550ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                log("checkForCompatibleConnectedApnContext: found potential conn=" + potentialDcac
2551ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        + " curApnCtx=" + potentialApnCtx);
2552cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2553ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            return potentialDcac;
2554cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2555c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2556ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("checkForCompatibleConnectedApnContext: NO conn apnContext=" + apnContext);
2557cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
2558cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2559c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
256027b650c406018355a88a41528db7859e232728a0Jack Yu    public void setEnabled(int id, boolean enable) {
25611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_ENABLE_NEW_APN);
25621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = id;
25631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg2 = (enable ? DctConstants.ENABLED : DctConstants.DISABLED);
25641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
25651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
25661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
25671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onEnableApn(int apnId, int enabled) {
2568af5593594070f825032be46dced573cd195956e1Robert Greenwalt        ApnContext apnContext = mApnContextsById.get(apnId);
2569cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
2570cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onEnableApn(" + apnId + ", " + enabled + "): NO ApnContext");
2571cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
2572cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2573cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO change our retry manager to use the appropriate numbers for the new APN
2574cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onEnableApn: apnContext=" + apnContext + " call applyNewState");
2575cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        applyNewState(apnContext, enabled == DctConstants.ENABLED, apnContext.getDependencyMet());
2576af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla
2577af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla        if ((enabled == DctConstants.DISABLED) &&
2578af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology()) &&
2579af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            !isHigherPriorityApnContextActive(apnContext)) {
2580af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla
2581af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            if(DBG) log("onEnableApn: isOnlySingleDcAllowed true & higher priority APN disabled");
2582af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            // If the highest priority APN is disabled and only single
2583af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            // data call is allowed, try to setup data call on other connectable APN.
2584af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            setupDataOnConnectableApns(Phone.REASON_SINGLE_PDN_ARBITRATION);
2585af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla        }
2586cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2587c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2588cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // TODO: We shouldnt need this.
25891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean onTrySetupData(String reason) {
2590cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onTrySetupData: reason=" + reason);
2591ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(reason);
2592cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
2593cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2594c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
25951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean onTrySetupData(ApnContext apnContext) {
2596cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onTrySetupData: apnContext=" + apnContext);
2597cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return trySetupData(apnContext);
2598cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2599c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
26001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
2601a64092befe003884c4c8951438ab311ce8f92824Malcolm Chen     * Whether data is enabled by user. Unlike isDataEnabled, this only
2602a64092befe003884c4c8951438ab311ce8f92824Malcolm Chen     * checks user setting stored in {@link android.provider.Settings.Global#MOBILE_DATA}
2603a64092befe003884c4c8951438ab311ce8f92824Malcolm Chen     * if not provisioning, or isProvisioningDataEnabled if provisioning.
26041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
2605a64092befe003884c4c8951438ab311ce8f92824Malcolm Chen    public boolean isUserDataEnabled() {
2606985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen        if (mDataEnabledSettings.isProvisioning()) {
2607985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen            return mDataEnabledSettings.isProvisioningDataEnabled();
2608f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        } else {
2609985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen            return mDataEnabledSettings.isUserDataEnabled();
26101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
26111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
26121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
26131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
261421e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * Modify {@link android.provider.Settings.Global#DATA_ROAMING} value for user modification only
26151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
261621e6af8d6197a071d025733fffeffc157d0085bcfionaxu    public void setDataRoamingEnabledByUser(boolean enabled) {
26171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        final int phoneSubId = mPhone.getSubId();
26185b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (getDataRoamingEnabled() != enabled) {
26191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            int roaming = enabled ? 1 : 0;
26201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
26211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // For single SIM phones, this is a per phone property.
26221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (TelephonyManager.getDefault().getSimCount() == 1) {
26231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Settings.Global.putInt(mResolver, Settings.Global.DATA_ROAMING, roaming);
262421e6af8d6197a071d025733fffeffc157d0085bcfionaxu                setDataRoamingFromUserAction(true);
26251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
26261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Settings.Global.putInt(mResolver, Settings.Global.DATA_ROAMING +
26271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                         phoneSubId, roaming);
26281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
26291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
26301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSubscriptionManager.setDataRoaming(roaming, phoneSubId);
26311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // will trigger handleDataOnRoamingChange() through observer
26321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
263321e6af8d6197a071d025733fffeffc157d0085bcfionaxu                log("setDataRoamingEnabledByUser: set phoneSubId=" + phoneSubId
26345b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu                        + " isRoaming=" + enabled);
26351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
26361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
26371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
263821e6af8d6197a071d025733fffeffc157d0085bcfionaxu                log("setDataRoamingEnabledByUser: unchanged phoneSubId=" + phoneSubId
26391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        + " isRoaming=" + enabled);
26401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu             }
26411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
26421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
26431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
26441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
26451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Return current {@link android.provider.Settings.Global#DATA_ROAMING} value.
26461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
26475b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    public boolean getDataRoamingEnabled() {
264821e6af8d6197a071d025733fffeffc157d0085bcfionaxu        boolean isDataRoamingEnabled;
26491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        final int phoneSubId = mPhone.getSubId();
26501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2651985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen        // For single SIM phones, this is a per phone property.
2652985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen        if (TelephonyManager.getDefault().getSimCount() == 1) {
2653985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen            isDataRoamingEnabled = Settings.Global.getInt(mResolver,
2654985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen                    Settings.Global.DATA_ROAMING,
2655985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen                    getDefaultDataRoamingEnabled() ? 1 : 0) != 0;
2656985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen        } else {
2657985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen            isDataRoamingEnabled = Settings.Global.getInt(mResolver,
2658985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen                    Settings.Global.DATA_ROAMING + phoneSubId,
2659985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen                    getDefaultDataRoamingEnabled() ? 1 : 0) != 0;
26601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
2661985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen
26621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) {
26635b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            log("getDataRoamingEnabled: phoneSubId=" + phoneSubId
26645b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu                    + " isDataRoamingEnabled=" + isDataRoamingEnabled);
26651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
26661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return isDataRoamingEnabled;
26671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
26681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
266921e6af8d6197a071d025733fffeffc157d0085bcfionaxu    /**
267021e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * get default values for {@link Settings.Global#DATA_ROAMING}
267121e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * return {@code true} if either
267221e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} or
267321e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * system property ro.com.android.dataroaming is set to true. otherwise return {@code false}
267421e6af8d6197a071d025733fffeffc157d0085bcfionaxu     */
267521e6af8d6197a071d025733fffeffc157d0085bcfionaxu    private boolean getDefaultDataRoamingEnabled() {
267621e6af8d6197a071d025733fffeffc157d0085bcfionaxu        final CarrierConfigManager configMgr = (CarrierConfigManager)
267721e6af8d6197a071d025733fffeffc157d0085bcfionaxu                mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
267821e6af8d6197a071d025733fffeffc157d0085bcfionaxu        boolean isDataRoamingEnabled = "true".equalsIgnoreCase(SystemProperties.get(
267921e6af8d6197a071d025733fffeffc157d0085bcfionaxu                "ro.com.android.dataroaming", "false"));
268021e6af8d6197a071d025733fffeffc157d0085bcfionaxu        isDataRoamingEnabled |= configMgr.getConfigForSubId(mPhone.getSubId()).getBoolean(
268121e6af8d6197a071d025733fffeffc157d0085bcfionaxu                CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
268221e6af8d6197a071d025733fffeffc157d0085bcfionaxu        return isDataRoamingEnabled;
268321e6af8d6197a071d025733fffeffc157d0085bcfionaxu    }
268421e6af8d6197a071d025733fffeffc157d0085bcfionaxu
268521e6af8d6197a071d025733fffeffc157d0085bcfionaxu    /**
268621e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * Set default value for {@link android.provider.Settings.Global#DATA_ROAMING}
268721e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * if the setting is not from user actions. default value is based on carrier config and system
268821e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * properties.
268921e6af8d6197a071d025733fffeffc157d0085bcfionaxu     */
269021e6af8d6197a071d025733fffeffc157d0085bcfionaxu    private void setDefaultDataRoamingEnabled() {
269121e6af8d6197a071d025733fffeffc157d0085bcfionaxu        // For single SIM phones, this is a per phone property.
269221e6af8d6197a071d025733fffeffc157d0085bcfionaxu        String setting = Settings.Global.DATA_ROAMING;
269321e6af8d6197a071d025733fffeffc157d0085bcfionaxu        boolean useCarrierSpecificDefault = false;
269421e6af8d6197a071d025733fffeffc157d0085bcfionaxu        if (TelephonyManager.getDefault().getSimCount() != 1) {
269521e6af8d6197a071d025733fffeffc157d0085bcfionaxu            setting = setting + mPhone.getSubId();
269621e6af8d6197a071d025733fffeffc157d0085bcfionaxu            try {
269721e6af8d6197a071d025733fffeffc157d0085bcfionaxu                Settings.Global.getInt(mResolver, setting);
269821e6af8d6197a071d025733fffeffc157d0085bcfionaxu            } catch (SettingNotFoundException ex) {
269921e6af8d6197a071d025733fffeffc157d0085bcfionaxu                // For msim, update to carrier default if uninitialized.
270021e6af8d6197a071d025733fffeffc157d0085bcfionaxu                useCarrierSpecificDefault = true;
270121e6af8d6197a071d025733fffeffc157d0085bcfionaxu            }
270221e6af8d6197a071d025733fffeffc157d0085bcfionaxu        } else if (!isDataRoamingFromUserAction()) {
270321e6af8d6197a071d025733fffeffc157d0085bcfionaxu            // for single sim device, update to carrier default if user action is not set
270421e6af8d6197a071d025733fffeffc157d0085bcfionaxu            useCarrierSpecificDefault = true;
270521e6af8d6197a071d025733fffeffc157d0085bcfionaxu        }
270621e6af8d6197a071d025733fffeffc157d0085bcfionaxu        if (useCarrierSpecificDefault) {
270721e6af8d6197a071d025733fffeffc157d0085bcfionaxu            boolean defaultVal = getDefaultDataRoamingEnabled();
270821e6af8d6197a071d025733fffeffc157d0085bcfionaxu            log("setDefaultDataRoamingEnabled: " + setting + "default value: " + defaultVal);
270921e6af8d6197a071d025733fffeffc157d0085bcfionaxu            Settings.Global.putInt(mResolver, setting, defaultVal ? 1 : 0);
271021e6af8d6197a071d025733fffeffc157d0085bcfionaxu            mSubscriptionManager.setDataRoaming(defaultVal ? 1 : 0, mPhone.getSubId());
271121e6af8d6197a071d025733fffeffc157d0085bcfionaxu        }
271221e6af8d6197a071d025733fffeffc157d0085bcfionaxu    }
271321e6af8d6197a071d025733fffeffc157d0085bcfionaxu
271421e6af8d6197a071d025733fffeffc157d0085bcfionaxu    private boolean isDataRoamingFromUserAction() {
271521e6af8d6197a071d025733fffeffc157d0085bcfionaxu        final SharedPreferences sp = PreferenceManager
271621e6af8d6197a071d025733fffeffc157d0085bcfionaxu                .getDefaultSharedPreferences(mPhone.getContext());
271721e6af8d6197a071d025733fffeffc157d0085bcfionaxu        // since we don't want to unset user preference from system update, pass true as the default
271821e6af8d6197a071d025733fffeffc157d0085bcfionaxu        // value if shared pref does not exist and set shared pref to false explicitly from factory
271921e6af8d6197a071d025733fffeffc157d0085bcfionaxu        // reset.
272021e6af8d6197a071d025733fffeffc157d0085bcfionaxu        if (!sp.contains(Phone.DATA_ROAMING_IS_USER_SETTING_KEY)
272121e6af8d6197a071d025733fffeffc157d0085bcfionaxu                && Settings.Global.getInt(mResolver, Settings.Global.DEVICE_PROVISIONED, 0) == 0) {
272221e6af8d6197a071d025733fffeffc157d0085bcfionaxu            sp.edit().putBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, false).commit();
272321e6af8d6197a071d025733fffeffc157d0085bcfionaxu        }
272421e6af8d6197a071d025733fffeffc157d0085bcfionaxu        return sp.getBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, true);
272521e6af8d6197a071d025733fffeffc157d0085bcfionaxu    }
272621e6af8d6197a071d025733fffeffc157d0085bcfionaxu
272721e6af8d6197a071d025733fffeffc157d0085bcfionaxu    private void setDataRoamingFromUserAction(boolean isUserAction) {
272821e6af8d6197a071d025733fffeffc157d0085bcfionaxu        final SharedPreferences.Editor sp = PreferenceManager
272921e6af8d6197a071d025733fffeffc157d0085bcfionaxu                .getDefaultSharedPreferences(mPhone.getContext()).edit();
273021e6af8d6197a071d025733fffeffc157d0085bcfionaxu        sp.putBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, isUserAction).commit();
273121e6af8d6197a071d025733fffeffc157d0085bcfionaxu    }
273221e6af8d6197a071d025733fffeffc157d0085bcfionaxu
27335b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    // When the data roaming status changes from roaming to non-roaming.
27345b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    private void onDataRoamingOff() {
27355b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (DBG) log("onDataRoamingOff");
2736c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
27375b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (!getDataRoamingEnabled()) {
27385b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // TODO: Remove this once all old vendor RILs are gone. We don't need to set initial apn
27395b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // attach and send the data profile again as the modem should have both roaming and
27405b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // non-roaming protocol in place. Modem should choose the right protocol based on the
27415b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // roaming condition.
27425b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            setInitialAttachApn();
27435b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            setDataProfilesAsNeeded();
27448e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu
27455b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // If the user did not enable data roaming, now when we transit from roaming to
27465b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // non-roaming, we should try to reestablish the data connection.
2747c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2748cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_OFF);
2749bda761320929f714951c328bfec6a51a1978db97Wink Saville            setupDataOnConnectableApns(Phone.REASON_ROAMING_OFF);
2750cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2751cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_ROAMING_OFF);
2752cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2753cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2754cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
27555b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    // This method is called
27565b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    // 1. When the data roaming status changes from non-roaming to roaming.
27575b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    // 2. When allowed data roaming settings is changed by the user.
2758d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen    private void onDataRoamingOnOrSettingsChanged(int messageType) {
27595b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (DBG) log("onDataRoamingOnOrSettingsChanged");
2760d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen        // Used to differentiate data roaming turned on vs settings changed.
2761d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen        boolean settingChanged = (messageType == DctConstants.EVENT_ROAMING_SETTING_CHANGE);
2762f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu
2763f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu        // Check if the device is actually data roaming
2764f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu        if (!mPhone.getServiceState().getDataRoaming()) {
2765f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu            if (DBG) log("device is not roaming. ignored the request.");
2766f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu            return;
2767f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu        }
2768cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2769d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen        checkDataRoamingStatus(settingChanged);
2770d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen
27715b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (getDataRoamingEnabled()) {
27725b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            if (DBG) log("onDataRoamingOnOrSettingsChanged: setup data on roaming");
27735b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu
2774ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_ROAMING_ON);
2775cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_ROAMING_ON);
2776cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
27775b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // If the user does not turn on data roaming, when we transit from non-roaming to
27785b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // roaming, we need to tear down the data connection otherwise the user might be
27795b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // charged for data roaming usage.
27805b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            if (DBG) log("onDataRoamingOnOrSettingsChanged: Tear down data connection on roaming.");
2781cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpAllConnections(true, Phone.REASON_ROAMING_ON);
2782cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
2783cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2784cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2785cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2786d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen    // We want to track possible roaming data leakage. Which is, if roaming setting
2787d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen    // is disabled, yet we still setup a roaming data connection or have a connected ApnContext
2788d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen    // switched to roaming. When this happens, we log it in a local log.
2789d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen    private void checkDataRoamingStatus(boolean settingChanged) {
2790d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen        if (!settingChanged && !getDataRoamingEnabled()
2791d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                && mPhone.getServiceState().getDataRoaming()) {
2792d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen            for (ApnContext apnContext : mApnContexts.values()) {
2793d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                if (apnContext.getState() == DctConstants.State.CONNECTED) {
2794d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                    mDataRoamingLeakageLog.log("PossibleRoamingLeakage "
2795d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                            + " connection params: " + (apnContext.getDcAc() != null
2796d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                            ? apnContext.getDcAc().mLastConnectionParams : ""));
2797d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                }
2798d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen            }
2799d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen        }
2800d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen    }
2801d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen
28021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRadioAvailable() {
2803cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onRadioAvailable");
2804cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
2805cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
2806cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
2807cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // setState(DctConstants.State.CONNECTED);
2808cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(null);
2809cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2810cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("onRadioAvailable: We're on the simulator; assuming data is connected");
2811cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2812cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2813cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
2814cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (r != null && r.getRecordsLoaded()) {
2815cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(null);
2816cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2817cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2818cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getOverallState() != DctConstants.State.IDLE) {
2819cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpConnection(true, null);
2820cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2821cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2822cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
28231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRadioOffOrNotAvailable() {
2824cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Make sure our reconnect delay starts at the initial value
2825cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // next time the radio comes on
2826cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2827cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mReregisterOnReconnectFailure = false;
2828cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
28297e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C        // Clear auto attach as modem is expected to do a new attach
28307e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C        mAutoAttachOnCreation.set(false);
28317e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C
2832cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
2833cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
2834cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
2835cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("We're on the simulator; assuming radio off is meaningless");
2836cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2837cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRadioOffOrNotAvailable: is off and clean up all connections");
2838cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpAllConnections(false, Phone.REASON_RADIO_TURNED_OFF);
2839cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2840cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyOffApnsOfAvailability(null);
2841cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2842cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
28431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void completeConnection(ApnContext apnContext) {
2844c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2845c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (DBG) log("completeConnection: successful, notify the world apnContext=" + apnContext);
2846c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2847c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (mIsProvisioning && !TextUtils.isEmpty(mProvisioningUrl)) {
2848c9b81a0c05128694c617fcdd67e73821895822feWink Saville            if (DBG) {
2849c9b81a0c05128694c617fcdd67e73821895822feWink Saville                log("completeConnection: MOBILE_PROVISIONING_ACTION url="
2850c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        + mProvisioningUrl);
2851c9b81a0c05128694c617fcdd67e73821895822feWink Saville            }
2852c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt            Intent newIntent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN,
2853c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt                    Intent.CATEGORY_APP_BROWSER);
2854c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt            newIntent.setData(Uri.parse(mProvisioningUrl));
2855c9b81a0c05128694c617fcdd67e73821895822feWink Saville            newIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
2856c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    Intent.FLAG_ACTIVITY_NEW_TASK);
2857c9b81a0c05128694c617fcdd67e73821895822feWink Saville            try {
2858c9b81a0c05128694c617fcdd67e73821895822feWink Saville                mPhone.getContext().startActivity(newIntent);
2859c9b81a0c05128694c617fcdd67e73821895822feWink Saville            } catch (ActivityNotFoundException e) {
2860c9b81a0c05128694c617fcdd67e73821895822feWink Saville                loge("completeConnection: startActivityAsUser failed" + e);
2861c9b81a0c05128694c617fcdd67e73821895822feWink Saville            }
2862c9b81a0c05128694c617fcdd67e73821895822feWink Saville        }
2863c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mIsProvisioning = false;
2864c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mProvisioningUrl = null;
28652b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        if (mProvisioningSpinner != null) {
28662b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            sendMessage(obtainMessage(DctConstants.CMD_CLEAR_PROVISIONING_SPINNER,
28672b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner));
28682b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        }
2869c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2870c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
2871c9b81a0c05128694c617fcdd67e73821895822feWink Saville        startNetStatPoll();
2872c9b81a0c05128694c617fcdd67e73821895822feWink Saville        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
2873c9b81a0c05128694c617fcdd67e73821895822feWink Saville    }
2874c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2875ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
2876ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * A SETUP (aka bringUp) has completed, possibly with an error. If
2877ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * there is an error this method will call {@link #onDataSetupCompleteError}.
2878ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
28791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataSetupComplete(AsyncResult ar) {
2880608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt
2881ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        DcFailCause cause = DcFailCause.UNKNOWN;
2882cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean handleError = false;
2883ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDataSetupComplete");
2884cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2885ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
2886cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2887cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (ar.exception == null) {
2888454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = apnContext.getDcAc();
2889cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2890cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (RADIO_TESTS) {
2891cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Note: To change radio.test.onDSC.null.dcac from command line you need to
2892cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // adb root and adb remount and from the command line you can only change the
2893cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // value to 1 once. To change it a second time you can reboot or execute
2894cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // adb shell stop and then adb shell start. The command line to set the value is:
2895ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink 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');"
2896cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ContentResolver cr = mPhone.getContext().getContentResolver();
2897cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                String radioTestProperty = "radio.test.onDSC.null.dcac";
2898cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (Settings.System.getInt(cr, radioTestProperty, 0) == 1) {
2899cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: " + radioTestProperty +
2900cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            " is true, set dcac to null and reset property to false");
2901cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    dcac = null;
2902cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    Settings.System.putInt(cr, radioTestProperty, 0);
2903cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: " + radioTestProperty + "=" +
2904cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            Settings.System.getInt(mPhone.getContext().getContentResolver(),
2905cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                    radioTestProperty, -1));
2906cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2907c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2908cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac == null) {
2909cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("onDataSetupComplete: no connection to DC, handle as error");
2910ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                cause = DcFailCause.CONNECTION_TO_DATACONNECTIONAC_BROKEN;
2911cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                handleError = true;
2912cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
2913cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ApnSetting apn = apnContext.getApnSetting();
2914cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
2915cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: success apn=" + (apn == null ? "unknown" : apn.apn));
2916cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2917cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn != null && apn.proxy != null && apn.proxy.length() != 0) {
2918cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    try {
2919cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        String port = apn.port;
2920cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (TextUtils.isEmpty(port)) port = "8080";
29219c180aedfc9f0d20525c0128487d3500e6c0a715Jason Monk                        ProxyInfo proxy = new ProxyInfo(apn.proxy,
2922cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                Integer.parseInt(port), null);
2923cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        dcac.setLinkPropertiesHttpProxySync(proxy);
2924cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    } catch (NumberFormatException e) {
2925cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        loge("onDataSetupComplete: NumberFormatException making ProxyProperties (" +
2926cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                apn.port + "): " + e);
2927cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2928cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2929cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2930cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // everything is setup
2931d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                if (TextUtils.equals(apnContext.getApnType(), PhoneConstants.APN_TYPE_DEFAULT)) {
293227b650c406018355a88a41528db7859e232728a0Jack Yu                    try {
293327b650c406018355a88a41528db7859e232728a0Jack Yu                        SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "true");
293427b650c406018355a88a41528db7859e232728a0Jack Yu                    } catch (RuntimeException ex) {
293527b650c406018355a88a41528db7859e232728a0Jack Yu                        log("Failed to set PUPPET_MASTER_RADIO_STRESS_TEST to true");
293627b650c406018355a88a41528db7859e232728a0Jack Yu                    }
293722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mCanSetPreferApn && mPreferredApn == null) {
29380e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                        if (DBG) log("onDataSetupComplete: PREFERRED APN is null");
2939cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mPreferredApn = apn;
2940cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (mPreferredApn != null) {
2941cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            setPreferredApn(mPreferredApn.id);
2942cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
2943cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2944cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
294527b650c406018355a88a41528db7859e232728a0Jack Yu                    try {
294627b650c406018355a88a41528db7859e232728a0Jack Yu                        SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
294727b650c406018355a88a41528db7859e232728a0Jack Yu                    } catch (RuntimeException ex) {
294827b650c406018355a88a41528db7859e232728a0Jack Yu                        log("Failed to set PUPPET_MASTER_RADIO_STRESS_TEST to false");
294927b650c406018355a88a41528db7859e232728a0Jack Yu                    }
2950cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2951c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2952c9b81a0c05128694c617fcdd67e73821895822feWink Saville                // A connection is setup
2953c9b81a0c05128694c617fcdd67e73821895822feWink Saville                apnContext.setState(DctConstants.State.CONNECTED);
29540e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
2955d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                checkDataRoamingStatus(false);
2956d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen
2957c9b81a0c05128694c617fcdd67e73821895822feWink Saville                boolean isProvApn = apnContext.isProvisioningApn();
2958b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                final ConnectivityManager cm = ConnectivityManager.from(mPhone.getContext());
2959b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                if (mProvisionBroadcastReceiver != null) {
2960b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mPhone.getContext().unregisterReceiver(mProvisionBroadcastReceiver);
2961b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mProvisionBroadcastReceiver = null;
2962b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                }
2963c9b81a0c05128694c617fcdd67e73821895822feWink Saville                if ((!isProvApn) || mIsProvisioning) {
2964b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // Hide any provisioning notification.
2965b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    cm.setProvisioningNotificationVisible(false, ConnectivityManager.TYPE_MOBILE,
2966b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                            mProvisionActionName);
2967c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // Complete the connection normally notifying the world we're connected.
2968c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // We do this if this isn't a special provisioning apn or if we've been
2969c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // told its time to provision.
2970c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    completeConnection(apnContext);
2971c9b81a0c05128694c617fcdd67e73821895822feWink Saville                } else {
2972c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // This is a provisioning APN that we're reporting as connected. Later
2973c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // when the user desires to upgrade this to a "default" connection,
2974c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // mIsProvisioning == true, we'll go through the code path above.
2975c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // mIsProvisioning becomes true when CMD_ENABLE_MOBILE_PROVISIONING
2976c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // is sent to the DCT.
2977c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    if (DBG) {
2978c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        log("onDataSetupComplete: successful, BUT send connected to prov apn as"
2979c9b81a0c05128694c617fcdd67e73821895822feWink Saville                                + " mIsProvisioning:" + mIsProvisioning + " == false"
2980c9b81a0c05128694c617fcdd67e73821895822feWink Saville                                + " && (isProvisioningApn:" + isProvApn + " == true");
2981c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    }
2982c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2983b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // While radio is up, grab provisioning URL.  The URL contains ICCID which
2984b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // disappears when radio is off.
2985b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mProvisionBroadcastReceiver = new ProvisionNotificationBroadcastReceiver(
29862b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                            cm.getMobileProvisioningUrl(),
29872b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                            TelephonyManager.getDefault().getNetworkOperatorName());
2988b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mPhone.getContext().registerReceiver(mProvisionBroadcastReceiver,
2989b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                            new IntentFilter(mProvisionActionName));
2990b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // Put up user notification that sign-in is required.
2991b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    cm.setProvisioningNotificationVisible(true, ConnectivityManager.TYPE_MOBILE,
2992b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                            mProvisionActionName);
2993b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // Turn off radio to save battery and avoid wasting carrier resources.
2994b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // The network isn't usable and network validation will just fail anyhow.
2995b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    setRadio(false);
2996c9b81a0c05128694c617fcdd67e73821895822feWink Saville                }
2997c9b81a0c05128694c617fcdd67e73821895822feWink Saville                if (DBG) {
2998c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    log("onDataSetupComplete: SETUP complete type=" + apnContext.getApnType()
2999c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        + ", reason:" + apnContext.getReason());
3000c9b81a0c05128694c617fcdd67e73821895822feWink Saville                }
30014c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                if (Build.IS_DEBUGGABLE) {
30024c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                    // adb shell setprop persist.radio.test.pco [pco_val]
30034c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                    String radioTestProperty = "persist.radio.test.pco";
3004cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    int pcoVal = SystemProperties.getInt(radioTestProperty, -1);
3005cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    if (pcoVal != -1) {
3006cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        log("PCO testing: read pco value from persist.radio.test.pco " + pcoVal);
3007cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        final byte[] value = new byte[1];
3008cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        value[0] = (byte) pcoVal;
3009cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        final Intent intent =
3010cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                                new Intent(TelephonyIntents.ACTION_CARRIER_SIGNAL_PCO_VALUE);
3011cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        intent.putExtra(TelephonyIntents.EXTRA_APN_TYPE_KEY, "default");
3012cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        intent.putExtra(TelephonyIntents.EXTRA_APN_PROTO_KEY, "IPV4V6");
3013cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        intent.putExtra(TelephonyIntents.EXTRA_PCO_ID_KEY, 0xFF00);
3014cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        intent.putExtra(TelephonyIntents.EXTRA_PCO_VALUE_KEY, value);
3015cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
3016cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    }
30174c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                }
3018c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3019cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
3020ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            cause = (DcFailCause) (ar.result);
3021cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
3022cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ApnSetting apn = apnContext.getApnSetting();
3023cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log(String.format("onDataSetupComplete: error apn=%s cause=%s",
3024cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        (apn == null ? "unknown" : apn.apn), cause));
3025c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3026cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cause.isEventLoggable()) {
3027cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Log this failure to the Event Logs.
3028cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                int cid = getCellLocationId();
3029cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                EventLog.writeEvent(EventLogTags.PDP_SETUP_FAIL,
3030cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        cause.ordinal(), cid, TelephonyManager.getDefault().getNetworkType());
3031c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
30320742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela            ApnSetting apn = apnContext.getApnSetting();
30330742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela            mPhone.notifyPreciseDataConnectionFailed(apnContext.getReason(),
30340742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela                    apnContext.getApnType(), apn != null ? apn.apn : "unknown", cause.toString());
3035cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
30364c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            // Compose broadcast intent send to the specific carrier signaling receivers
30374c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            Intent intent = new Intent(TelephonyIntents
30384c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                    .ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED);
30394c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            intent.putExtra(TelephonyIntents.EXTRA_ERROR_CODE_KEY, cause.getErrorCode());
30404c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            intent.putExtra(TelephonyIntents.EXTRA_APN_TYPE_KEY, apnContext.getApnType());
30414c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
3042a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
304331f84bf1a4f1c945f7ca4646095ef4717a261c98Jordan Liu            if (cause.isRestartRadioFail(mPhone.getContext(), mPhone.getSubId()) ||
304431f84bf1a4f1c945f7ca4646095ef4717a261c98Jordan Liu                    apnContext.restartOnError(cause.getErrorCode())) {
30450e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                if (DBG) log("Modem restarted.");
30460e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                sendRestartRadio();
30470e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            }
3048cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
30490e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // If the data call failure cause is a permanent failure, we mark the APN as permanent
30500e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // failed.
3051ccfe5ebaf81c1378e8dbe44e45df26b0dc462a21Jack Yu            if (isPermanentFailure(cause)) {
30520e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                log("cause = " + cause + ", mark apn as permanent failed. apn = " + apn);
30530e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                apnContext.markApnPermanentFailed(apn);
3054c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
30550e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
3056cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            handleError = true;
3057cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3058cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3059cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (handleError) {
3060ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            onDataSetupCompleteError(ar);
3061ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
3062a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3063a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        /* If flag is set to false after SETUP_DATA_CALL is invoked, we need
3064a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         * to clean data connections.
3065a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         */
3066a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        if (!mDataEnabledSettings.isInternalDataEnabled()) {
30674fdc57b9bf223c908474c4545cc6f63456117a3bSanket Padawe            cleanUpAllConnections(Phone.REASON_DATA_DISABLED);
3068a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
3069a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3070ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
3071cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3072ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
3073ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt     * check for obsolete messages.  Return ApnContext if valid, null if not
3074ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt     */
3075ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt    private ApnContext getValidApnContext(AsyncResult ar, String logString) {
3076ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (ar != null && ar.userObj instanceof Pair) {
3077ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            Pair<ApnContext, Integer>pair = (Pair<ApnContext, Integer>)ar.userObj;
3078ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            ApnContext apnContext = pair.first;
3079ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            if (apnContext != null) {
30801a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                final int generation = apnContext.getConnectionGeneration();
30811a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                if (DBG) {
30821a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                    log("getValidApnContext (" + logString + ") on " + apnContext + " got " +
30831a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                            generation + " vs " + pair.second);
30841a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                }
30851a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                if (generation == pair.second) {
3086ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                    return apnContext;
3087ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                } else {
3088ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                    log("ignoring obsolete " + logString);
3089ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                    return null;
3090ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                }
3091ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            }
3092ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        }
3093ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        throw new RuntimeException(logString + ": No apnContext");
3094ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt    }
3095ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt
3096ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt    /**
3097ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Error has occurred during the SETUP {aka bringUP} request and the DCT
3098ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * should either try the next waiting APN or start over from the
3099ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * beginning if the list is empty. Between each SETUP request there will
3100ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville     * be a delay defined by {@link #getApnDelay()}.
3101ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
31021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataSetupCompleteError(AsyncResult ar) {
31030e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
3104ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDataSetupCompleteError");
3105ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3106ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
3107ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
31080e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        long delay = apnContext.getDelayForNextApn(mFailFast);
3109ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
31100e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        // Check if we need to retry or not.
31110852a954be5937a1b0bca94df0c2007d7ee3c0c7Jack Yu        if (delay >= 0) {
31120e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (DBG) log("onDataSetupCompleteError: Try next APN. delay = " + delay);
3113ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext.setState(DctConstants.State.SCANNING);
3114ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // Wait a bit before trying the next APN, so that
3115ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // we're not tying up the RIL command channel
31160e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            startAlarmForReconnect(delay, apnContext);
31170e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        } else {
31180e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // If we are not going to retry any APN, set this APN context to failed state.
31190e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // This would be the final state of a data connection.
31200e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            apnContext.setState(DctConstants.State.FAILED);
31210e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType());
31220e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            apnContext.setDataConnectionAc(null);
31230e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            log("onDataSetupCompleteError: Stop retrying APNs.");
3124c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3125c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3126c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3127c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
3128a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu     * Called when EVENT_REDIRECTION_DETECTED is received.
3129a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu     */
31304c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu    private void onDataConnectionRedirected(String redirectUrl) {
3131a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        if (!TextUtils.isEmpty(redirectUrl)) {
31324c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            Intent intent = new Intent(TelephonyIntents.ACTION_CARRIER_SIGNAL_REDIRECTED);
31334c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            intent.putExtra(TelephonyIntents.EXTRA_REDIRECTION_URL_KEY, redirectUrl);
31346a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu            mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
31356a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu            log("Notify carrier signal receivers with redirectUrl: " + redirectUrl);
3136a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        }
3137a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    }
3138a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
3139a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    /**
3140cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Called when EVENT_DISCONNECT_DONE is received.
3141c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
31421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDisconnectDone(AsyncResult ar) {
3143ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDisconnectDone");
3144ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
3145c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3146cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE apnContext=" + apnContext);
3147cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setState(DctConstants.State.IDLE);
3148cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3149cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
3150cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3151cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // if all data connection are gone, check whether Airplane mode request was
3152cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // pending.
3153cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isDisconnected()) {
3154cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPhone.getServiceStateTracker().processPendingRadioPowerOffAfterDataOff()) {
3155a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                if (DBG) log("onDisconnectDone: radio will be turned off, no retries");
3156cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Radio will be turned off. No need to retry data setup
3157cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setApnSetting(null);
3158cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setDataConnectionAc(null);
3159a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3160a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // Need to notify disconnect as well, in the case of switching Airplane mode.
3161a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // Otherwise, it would cause 30s delayed to turn on Airplane mode.
31620e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                if (mDisconnectPendingCount > 0) {
3163a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mDisconnectPendingCount--;
31640e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                }
3165a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3166a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mDisconnectPendingCount == 0) {
3167a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    notifyDataDisconnectComplete();
3168a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    notifyAllDataDisconnected();
3169a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
3170cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return;
3171cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3172c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3173cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // If APN is still enabled, try to bring it back up automatically
31743fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (mAttached.get() && apnContext.isReady() && retryAfterDisconnected(apnContext)) {
317527b650c406018355a88a41528db7859e232728a0Jack Yu            try {
317627b650c406018355a88a41528db7859e232728a0Jack Yu                SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
317727b650c406018355a88a41528db7859e232728a0Jack Yu            } catch (RuntimeException ex) {
317827b650c406018355a88a41528db7859e232728a0Jack Yu                log("Failed to set PUPPET_MASTER_RADIO_STRESS_TEST to false");
317927b650c406018355a88a41528db7859e232728a0Jack Yu            }
3180cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Wait a bit before trying the next APN, so that
3181cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // we're not tying up the RIL command channel.
3182cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // This also helps in any external dependency to turn off the context.
31830e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (DBG) log("onDisconnectDone: attached, ready and retry after disconnect");
3184da21f0de2087657b20b18817b33d59778720bffbJack Yu            long delay = apnContext.getRetryAfterDisconnectDelay();
31850e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (delay > 0) {
31860e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                // Data connection is in IDLE state, so when we reconnect later, we'll rebuild
31870e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                // the waiting APN list, which will also reset/reconfigure the retry manager.
31880e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                startAlarmForReconnect(delay, apnContext);
31890e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            }
3190c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
3191449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            boolean restartRadioAfterProvisioning = mPhone.getContext().getResources().getBoolean(
3192449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                    com.android.internal.R.bool.config_restartRadioAfterProvisioning);
3193449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville
3194449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            if (apnContext.isProvisioningApn() && restartRadioAfterProvisioning) {
3195449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                log("onDisconnectDone: restartRadio after provisioning");
3196449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                restartRadio();
3197449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            }
3198cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setApnSetting(null);
3199cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setDataConnectionAc(null);
32003fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())) {
3201449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                if(DBG) log("onDisconnectDone: isOnlySigneDcAllowed true so setup single apn");
32023fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                setupDataOnConnectableApns(Phone.REASON_SINGLE_PDN_ARBITRATION);
3203449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            } else {
3204449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                if(DBG) log("onDisconnectDone: not retrying");
32053fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
3206c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3207a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3208a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mDisconnectPendingCount > 0)
3209a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mDisconnectPendingCount--;
3210a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3211a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mDisconnectPendingCount == 0) {
3212c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt            apnContext.setConcurrentVoiceAndDataAllowed(
3213c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed());
3214a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyDataDisconnectComplete();
3215a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
3216a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
3217a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3218c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3219c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3220ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
3221ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Called when EVENT_DISCONNECT_DC_RETRYING is received.
3222ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
32231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDisconnectDcRetrying(AsyncResult ar) {
3224ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // We could just do this in DC!!!
3225ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDisconnectDcRetrying");
3226ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
3227ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3228ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setState(DctConstants.State.RETRYING);
3229ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if(DBG) log("onDisconnectDcRetrying: apnContext=" + apnContext);
3230ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3231ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
3232ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
3233ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
32341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onVoiceCallStarted() {
3235cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onVoiceCallStarted");
3236ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        mInVoiceCall = true;
3237cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnected() && ! mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
3238cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onVoiceCallStarted stop polling");
3239cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            stopNetStatPoll();
3240cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            stopDataStallAlarm();
3241cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
3242c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3243c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3244c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onVoiceCallEnded() {
3246cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onVoiceCallEnded");
3247ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        mInVoiceCall = false;
3248cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnected()) {
3249cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
3250cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                startNetStatPoll();
3251cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
3252cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
3253cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
3254cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // clean slate after call end.
3255cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                resetPollStats();
3256c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3257c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3258bda761320929f714951c328bfec6a51a1978db97Wink Saville        // reset reconnect timer
3259bda761320929f714951c328bfec6a51a1978db97Wink Saville        setupDataOnConnectableApns(Phone.REASON_VOICE_CALL_ENDED);
3260c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3261c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onCleanUpConnection(boolean tearDown, int apnId, String reason) {
3263cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onCleanUpConnection");
3264af5593594070f825032be46dced573cd195956e1Robert Greenwalt        ApnContext apnContext = mApnContextsById.get(apnId);
3265cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
3266cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setReason(reason);
3267cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpConnection(tearDown, apnContext);
3268c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3269c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3270c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean isConnected() {
3272cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
3273ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getState() == DctConstants.State.CONNECTED) {
3274cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // At least one context is connected, return true
3275cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return true;
3276c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3277c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3278cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // There are not any contexts connected, return false
3279cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return false;
3280c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3281c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3282cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isDisconnected() {
3283cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
3284cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!apnContext.isDisconnected()) {
3285cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // At least one context was not disconnected return false
3286cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
3287cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3288c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3289cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // All contexts were disconnected so return true
3290cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
3291c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3292c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyDataConnection(String reason) {
3294cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("notifyDataConnection: reason=" + reason);
3295cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
3296187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (mAttached.get() && apnContext.isReady()) {
3297187a39f896f88eb6c5e4306d9595546654825976Wink Saville                if (DBG) log("notifyDataConnection: type:" + apnContext.getApnType());
3298cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
3299cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.getApnType());
3300cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3301c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3302cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyOffApnsOfAvailability(reason);
3303c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3304c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
33051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void setDataProfilesAsNeeded() {
33061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("setDataProfilesAsNeeded");
33071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mAllApnSettings != null && !mAllApnSettings.isEmpty()) {
33081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            ArrayList<DataProfile> dps = new ArrayList<DataProfile>();
33091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (ApnSetting apn : mAllApnSettings) {
33101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (apn.modemCognitive) {
3311886183cde1263ea524cdf08524442724e246ed42Jack Yu                    DataProfile dp = createDataProfile(apn);
33128e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                    if (!dps.contains(dp)) {
33131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        dps.add(dp);
33141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
33151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
33161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
33178e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu            if (dps.size() > 0) {
331871f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                mDataServiceManager.setDataProfile(dps,
3319cc40713c49908aeaac0070bf4ea796247f9066b5Jack Yu                        mPhone.getServiceState().getDataRoamingFromRegistration(), null);
33201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
33211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
33221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
33231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3324c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
3325cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Based on the sim operator numeric, create a list for all possible
3326cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Data Connections and setup the preferredApn.
3327c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
3328cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void createAllApnList() {
33291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mMvnoMatched = false;
33308e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu        mAllApnSettings = new ArrayList<>();
3331cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
3332cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String operator = (r != null) ? r.getOperatorNumeric() : "";
3333cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (operator != null) {
33343c89e23cf33c3c7f795554b29cd926219f28fe34Sungmin Choi            String selection = Telephony.Carriers.NUMERIC + " = '" + operator + "'";
3335cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // query only enabled apn.
3336cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // carrier_enabled : 1 means enabled apn, 0 disabled apn.
33379d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan            // selection += " and carrier_enabled = 1";
3338cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: selection=" + selection);
3339cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
33403c89e23cf33c3c7f795554b29cd926219f28fe34Sungmin Choi            // ORDER BY Telephony.Carriers._ID ("_id")
3341cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            Cursor cursor = mPhone.getContext().getContentResolver().query(
3342030fdfb7ccdf5dce9a6b48ca07918082627200f4yuemingw                    Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "filtered"),
3343030fdfb7ccdf5dce9a6b48ca07918082627200f4yuemingw                    null, selection, null, Telephony.Carriers._ID);
3344cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3345cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cursor != null) {
3346cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (cursor.getCount() > 0) {
3347ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    mAllApnSettings = createApnList(cursor);
3348cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3349cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cursor.close();
3350cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3351c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3352c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
335376f43316a5a6082d601bffd4b6898d0bd81e11fcram        addEmergencyApnSetting();
335476f43316a5a6082d601bffd4b6898d0bd81e11fcram
335529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        dedupeApnSettings();
335629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
3357ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings.isEmpty()) {
3358cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: No APN found for carrier: " + operator);
3359cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPreferredApn = null;
3360ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // TODO: What is the right behavior?
3361cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            //notifyNoData(DataConnection.FailCause.MISSING_UNKNOWN_APN);
3362c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
3363cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPreferredApn = getPreferredApn();
3364cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator)) {
3365cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn = null;
3366cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                setPreferredApn(-1);
3367cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3368cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: mPreferredApn=" + mPreferredApn);
3369c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3370ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("createAllApnList: X mAllApnSettings=" + mAllApnSettings);
33719d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan
33729d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        setDataProfilesAsNeeded();
3373c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3374c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
337529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    private void dedupeApnSettings() {
337629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        ArrayList<ApnSetting> resultApns = new ArrayList<ApnSetting>();
337729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
337829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        // coalesce APNs if they are similar enough to prevent
337929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        // us from bringing up two data calls with the same interface
338029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        int i = 0;
338129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        while (i < mAllApnSettings.size() - 1) {
338229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            ApnSetting first = mAllApnSettings.get(i);
338329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            ApnSetting second = null;
338429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            int j = i + 1;
338529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            while (j < mAllApnSettings.size()) {
338629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                second = mAllApnSettings.get(j);
33879fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                if (first.similar(second)) {
338829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    ApnSetting newApn = mergeApns(first, second);
338929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    mAllApnSettings.set(i, newApn);
339029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    first = newApn;
339129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    mAllApnSettings.remove(j);
339229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                } else {
339329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    j++;
339429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                }
339529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            }
339629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            i++;
339729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        }
339829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    }
339929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
340029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    private ApnSetting mergeApns(ApnSetting dest, ApnSetting src) {
3401bca51fc3a191d3ca30df627b75374db0941571c5Sungmin Choi        int id = dest.id;
340229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        ArrayList<String> resultTypes = new ArrayList<String>();
340329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        resultTypes.addAll(Arrays.asList(dest.types));
340429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        for (String srcType : src.types) {
340529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            if (resultTypes.contains(srcType) == false) resultTypes.add(srcType);
3406bca51fc3a191d3ca30df627b75374db0941571c5Sungmin Choi            if (srcType.equals(PhoneConstants.APN_TYPE_DEFAULT)) id = src.id;
340729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        }
340829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        String mmsc = (TextUtils.isEmpty(dest.mmsc) ? src.mmsc : dest.mmsc);
340929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        String mmsProxy = (TextUtils.isEmpty(dest.mmsProxy) ? src.mmsProxy : dest.mmsProxy);
341029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        String mmsPort = (TextUtils.isEmpty(dest.mmsPort) ? src.mmsPort : dest.mmsPort);
341161cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String proxy = (TextUtils.isEmpty(dest.proxy) ? src.proxy : dest.proxy);
341261cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String port = (TextUtils.isEmpty(dest.port) ? src.port : dest.port);
341361cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String protocol = src.protocol.equals("IPV4V6") ? src.protocol : dest.protocol;
341461cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String roamingProtocol = src.roamingProtocol.equals("IPV4V6") ? src.roamingProtocol :
341561cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                dest.roamingProtocol;
3416176f28521fd45bb739709d309e7970b1558c9f61Cassie        int networkTypeBitmask = (dest.networkTypeBitmask == 0 || src.networkTypeBitmask == 0)
3417176f28521fd45bb739709d309e7970b1558c9f61Cassie                ? 0 : (dest.networkTypeBitmask | src.networkTypeBitmask);
3418176f28521fd45bb739709d309e7970b1558c9f61Cassie        if (networkTypeBitmask == 0) {
3419176f28521fd45bb739709d309e7970b1558c9f61Cassie            int bearerBitmask = (dest.bearerBitmask == 0 || src.bearerBitmask == 0)
3420176f28521fd45bb739709d309e7970b1558c9f61Cassie                    ? 0 : (dest.bearerBitmask | src.bearerBitmask);
3421176f28521fd45bb739709d309e7970b1558c9f61Cassie            networkTypeBitmask = ServiceState.convertBearerBitmaskToNetworkTypeBitmask(
3422176f28521fd45bb739709d309e7970b1558c9f61Cassie                    bearerBitmask);
3423176f28521fd45bb739709d309e7970b1558c9f61Cassie        }
342429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
3425bca51fc3a191d3ca30df627b75374db0941571c5Sungmin Choi        return new ApnSetting(id, dest.numeric, dest.carrier, dest.apn,
342661cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                proxy, port, mmsc, mmsProxy, mmsPort, dest.user, dest.password,
342761cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                dest.authType, resultTypes.toArray(new String[0]), protocol,
3428176f28521fd45bb739709d309e7970b1558c9f61Cassie                roamingProtocol, dest.carrierEnabled, networkTypeBitmask, dest.profileId,
342929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                (dest.modemCognitive || src.modemCognitive), dest.maxConns, dest.waitTime,
343021f6e74b368a7045981cdb718570bf872471ac0bJordan Liu                dest.maxConnsTime, dest.mtu, dest.mvnoType, dest.mvnoMatchData, dest.apnSetId);
343129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    }
343229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
3433ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /** Return the DC AsyncChannel for the new data connection */
3434454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel createDataConnection() {
3435cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createDataConnection E");
3436cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3437cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int id = mUniqueIdGenerator.getAndIncrement();
343871f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        DataConnection conn = DataConnection.makeDataConnection(mPhone, id, this,
343971f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                mDataServiceManager, mDcTesterFailBringUpAll, mDcc);
3440cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mDataConnections.put(id, conn);
3441454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac = new DcAsyncChannel(conn, LOG_TAG);
3442cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int status = dcac.fullyConnectSync(mPhone.getContext(), this, conn.getHandler());
3443cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (status == AsyncChannel.STATUS_SUCCESSFUL) {
3444ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            mDataConnectionAcHashMap.put(dcac.getDataConnectionIdSync(), dcac);
3445c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
3446ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            loge("createDataConnection: Could not connect to dcac=" + dcac + " status=" + status);
3447c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3448cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3449cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createDataConnection() X id=" + id + " dc=" + conn);
3450ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        return dcac;
3451c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3452c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3453cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void destroyDataConnections() {
3454cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(mDataConnections != null) {
3455cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("destroyDataConnections: clear mDataConnectionList");
3456cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mDataConnections.clear();
3457cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
3458cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("destroyDataConnections: mDataConnecitonList is empty, ignore");
3459c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3460c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3461c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3462c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
3463cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Build a list of APNs to be used to create PDP's.
3464c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
3465cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param requestedApnType
3466cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return waitingApns list to be used to create PDP
3467cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *          error when waitingApns.isEmpty()
3468c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
3469203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    private ArrayList<ApnSetting> buildWaitingApns(String requestedApnType, int radioTech) {
3470cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("buildWaitingApns: E requestedApnType=" + requestedApnType);
3471cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ArrayList<ApnSetting> apnList = new ArrayList<ApnSetting>();
3472cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3473cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (requestedApnType.equals(PhoneConstants.APN_TYPE_DUN)) {
34742abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu            ArrayList<ApnSetting> dunApns = fetchDunApns();
34752abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu            if (dunApns.size() > 0) {
34762abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                for (ApnSetting dun : dunApns) {
34772abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                    apnList.add(dun);
34782abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                    if (DBG) log("buildWaitingApns: X added APN_TYPE_DUN apnList=" + apnList);
34792abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                }
34802abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                return sortApnListByPreferred(apnList);
3481c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3482c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3483c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3484cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
3485cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String operator = (r != null) ? r.getOperatorNumeric() : "";
3486c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3487cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // This is a workaround for a bug (7305641) where we don't failover to other
3488cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // suitable APNs if our preferred APN fails.  On prepaid ATT sims we need to
3489cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // failover to a provisioning APN, but once we've used their default data
3490cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // connection we are locked to it for life.  This change allows ATT devices
3491cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // to say they don't want to use preferred at all.
3492cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean usePreferred = true;
3493cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        try {
3494cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            usePreferred = ! mPhone.getContext().getResources().getBoolean(com.android.
3495cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    internal.R.bool.config_dontPreferApn);
3496cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } catch (Resources.NotFoundException e) {
3497cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("buildWaitingApns: usePreferred NotFoundException set to true");
3498cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            usePreferred = true;
3499cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3500bf660a4647db8151609cdfa0ecc4c96e1518947fSungmin Choi        if (usePreferred) {
3501bf660a4647db8151609cdfa0ecc4c96e1518947fSungmin Choi            mPreferredApn = getPreferredApn();
3502bf660a4647db8151609cdfa0ecc4c96e1518947fSungmin Choi        }
3503cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
3504cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("buildWaitingApns: usePreferred=" + usePreferred
350522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    + " canSetPreferApn=" + mCanSetPreferApn
3506cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " mPreferredApn=" + mPreferredApn
3507cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " operator=" + operator + " radioTech=" + radioTech
3508cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " IccRecords r=" + r);
3509cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3510c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
351122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (usePreferred && mCanSetPreferApn && mPreferredApn != null &&
3512cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn.canHandleType(requestedApnType)) {
3513cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
3514cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("buildWaitingApns: Preferred APN:" + operator + ":"
3515cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        + mPreferredApn.numeric + ":" + mPreferredApn);
3516cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3517cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPreferredApn.numeric.equals(operator)) {
3518176f28521fd45bb739709d309e7970b1558c9f61Cassie                if (ServiceState.bitmaskHasTech(mPreferredApn.networkTypeBitmask,
3519176f28521fd45bb739709d309e7970b1558c9f61Cassie                        ServiceState.rilRadioTechnologyToNetworkType(radioTech))) {
3520cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnList.add(mPreferredApn);
35212abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                    apnList = sortApnListByPreferred(apnList);
3522cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
3523cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return apnList;
3524cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
3525cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("buildWaitingApns: no preferred APN");
3526cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    setPreferredApn(-1);
3527cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mPreferredApn = null;
3528c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
3529cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
3530cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: no preferred APN");
3531cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                setPreferredApn(-1);
3532cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn = null;
3533c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3534c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3535ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings != null) {
3536ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (DBG) log("buildWaitingApns: mAllApnSettings=" + mAllApnSettings);
3537ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for (ApnSetting apn : mAllApnSettings) {
3538cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn.canHandleType(requestedApnType)) {
3539176f28521fd45bb739709d309e7970b1558c9f61Cassie                    if (ServiceState.bitmaskHasTech(apn.networkTypeBitmask,
3540176f28521fd45bb739709d309e7970b1558c9f61Cassie                            ServiceState.rilRadioTechnologyToNetworkType(radioTech))) {
35419232dafa7ea833fc0b3a6024d6c7e23fc8e961eaRobert Greenwalt                        if (DBG) log("buildWaitingApns: adding apn=" + apn);
3542cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnList.add(apn);
3543c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else {
3544cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (DBG) {
3545176f28521fd45bb739709d309e7970b1558c9f61Cassie                            log("buildWaitingApns: bearerBitmask:" + apn.bearerBitmask
3546176f28521fd45bb739709d309e7970b1558c9f61Cassie                                    + " or " + "networkTypeBitmask:" + apn.networkTypeBitmask
3547176f28521fd45bb739709d309e7970b1558c9f61Cassie                                    + "do not include radioTech:" + radioTech);
3548cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
3549c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
35509232dafa7ea833fc0b3a6024d6c7e23fc8e961eaRobert Greenwalt                } else if (DBG) {
355127b650c406018355a88a41528db7859e232728a0Jack Yu                    log("buildWaitingApns: couldn't handle requested ApnType="
3552cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            + requestedApnType);
3553c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
3554c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3555cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
35564bd0ae43eb0cb9969dee4f30cddc18a71da68190Jack Yu            loge("mAllApnSettings is null!");
3557c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
35582abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu
35592abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu        apnList = sortApnListByPreferred(apnList);
35600e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        if (DBG) log("buildWaitingApns: " + apnList.size() + " APNs in the list: " + apnList);
3561cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return apnList;
3562c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3563c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
35642abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu    /**
35652abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu     * Sort a list of ApnSetting objects, with the preferred APNs at the front of the list
35662abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu     *
35672abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu     * e.g. if the preferred APN set = 2 and we have
35682abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu     *   1. APN with apn_set_id = 0 = Carriers.NO_SET_SET (no set is set)
35692abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu     *   2. APN with apn_set_id = 1 (not preferred set)
35702abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu     *   3. APN with apn_set_id = 2 (preferred set)
35712abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu     * Then the return order should be (3, 1, 2) or (3, 2, 1)
35722abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu     *
35732abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu     * e.g. if the preferred APN set = Carriers.NO_SET_SET (no preferred set) then the
35742abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu     * return order can be anything
35752abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu     */
35762abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu    @VisibleForTesting
35772abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu    public ArrayList<ApnSetting> sortApnListByPreferred(ArrayList<ApnSetting> list) {
35782abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu        if (list == null || list.size() <= 1) return list;
35792abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu        int preferredApnSetId = getPreferredApnSetId();
35802abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu        if (preferredApnSetId != Telephony.Carriers.NO_SET_SET) {
35812abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu            list.sort(new Comparator<ApnSetting>() {
35822abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                @Override
35832abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                public int compare(ApnSetting apn1, ApnSetting apn2) {
35842abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                    if (apn1.apnSetId == preferredApnSetId) return -1;
35852abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                    if (apn2.apnSetId == preferredApnSetId) return 1;
35862abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                    return 0;
35872abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu                }
35882abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu            });
35892abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu        }
35902abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu        return list;
35912abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu    }
35922abcc8f5d0dc589e7bd2f1b7ce1d7d4f0a8a5e10Jordan Liu
3593cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private String apnListToString (ArrayList<ApnSetting> apns) {
3594cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        StringBuilder result = new StringBuilder();
3595cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (int i = 0, size = apns.size(); i < size; i++) {
3596cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result.append('[')
3597cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                  .append(apns.get(i).toString())
3598cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                  .append(']');
3599c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3600cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result.toString();
3601c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3602c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3603cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void setPreferredApn(int pos) {
360422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (!mCanSetPreferApn) {
3605cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("setPreferredApn: X !canSEtPreferApn");
3606cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
3607cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3608cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
36096bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        String subId = Long.toString(mPhone.getSubId());
36106bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        Uri uri = Uri.withAppendedPath(PREFERAPN_NO_UPDATE_URI_USING_SUBID, subId);
3611cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("setPreferredApn: delete");
3612cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ContentResolver resolver = mPhone.getContext().getContentResolver();
36136bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        resolver.delete(uri, null, null);
3614cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3615cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (pos >= 0) {
3616cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("setPreferredApn: insert");
3617cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ContentValues values = new ContentValues();
3618cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            values.put(APN_ID, pos);
36196bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville            resolver.insert(uri, values);
3620cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3621cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
3622cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3623cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ApnSetting getPreferredApn() {
36244bd0ae43eb0cb9969dee4f30cddc18a71da68190Jack Yu        if (mAllApnSettings == null || mAllApnSettings.isEmpty()) {
36254bd0ae43eb0cb9969dee4f30cddc18a71da68190Jack Yu            log("getPreferredApn: mAllApnSettings is " + ((mAllApnSettings == null)?"null":"empty"));
3626cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return null;
3627cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3628cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
36296bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        String subId = Long.toString(mPhone.getSubId());
36306bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        Uri uri = Uri.withAppendedPath(PREFERAPN_NO_UPDATE_URI_USING_SUBID, subId);
3631cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Cursor cursor = mPhone.getContext().getContentResolver().query(
36326bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville                uri, new String[] { "_id", "name", "apn" },
3633cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
3634cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3635cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor != null) {
363622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCanSetPreferApn = true;
3637cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
363822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCanSetPreferApn = false;
3639cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3640cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("getPreferredApn: mRequestedApnType=" + mRequestedApnType + " cursor=" + cursor
3641cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                + " cursor.count=" + ((cursor != null) ? cursor.getCount() : 0));
3642cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
364322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mCanSetPreferApn && cursor.getCount() > 0) {
3644cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            int pos;
3645cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cursor.moveToFirst();
3646cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            pos = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID));
3647ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for(ApnSetting p : mAllApnSettings) {
3648cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("getPreferredApn: apnSetting=" + p);
3649cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (p.id == pos && p.canHandleType(mRequestedApnType)) {
3650cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("getPreferredApn: X found apnSetting" + p);
3651cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    cursor.close();
3652cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return p;
3653cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3654cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
3655cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3656cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3657cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor != null) {
3658cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cursor.close();
3659cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3660cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3661cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("getPreferredApn: X not found");
3662cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
3663cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
3664cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3665cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
3666cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void handleMessage (Message msg) {
36671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) log("handleMessage msg=" + msg);
3668cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3669cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        switch (msg.what) {
3670cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_RECORDS_LOADED:
36711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // If onRecordsLoadedOrSubIdChanged() is not called here, it should be called on
36721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // onSubscriptionsChanged() when a valid subId is available.
36731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                int subId = mPhone.getSubId();
36741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (SubscriptionManager.isValidSubscriptionId(subId)) {
36751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onRecordsLoadedOrSubIdChanged();
36761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
36771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("Ignoring EVENT_RECORDS_LOADED as subId is not valid: " + subId);
36781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
3679cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3680cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3681cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_CONNECTION_DETACHED:
3682cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onDataConnectionDetached();
3683cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3684cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3685cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_CONNECTION_ATTACHED:
3686bda761320929f714951c328bfec6a51a1978db97Wink Saville                onDataConnectionAttached();
3687cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3688cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3689cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DO_RECOVERY:
3690cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                doRecovery();
3691cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3692cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3693cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_APN_CHANGED:
3694cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onApnChanged();
3695cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3696cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3697cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_PS_RESTRICT_ENABLED:
3698cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                /**
3699cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * We don't need to explicitly to tear down the PDP context
3700cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * when PS restricted is enabled. The base band will deactive
3701cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * PDP context and notify us with PDP_CONTEXT_CHANGED.
3702cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * But we should stop the network polling and prevent reset PDP.
3703cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 */
3704cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
3705cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                stopNetStatPoll();
3706cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                stopDataStallAlarm();
3707cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsPsRestricted = true;
3708cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
3709cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3710cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_PS_RESTRICT_DISABLED:
3711cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                /**
3712cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * When PS restrict is removed, we need setup PDP connection if
3713cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * PDP connection is down.
3714cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 */
3715cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_PS_RESTRICT_DISABLED " + mIsPsRestricted);
3716cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsPsRestricted  = false;
3717cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (isConnected()) {
3718cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    startNetStatPoll();
3719cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
3720cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
3721cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // TODO: Should all PDN states be checked to fail?
3722ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    if (mState == DctConstants.State.FAILED) {
3723cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        cleanUpAllConnections(false, Phone.REASON_PS_RESTRICT_ENABLED);
3724cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mReregisterOnReconnectFailure = false;
3725cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
3726af5593594070f825032be46dced573cd195956e1Robert Greenwalt                    ApnContext apnContext = mApnContextsById.get(DctConstants.APN_DEFAULT_ID);
37273fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (apnContext != null) {
37283fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        apnContext.setReason(Phone.REASON_PS_RESTRICT_ENABLED);
37293fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        trySetupData(apnContext);
37303fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    } else {
37313fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        loge("**** Default ApnContext not found ****");
37323fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        if (Build.IS_DEBUGGABLE) {
37333fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                            throw new RuntimeException("Default ApnContext not found");
37343fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        }
37353fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    }
3736cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3737cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
3738ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3739cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_TRY_SETUP_DATA:
3740cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (msg.obj instanceof ApnContext) {
3741cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    onTrySetupData((ApnContext)msg.obj);
3742cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else if (msg.obj instanceof String) {
3743cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    onTrySetupData((String)msg.obj);
3744cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
3745cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    loge("EVENT_TRY_SETUP request w/o apnContext or String");
3746cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3747cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
3748cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3749cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_CLEAN_UP_CONNECTION:
3750cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                boolean tearDown = (msg.arg1 == 0) ? false : true;
3751cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_CLEAN_UP_CONNECTION tearDown=" + tearDown);
3752cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (msg.obj instanceof ApnContext) {
3753cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    cleanUpConnection(tearDown, (ApnContext)msg.obj);
3754cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
37551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onCleanUpConnection(tearDown, msg.arg2, (String) msg.obj);
3756cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3757cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
37581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE: {
37591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
3760a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                onSetInternalDataEnabled(enabled, (Message) msg.obj);
3761a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
37621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
3763a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS:
37641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if ((msg.obj != null) && (msg.obj instanceof String == false)) {
37651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    msg.obj = null;
3766a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
37671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onCleanUpAllConnections((String) msg.obj);
3768a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
3769ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3770220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville            case DctConstants.EVENT_DATA_RAT_CHANGED:
3771b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                if (mPhone.getServiceState().getRilDataRadioTechnology()
3772b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                        == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
3773b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                    // unknown rat is an exception for data rat change. It's only received when out
3774b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                    // of service and is not applicable for apn bearer bitmask. We should bypass the
3775b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                    // check of waiting apn list and keep the data connection on, and no need to
3776b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                    // setup a new one.
3777b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                    break;
3778b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                }
3779ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                cleanUpConnectionsOnUpdatedApns(false, Phone.REASON_NW_TYPE_CHANGED);
3780220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville                //May new Network allow setupData, so try it here
3781c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                setupDataOnConnectableApns(Phone.REASON_NW_TYPE_CHANGED,
3782c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                        RetryFailures.ONLY_ON_CHANGE);
3783220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville                break;
3784220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville
37852b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            case DctConstants.CMD_CLEAR_PROVISIONING_SPINNER:
37862b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                // Check message sender intended to clear the current spinner.
37872b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                if (mProvisioningSpinner == msg.obj) {
37882b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner.dismiss();
37892b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner = null;
37902b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                }
37912b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                break;
37921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
37931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("DISCONNECTED_CONNECTED: msg=" + msg);
37941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DcAsyncChannel dcac = (DcAsyncChannel) msg.obj;
37951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mDataConnectionAcHashMap.remove(dcac.getDataConnectionIdSync());
37961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                dcac.disconnected();
37971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
37991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ENABLE_NEW_APN:
38001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onEnableApn(msg.arg1, msg.arg2);
38011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
38031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_STALL_ALARM:
38041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDataStallAlarm(msg.arg1);
38051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
38071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ROAMING_OFF:
38085b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu                onDataRoamingOff();
38091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
38111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ROAMING_ON:
3812d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen            case DctConstants.EVENT_ROAMING_SETTING_CHANGE:
3813d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                onDataRoamingOnOrSettingsChanged(msg.what);
38141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3816f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            case DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE:
3817f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                onDeviceProvisionedChange();
3818f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                break;
3819f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
3820a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            case DctConstants.EVENT_REDIRECTION_DETECTED:
38214c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                String url = (String) msg.obj;
382268f4f4a0bc8d4060b5775e7a24a97ea5b485989efionaxu                log("dataConnectionTracker.handleMessage: EVENT_REDIRECTION_DETECTED=" + url);
38234c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                onDataConnectionRedirected(url);
3824a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
38251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RADIO_AVAILABLE:
38261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onRadioAvailable();
38271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
38291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
38301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onRadioOffOrNotAvailable();
38311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
38331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_SETUP_COMPLETE:
38341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDataSetupComplete((AsyncResult) msg.obj);
38351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
38371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_SETUP_COMPLETE_ERROR:
38381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDataSetupCompleteError((AsyncResult) msg.obj);
38391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
3840a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
38411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DISCONNECT_DONE:
38421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("DataConnectionTracker.handleMessage: EVENT_DISCONNECT_DONE msg=" + msg);
38431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDisconnectDone((AsyncResult) msg.obj);
38441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
38461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DISCONNECT_DC_RETRYING:
38471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("DataConnectionTracker.handleMessage: EVENT_DISCONNECT_DC_RETRYING msg=" + msg);
38481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDisconnectDcRetrying((AsyncResult) msg.obj);
38491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
38511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_VOICE_CALL_STARTED:
38521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onVoiceCallStarted();
38531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
38551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_VOICE_CALL_ENDED:
38561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onVoiceCallEnded();
38571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_USER_DATA_ENABLE: {
38591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
38601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_SET_USER_DATA_ENABLE enabled=" + enabled);
38611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onSetUserDataEnabled(enabled);
38621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
38641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // TODO - remove
38651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_DEPENDENCY_MET: {
38661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                boolean met = (msg.arg1 == DctConstants.ENABLED) ? true : false;
38671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_SET_DEPENDENCY_MET met=" + met);
38681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Bundle bundle = msg.getData();
38691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (bundle != null) {
38701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    String apnType = (String)bundle.get(DctConstants.APN_TYPE_KEY);
38711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (apnType != null) {
38721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onSetDependencyMet(apnType, met);
38731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
38741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
38771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_POLICY_DATA_ENABLE: {
38781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
38791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onSetPolicyDataEnabled(enabled);
38801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
38821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: {
38831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                sEnableFailFastRefCounter += (msg.arg1 == DctConstants.ENABLED) ? 1 : -1;
38841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
38851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: "
38861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + " sEnableFailFastRefCounter=" + sEnableFailFastRefCounter);
38871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (sEnableFailFastRefCounter < 0) {
38891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    final String s = "CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: "
38901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + "sEnableFailFastRefCounter:" + sEnableFailFastRefCounter + " < 0";
38911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge(s);
38921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    sEnableFailFastRefCounter = 0;
38931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = sEnableFailFastRefCounter > 0;
38951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
38961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: enabled=" + enabled
38971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + " sEnableFailFastRefCounter=" + sEnableFailFastRefCounter);
38981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (mFailFast != enabled) {
39001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mFailFast = enabled;
39010e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
39021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mDataStallDetectionEnabled = !enabled;
39031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mDataStallDetectionEnabled
39041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            && (getOverallState() == DctConstants.State.CONNECTED)
39051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            && (!mInVoiceCall ||
39061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    mPhone.getServiceStateTracker()
39071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                        .isConcurrentVoiceAndDataAllowed())) {
39081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: start data stall");
39091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        stopDataStallAlarm();
39101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
39111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
39121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: stop data stall");
39131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        stopDataStallAlarm();
39141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
39151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
39162b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen
39171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_ENABLE_MOBILE_PROVISIONING: {
39201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Bundle bundle = msg.getData();
39211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (bundle != null) {
39221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    try {
39231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mProvisioningUrl = (String)bundle.get(DctConstants.PROVISIONING_URL_KEY);
39241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } catch(ClassCastException e) {
39251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioning url not a string" + e);
39261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mProvisioningUrl = null;
39271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
39281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
39291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (TextUtils.isEmpty(mProvisioningUrl)) {
39301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioning url is empty, ignoring");
39311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mIsProvisioning = false;
39321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mProvisioningUrl = null;
39331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
39341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioningUrl=" + mProvisioningUrl);
39351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mIsProvisioning = true;
39361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    startProvisioningApnAlarm();
39371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
39381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_PROVISIONING_APN_ALARM: {
39411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("EVENT_PROVISIONING_APN_ALARM");
3942af5593594070f825032be46dced573cd195956e1Robert Greenwalt                ApnContext apnCtx = mApnContextsById.get(DctConstants.APN_DEFAULT_ID);
39431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (apnCtx.isProvisioningApn() && apnCtx.isConnectedOrConnecting()) {
39441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mProvisioningApnAlarmTag == msg.arg1) {
39451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) log("EVENT_PROVISIONING_APN_ALARM: Disconnecting");
39461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mIsProvisioning = false;
39471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mProvisioningUrl = null;
39481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        stopProvisioningApnAlarm();
39491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        sendCleanUpConnection(true, apnCtx);
39501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
39511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) {
39521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            log("EVENT_PROVISIONING_APN_ALARM: ignore stale tag,"
39531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    + " mProvisioningApnAlarmTag:" + mProvisioningApnAlarmTag
39541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    + " != arg1:" + msg.arg1);
39551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        }
39561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
39571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
39581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (DBG) log("EVENT_PROVISIONING_APN_ALARM: Not connected ignore");
39591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
39601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_IS_PROVISIONING_APN: {
39631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_IS_PROVISIONING_APN");
39641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                boolean isProvApn;
39651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                try {
39661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    String apnType = null;
39671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    Bundle bundle = msg.getData();
39681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (bundle != null) {
39691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        apnType = (String)bundle.get(DctConstants.APN_TYPE_KEY);
39701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
39711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (TextUtils.isEmpty(apnType)) {
39721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        loge("CMD_IS_PROVISIONING_APN: apnType is empty");
39731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        isProvApn = false;
39741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
39751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        isProvApn = isProvisioningApn(apnType);
39761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
39771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } catch (ClassCastException e) {
39781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge("CMD_IS_PROVISIONING_APN: NO provisioning url ignoring");
39791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    isProvApn = false;
39801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
39811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_IS_PROVISIONING_APN: ret=" + isProvApn);
39821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mReplyAc.replyToMessage(msg, DctConstants.CMD_IS_PROVISIONING_APN,
39831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        isProvApn ? DctConstants.ENABLED : DctConstants.DISABLED);
39841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ICC_CHANGED: {
39871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onUpdateIcc();
39881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RESTART_RADIO: {
39911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartRadio();
39921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_NET_STAT_POLL: {
39951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (msg.arg1 == DctConstants.ENABLED) {
39961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    handleStartNetStatPoll((DctConstants.Activity)msg.obj);
39971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else if (msg.arg1 == DctConstants.DISABLED) {
39981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    handleStopNetStatPoll((DctConstants.Activity)msg.obj);
39991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
40001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
40011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
40022e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            case DctConstants.EVENT_PCO_DATA_RECEIVED: {
40032e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt                handlePcoData((AsyncResult)msg.obj);
40042e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt                break;
40052e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            }
4006a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            case DctConstants.EVENT_SET_CARRIER_DATA_ENABLED:
40076a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu                onSetCarrierDataEnabled((AsyncResult) msg.obj);
4008a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                break;
4009e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu            case DctConstants.EVENT_DATA_RECONNECT:
4010e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                onDataReconnect(msg.getData());
4011e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                break;
401271f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu            case DctConstants.EVENT_DATA_SERVICE_BINDING_CHANGED:
401371f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                onDataServiceBindingChanged((Boolean) ((AsyncResult) msg.obj).result);
4014cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            default:
40151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Rlog.e("DcTracker", "Unhandled event=" + msg);
4016cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
40171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4018cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
4019cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
4020cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
40211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int getApnProfileID(String apnType) {
4022cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IMS)) {
4023cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_IMS;
4024cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_FOTA)) {
4025cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_FOTA;
4026cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_CBS)) {
4027cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_CBS;
40281b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IA)) {
40291b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            return RILConstants.DATA_PROFILE_DEFAULT; // DEFAULT for now
403045df26444864daad60afdd4d121ab4043da3834bSungmin Choi        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_DUN)) {
403145df26444864daad60afdd4d121ab4043da3834bSungmin Choi            return RILConstants.DATA_PROFILE_TETHERED;
4032cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
4033cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_DEFAULT;
4034cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
4035cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
4036cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4037cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private int getCellLocationId() {
4038cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int cid = -1;
4039cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        CellLocation loc = mPhone.getCellLocation();
4040cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4041cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (loc != null) {
4042cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (loc instanceof GsmCellLocation) {
4043cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cid = ((GsmCellLocation)loc).getCid();
4044cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else if (loc instanceof CdmaCellLocation) {
4045cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cid = ((CdmaCellLocation)loc).getBaseStationId();
4046cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
4047cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
4048cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return cid;
4049cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
4050cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4051a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private IccRecords getUiccRecords(int appFamily) {
4052a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return mUiccController.getIccRecords(mPhone.getPhoneId(), appFamily);
4053a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4054a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4055a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
40561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onUpdateIcc() {
4057cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mUiccController == null ) {
4058cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            return;
4059cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
4060cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4061a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        IccRecords newIccRecords = getUiccRecords(UiccController.APP_FAM_3GPP);
4062cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4063cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
4064cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (r != newIccRecords) {
4065cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (r != null) {
4066cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("Removing stale icc objects.");
4067cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                r.unregisterForRecordsLoaded(this);
4068cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIccRecords.set(null);
40699aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan            }
4070cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (newIccRecords != null) {
40711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (SubscriptionManager.isValidSubscriptionId(mPhone.getSubId())) {
4072aa863054476b152fe9323defd197fa946a47033fSungmin Choi                    log("New records found.");
4073aa863054476b152fe9323defd197fa946a47033fSungmin Choi                    mIccRecords.set(newIccRecords);
4074aa863054476b152fe9323defd197fa946a47033fSungmin Choi                    newIccRecords.registerForRecordsLoaded(
4075aa863054476b152fe9323defd197fa946a47033fSungmin Choi                            this, DctConstants.EVENT_RECORDS_LOADED, null);
4076aa863054476b152fe9323defd197fa946a47033fSungmin Choi                }
40770469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal            } else {
40780469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal                onSimNotReady();
40799aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan            }
40809aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan        }
4081cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
4082cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4083a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void update() {
4084a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("update sub = " + mPhone.getSubId());
4085bda761320929f714951c328bfec6a51a1978db97Wink Saville        log("update(): Active DDS, register for all events now!");
4086bda761320929f714951c328bfec6a51a1978db97Wink Saville        onUpdateIcc();
4087a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
40880979b71e48405cab10bdf1d1b4170cfce72838a7Jack Yu        mAutoAttachOnCreation.set(false);
4089bda761320929f714951c328bfec6a51a1978db97Wink Saville
40901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ((GsmCdmaPhone)mPhone).updateCurrentCarrierInProvider();
4091a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4092a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4093a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void cleanUpAllConnections(String cause) {
4094a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cleanUpAllConnections(cause, null);
4095a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4096a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4097a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void updateRecords() {
4098bda761320929f714951c328bfec6a51a1978db97Wink Saville        onUpdateIcc();
4099a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4100a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4101a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void cleanUpAllConnections(String cause, Message disconnectAllCompleteMsg) {
4102a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("cleanUpAllConnections");
4103a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (disconnectAllCompleteMsg != null) {
4104a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mDisconnectAllCompleteMsgList.add(disconnectAllCompleteMsg);
4105a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4106a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4107a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Message msg = obtainMessage(DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS);
4108a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        msg.obj = cause;
4109a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sendMessage(msg);
4110a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4111a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
41121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyDataDisconnectComplete() {
4113a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("notifyDataDisconnectComplete");
4114a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        for (Message m: mDisconnectAllCompleteMsgList) {
4115a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            m.sendToTarget();
4116a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4117a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mDisconnectAllCompleteMsgList.clear();
4118a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4119a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4120a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
41211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyAllDataDisconnected() {
4122a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sEnableFailFastRefCounter = 0;
4123a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mFailFast = false;
4124a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.notifyRegistrants();
4125a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4126a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4127a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void registerForAllDataDisconnected(Handler h, int what, Object obj) {
4128a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.addUnique(h, what, obj);
4129a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4130a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (isDisconnected()) {
4131a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("notify All Data Disconnected");
4132a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
4133a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4134a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4135a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4136a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void unregisterForAllDataDisconnected(Handler h) {
4137a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.remove(h);
4138a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4139a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4140a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    public void registerForDataEnabledChanged(Handler h, int what, Object obj) {
4141a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        mDataEnabledSettings.registerForDataEnabledChanged(h, what, obj);
4142a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    }
4143a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
4144a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    public void unregisterForDataEnabledChanged(Handler h) {
4145a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        mDataEnabledSettings.unregisterForDataEnabledChanged(h);
4146a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    }
4147a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
41481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetInternalDataEnabled(boolean enabled, Message onCompleteMsg) {
414912161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen        if (DBG) log("onSetInternalDataEnabled: enabled=" + enabled);
415012161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen        boolean sendOnComplete = true;
4151a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
415212161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen        mDataEnabledSettings.setInternalDataEnabled(enabled);
415312161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen        if (enabled) {
415412161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen            log("onSetInternalDataEnabled: changed to enabled, try to setup data call");
415512161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen            onTrySetupData(Phone.REASON_DATA_ENABLED);
415612161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen        } else {
415712161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen            sendOnComplete = false;
415812161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen            log("onSetInternalDataEnabled: changed to disabled, cleanUpAllConnections");
415912161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen            cleanUpAllConnections(Phone.REASON_DATA_DISABLED, onCompleteMsg);
416012161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen        }
4161a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
416212161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen        if (sendOnComplete) {
416312161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen            if (onCompleteMsg != null) {
416412161f13cb8fc7443c86b26753c078b33b762077Malcolm Chen                onCompleteMsg.sendToTarget();
4165a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
4166a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4167a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4168a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4169a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean setInternalDataEnabled(boolean enable) {
4170a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return setInternalDataEnabled(enable, null);
4171a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4172a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4173a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean setInternalDataEnabled(boolean enable, Message onCompleteMsg) {
41746bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        if (DBG) log("setInternalDataEnabled(" + enable + ")");
4175a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4176a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Message msg = obtainMessage(DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE, onCompleteMsg);
4177a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        msg.arg1 = (enable ? DctConstants.ENABLED : DctConstants.DISABLED);
4178a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sendMessage(msg);
4179a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return true;
4180a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4181a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
41821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void log(String s) {
4183a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Rlog.d(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s);
4184cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
4185cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
41861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void loge(String s) {
4187a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Rlog.e(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s);
4188cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
4189cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4190c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
41911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println("DcTracker:");
41921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" RADIO_TESTS=" + RADIO_TESTS);
419399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        pw.println(" mDataEnabledSettings=" + mDataEnabledSettings);
419499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        pw.println(" isDataAllowed=" + isDataAllowed(null));
41951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
41961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mRequestedApnType=" + mRequestedApnType);
41971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mPhone=" + mPhone.getPhoneName());
41981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mActivity=" + mActivity);
41991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mState=" + mState);
42001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mTxPkts=" + mTxPkts);
42011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mRxPkts=" + mRxPkts);
42021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mNetStatPollPeriod=" + mNetStatPollPeriod);
42031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mNetStatPollEnabled=" + mNetStatPollEnabled);
42041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mDataStallTxRxSum=" + mDataStallTxRxSum);
42051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mDataStallAlarmTag=" + mDataStallAlarmTag);
4206a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        pw.println(" mDataStallDetectionEnabled=" + mDataStallDetectionEnabled);
42071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mSentSinceLastRecv=" + mSentSinceLastRecv);
42081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mNoRecvPollCount=" + mNoRecvPollCount);
42091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mResolver=" + mResolver);
42101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mReconnectIntent=" + mReconnectIntent);
42111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mAutoAttachOnCreation=" + mAutoAttachOnCreation.get());
42121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsScreenOn=" + mIsScreenOn);
42131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mUniqueIdGenerator=" + mUniqueIdGenerator);
4214d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen        pw.println(" mDataRoamingLeakageLog= ");
4215d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen        mDataRoamingLeakageLog.dump(fd, pw, args);
42161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
42171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
42181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        DcController dcc = mDcc;
42191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (dcc != null) {
42201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            dcc.dump(fd, pw, args);
42211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
42221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mDcc=null");
42231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
42241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
42251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        HashMap<Integer, DataConnection> dcs = mDataConnections;
42261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (dcs != null) {
42271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Set<Entry<Integer, DataConnection> > mDcSet = mDataConnections.entrySet();
42281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mDataConnections: count=" + mDcSet.size());
42291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (Entry<Integer, DataConnection> entry : mDcSet) {
42301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                pw.printf(" *** mDataConnection[%d] \n", entry.getKey());
42311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                entry.getValue().dump(fd, pw, args);
42321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
42331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
42341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println("mDataConnections=null");
42351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
42361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
42371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
42381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        HashMap<String, Integer> apnToDcId = mApnToDataConnectionId;
42391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (apnToDcId != null) {
42401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Set<Entry<String, Integer>> apnToDcIdSet = apnToDcId.entrySet();
42411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mApnToDataConnectonId size=" + apnToDcIdSet.size());
42421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (Entry<String, Integer> entry : apnToDcIdSet) {
42431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                pw.printf(" mApnToDataConnectonId[%s]=%d\n", entry.getKey(), entry.getValue());
42441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
42451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
42461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println("mApnToDataConnectionId=null");
42471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
42481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
42491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
42501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ConcurrentHashMap<String, ApnContext> apnCtxs = mApnContexts;
42511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (apnCtxs != null) {
42521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Set<Entry<String, ApnContext>> apnCtxsSet = apnCtxs.entrySet();
42531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mApnContexts size=" + apnCtxsSet.size());
42541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (Entry<String, ApnContext> entry : apnCtxsSet) {
42551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                entry.getValue().dump(fd, pw, args);
42561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
42571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" ***************************************");
42581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
42591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mApnContexts=null");
42601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
42611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
42621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ArrayList<ApnSetting> apnSettings = mAllApnSettings;
42631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (apnSettings != null) {
42641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mAllApnSettings size=" + apnSettings.size());
42651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (int i=0; i < apnSettings.size(); i++) {
42661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                pw.printf(" mAllApnSettings[%d]: %s\n", i, apnSettings.get(i));
42671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
42681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.flush();
42691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
42701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mAllApnSettings=null");
42711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
42721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mPreferredApn=" + mPreferredApn);
42731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsPsRestricted=" + mIsPsRestricted);
42741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsDisposed=" + mIsDisposed);
42751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIntentReceiver=" + mIntentReceiver);
4276cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mReregisterOnReconnectFailure=" + mReregisterOnReconnectFailure);
427722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" canSetPreferApn=" + mCanSetPreferApn);
4278cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mApnObserver=" + mApnObserver);
4279cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" getOverallState=" + getOverallState());
4280ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        pw.println(" mDataConnectionAsyncChannels=%s\n" + mDataConnectionAcHashMap);
4281187a39f896f88eb6c5e4306d9595546654825976Wink Saville        pw.println(" mAttached=" + mAttached.get());
4282985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen        mDataEnabledSettings.dump(fd, pw, args);
42831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
4284c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
4285a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4286bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram    public String[] getPcscfAddress(String apnType) {
4287a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("getPcscfAddress()");
4288bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        ApnContext apnContext = null;
4289bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram
4290bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        if(apnType == null){
4291bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            log("apnType is null, return null");
4292bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            return null;
4293bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        }
4294a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4295bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_EMERGENCY)) {
4296af5593594070f825032be46dced573cd195956e1Robert Greenwalt            apnContext = mApnContextsById.get(DctConstants.APN_EMERGENCY_ID);
4297bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IMS)) {
4298af5593594070f825032be46dced573cd195956e1Robert Greenwalt            apnContext = mApnContextsById.get(DctConstants.APN_IMS_ID);
4299bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        } else {
4300bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            log("apnType is invalid, return null");
4301bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            return null;
4302bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        }
4303a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4304a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (apnContext == null) {
4305a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("apnContext is null, return null");
4306a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return null;
4307a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4308a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4309a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        DcAsyncChannel dcac = apnContext.getDcAc();
4310a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        String[] result = null;
4311a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4312a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (dcac != null) {
4313a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            result = dcac.getPcscfAddr();
4314a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4315c0a3ed8c70021d47cd55bbc1406a9cf63bd6afe2Jack Yu            if (result != null) {
4316c0a3ed8c70021d47cd55bbc1406a9cf63bd6afe2Jack Yu                for (int i = 0; i < result.length; i++) {
4317c0a3ed8c70021d47cd55bbc1406a9cf63bd6afe2Jack Yu                    log("Pcscf[" + i + "]: " + result[i]);
4318c0a3ed8c70021d47cd55bbc1406a9cf63bd6afe2Jack Yu                }
4319a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
4320a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return result;
4321a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4322a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return null;
4323a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4324a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
432576f43316a5a6082d601bffd4b6898d0bd81e11fcram    /**
432676f43316a5a6082d601bffd4b6898d0bd81e11fcram     * Read APN configuration from Telephony.db for Emergency APN
432776f43316a5a6082d601bffd4b6898d0bd81e11fcram     * All opertors recognize the connection request for EPDN based on APN type
432876f43316a5a6082d601bffd4b6898d0bd81e11fcram     * PLMN name,APN name are not mandatory parameters
432976f43316a5a6082d601bffd4b6898d0bd81e11fcram     */
433076f43316a5a6082d601bffd4b6898d0bd81e11fcram    private void initEmergencyApnSetting() {
433176f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Operator Numeric is not available when sim records are not loaded.
433276f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Query Telephony.db with APN type as EPDN request does not
433376f43316a5a6082d601bffd4b6898d0bd81e11fcram        // require APN name, plmn and all operators support same APN config.
433476f43316a5a6082d601bffd4b6898d0bd81e11fcram        // DB will contain only one entry for Emergency APN
433576f43316a5a6082d601bffd4b6898d0bd81e11fcram        String selection = "type=\"emergency\"";
433676f43316a5a6082d601bffd4b6898d0bd81e11fcram        Cursor cursor = mPhone.getContext().getContentResolver().query(
4337030fdfb7ccdf5dce9a6b48ca07918082627200f4yuemingw                Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "filtered"),
4338030fdfb7ccdf5dce9a6b48ca07918082627200f4yuemingw                null, selection, null, null);
433976f43316a5a6082d601bffd4b6898d0bd81e11fcram
434076f43316a5a6082d601bffd4b6898d0bd81e11fcram        if (cursor != null) {
434176f43316a5a6082d601bffd4b6898d0bd81e11fcram            if (cursor.getCount() > 0) {
434276f43316a5a6082d601bffd4b6898d0bd81e11fcram                if (cursor.moveToFirst()) {
434376f43316a5a6082d601bffd4b6898d0bd81e11fcram                    mEmergencyApn = makeApnSetting(cursor);
434476f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
434576f43316a5a6082d601bffd4b6898d0bd81e11fcram            }
434676f43316a5a6082d601bffd4b6898d0bd81e11fcram            cursor.close();
434776f43316a5a6082d601bffd4b6898d0bd81e11fcram        }
434876f43316a5a6082d601bffd4b6898d0bd81e11fcram    }
434976f43316a5a6082d601bffd4b6898d0bd81e11fcram
435076f43316a5a6082d601bffd4b6898d0bd81e11fcram    /**
435176f43316a5a6082d601bffd4b6898d0bd81e11fcram     * Add the Emergency APN settings to APN settings list
435276f43316a5a6082d601bffd4b6898d0bd81e11fcram     */
435376f43316a5a6082d601bffd4b6898d0bd81e11fcram    private void addEmergencyApnSetting() {
435476f43316a5a6082d601bffd4b6898d0bd81e11fcram        if(mEmergencyApn != null) {
435576f43316a5a6082d601bffd4b6898d0bd81e11fcram            if(mAllApnSettings == null) {
435676f43316a5a6082d601bffd4b6898d0bd81e11fcram                mAllApnSettings = new ArrayList<ApnSetting>();
435776f43316a5a6082d601bffd4b6898d0bd81e11fcram            } else {
435876f43316a5a6082d601bffd4b6898d0bd81e11fcram                boolean hasEmergencyApn = false;
435976f43316a5a6082d601bffd4b6898d0bd81e11fcram                for (ApnSetting apn : mAllApnSettings) {
436076f43316a5a6082d601bffd4b6898d0bd81e11fcram                    if (ArrayUtils.contains(apn.types, PhoneConstants.APN_TYPE_EMERGENCY)) {
436176f43316a5a6082d601bffd4b6898d0bd81e11fcram                        hasEmergencyApn = true;
436276f43316a5a6082d601bffd4b6898d0bd81e11fcram                        break;
436376f43316a5a6082d601bffd4b6898d0bd81e11fcram                    }
436476f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
436576f43316a5a6082d601bffd4b6898d0bd81e11fcram
436676f43316a5a6082d601bffd4b6898d0bd81e11fcram                if(hasEmergencyApn == false) {
436776f43316a5a6082d601bffd4b6898d0bd81e11fcram                    mAllApnSettings.add(mEmergencyApn);
436876f43316a5a6082d601bffd4b6898d0bd81e11fcram                } else {
436976f43316a5a6082d601bffd4b6898d0bd81e11fcram                    log("addEmergencyApnSetting - E-APN setting is already present");
437076f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
437176f43316a5a6082d601bffd4b6898d0bd81e11fcram            }
437276f43316a5a6082d601bffd4b6898d0bd81e11fcram        }
437376f43316a5a6082d601bffd4b6898d0bd81e11fcram    }
43749a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
43759fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu    private boolean containsAllApns(ArrayList<ApnSetting> oldApnList,
43769fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                                    ArrayList<ApnSetting> newApnList) {
43779fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu        for (ApnSetting newApnSetting : newApnList) {
43789fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            boolean canHandle = false;
43799fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            for (ApnSetting oldApnSetting : oldApnList) {
43809fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                // Make sure at least one of the APN from old list can cover the new APN
43819fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                if (oldApnSetting.equals(newApnSetting,
43829fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                        mPhone.getServiceState().getDataRoamingFromRegistration())) {
43839fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                    canHandle = true;
43849fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                    break;
43859fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                }
43869fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            }
43879fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            if (!canHandle) return false;
43889fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu        }
43899fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu        return true;
43909fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu    }
43919fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu
4392ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu    private void cleanUpConnectionsOnUpdatedApns(boolean tearDown, String reason) {
43939a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (DBG) log("cleanUpConnectionsOnUpdatedApns: tearDown=" + tearDown);
4394ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu        if (mAllApnSettings != null && mAllApnSettings.isEmpty()) {
43959a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            cleanUpAllConnections(tearDown, Phone.REASON_APN_CHANGED);
43969a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        } else {
4397e996a89f15d07d8c9fae23e9b03d47fff17087d8fionaxu            int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
4398e996a89f15d07d8c9fae23e9b03d47fff17087d8fionaxu            if (radioTech == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
4399e996a89f15d07d8c9fae23e9b03d47fff17087d8fionaxu                // unknown rat is an exception for data rat change. Its only received when out of
4400e996a89f15d07d8c9fae23e9b03d47fff17087d8fionaxu                // service and is not applicable for apn bearer bitmask. We should bypass the check
4401e996a89f15d07d8c9fae23e9b03d47fff17087d8fionaxu                // of waiting apn list and keep the data connection on.
4402e996a89f15d07d8c9fae23e9b03d47fff17087d8fionaxu                return;
4403e996a89f15d07d8c9fae23e9b03d47fff17087d8fionaxu            }
44049a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            for (ApnContext apnContext : mApnContexts.values()) {
44059a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                ArrayList<ApnSetting> currentWaitingApns = apnContext.getWaitingApns();
4406ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                ArrayList<ApnSetting> waitingApns = buildWaitingApns(
4407b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                        apnContext.getApnType(),
4408b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                        mPhone.getServiceState().getRilDataRadioTechnology());
4409ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                if (VDBG) log("new waitingApns:" + waitingApns);
4410ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                if ((currentWaitingApns != null)
4411ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                        && ((waitingApns.size() != currentWaitingApns.size())
44129fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                        // Check if the existing waiting APN list can cover the newly built APN
44139fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                        // list. If yes, then we don't need to tear down the existing data call.
44149fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                        // TODO: We probably need to rebuild APN list when roaming status changes.
44159fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                        || !containsAllApns(currentWaitingApns, waitingApns))) {
4416ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                    if (VDBG) log("new waiting apn is different for " + apnContext);
4417ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                    apnContext.setWaitingApns(waitingApns);
4418ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                    if (!apnContext.isDisconnected()) {
4419ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                        if (VDBG) log("cleanUpConnectionsOnUpdatedApns for " + apnContext);
4420ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                        apnContext.setReason(reason);
4421ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                        cleanUpConnection(true, apnContext);
44229a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    }
44239a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                }
44249a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            }
44259a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        }
44269a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
44279a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (!isConnected()) {
44289a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            stopNetStatPoll();
44299a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            stopDataStallAlarm();
44309a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        }
44319a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
44329a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
44339a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
44349a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (DBG) log("mDisconnectPendingCount = " + mDisconnectPendingCount);
44359a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (tearDown && mDisconnectPendingCount == 0) {
44369a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            notifyDataDisconnectComplete();
44379a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            notifyAllDataDisconnected();
44389a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        }
44399a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang    }
44401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
44421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Polling stuff
44431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
44441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void resetPollStats() {
44451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mTxPkts = -1;
44461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mRxPkts = -1;
44471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mNetStatPollPeriod = POLL_NETSTAT_MILLIS;
44481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void startNetStatPoll() {
44511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (getOverallState() == DctConstants.State.CONNECTED
44521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                && mNetStatPollEnabled == false) {
44531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
44541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("startNetStatPoll");
44551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
44561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            resetPollStats();
44571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mNetStatPollEnabled = true;
44581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPollNetStat.run();
44591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mPhone != null) {
44611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPhone.notifyDataActivity();
44621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void stopNetStatPoll() {
44661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mNetStatPollEnabled = false;
44671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        removeCallbacks(mPollNetStat);
44681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
44691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("stopNetStatPoll");
44701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // To sync data activity icon in the case of switching data connection to send MMS.
44731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mPhone != null) {
44741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPhone.notifyDataActivity();
44751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void sendStartNetStatPoll(DctConstants.Activity activity) {
44791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.CMD_NET_STAT_POLL);
44801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = DctConstants.ENABLED;
44811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.obj = activity;
44821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
44831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void handleStartNetStatPoll(DctConstants.Activity activity) {
44861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startNetStatPoll();
44871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
44881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        setActivity(activity);
44891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void sendStopNetStatPoll(DctConstants.Activity activity) {
44921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.CMD_NET_STAT_POLL);
44931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = DctConstants.DISABLED;
44941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.obj = activity;
44951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
44961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void handleStopNetStatPoll(DctConstants.Activity activity) {
44991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        stopNetStatPoll();
45001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        stopDataStallAlarm();
45011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        setActivity(activity);
45021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void updateDataActivity() {
45051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        long sent, received;
45061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        DctConstants.Activity newActivity;
45081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        TxRxSum preTxRxSum = new TxRxSum(mTxPkts, mRxPkts);
45101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        TxRxSum curTxRxSum = new TxRxSum();
45111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        curTxRxSum.updateTxRxSum();
45121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mTxPkts = curTxRxSum.txPkts;
45131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mRxPkts = curTxRxSum.rxPkts;
45141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) {
45161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("updateDataActivity: curTxRxSum=" + curTxRxSum + " preTxRxSum=" + preTxRxSum);
45171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
45181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mNetStatPollEnabled && (preTxRxSum.txPkts > 0 || preTxRxSum.rxPkts > 0)) {
45201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            sent = mTxPkts - preTxRxSum.txPkts;
45211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            received = mRxPkts - preTxRxSum.rxPkts;
45221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG)
45241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("updateDataActivity: sent=" + sent + " received=" + received);
45251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (sent > 0 && received > 0) {
45261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = DctConstants.Activity.DATAINANDOUT;
45271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (sent > 0 && received == 0) {
45281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = DctConstants.Activity.DATAOUT;
45291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (sent == 0 && received > 0) {
45301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = DctConstants.Activity.DATAIN;
45311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
45321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = (mActivity == DctConstants.Activity.DORMANT) ?
45331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mActivity : DctConstants.Activity.NONE;
45341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
45351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mActivity != newActivity && mIsScreenOn) {
45371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (VDBG)
45381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("updateDataActivity: newActivity=" + newActivity);
45391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mActivity = newActivity;
45401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mPhone.notifyDataActivity();
45411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
45421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
45431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45452e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt    private void handlePcoData(AsyncResult ar) {
45462e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        if (ar.exception != null) {
45472e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            Rlog.e(LOG_TAG, "PCO_DATA exception: " + ar.exception);
45482e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            return;
45492e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        }
45502e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        PcoData pcoData = (PcoData)(ar.result);
4551cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        ArrayList<DataConnection> dcList = new ArrayList<>();
4552cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        DataConnection temp = mDcc.getActiveDcByCid(pcoData.cid);
4553cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        if (temp != null) {
4554cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            dcList.add(temp);
4555cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        }
4556cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        if (dcList.size() == 0) {
4557cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            Rlog.e(LOG_TAG, "PCO_DATA for unknown cid: " + pcoData.cid + ", inferring");
4558cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            for (DataConnection dc : mDataConnections.values()) {
4559cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                final int cid = dc.getCid();
4560cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                if (cid == pcoData.cid) {
4561cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    if (VDBG) Rlog.d(LOG_TAG, "  found " + dc);
4562cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    dcList.clear();
4563cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    dcList.add(dc);
4564cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    break;
4565cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                }
4566cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                // check if this dc is still connecting
4567cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                if (cid == -1) {
4568cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    for (ApnContext apnContext : dc.mApnContexts.keySet()) {
4569cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        if (apnContext.getState() == DctConstants.State.CONNECTING) {
4570cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                            if (VDBG) Rlog.d(LOG_TAG, "  found potential " + dc);
4571cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                            dcList.add(dc);
4572cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                            break;
4573cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        }
4574cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    }
4575cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                }
4576cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            }
4577cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        }
4578cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        if (dcList.size() == 0) {
4579cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            Rlog.e(LOG_TAG, "PCO_DATA - couldn't infer cid");
45802e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            return;
45812e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        }
4582cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        for (DataConnection dc : dcList) {
4583cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            if (dc.mApnContexts.size() == 0) {
4584cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                break;
4585cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            }
4586cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            // send one out for each apn type in play
4587cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            for (ApnContext apnContext : dc.mApnContexts.keySet()) {
4588cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                String apnType = apnContext.getApnType();
4589cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt
4590cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                final Intent intent = new Intent(TelephonyIntents.ACTION_CARRIER_SIGNAL_PCO_VALUE);
4591cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                intent.putExtra(TelephonyIntents.EXTRA_APN_TYPE_KEY, apnType);
4592cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                intent.putExtra(TelephonyIntents.EXTRA_APN_PROTO_KEY, pcoData.bearerProto);
4593cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                intent.putExtra(TelephonyIntents.EXTRA_PCO_ID_KEY, pcoData.pcoId);
4594cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                intent.putExtra(TelephonyIntents.EXTRA_PCO_VALUE_KEY, pcoData.contents);
4595cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
4596cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            }
45972e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        }
45982e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt    }
45992e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt
46001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
46011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Data-Stall
46021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
46031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Recovery action taken in case of data stall
46041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static class RecoveryAction {
46051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int GET_DATA_CALL_LIST      = 0;
46061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int CLEANUP                 = 1;
46071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int REREGISTER              = 2;
46081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int RADIO_RESTART           = 3;
46091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        private static boolean isAggressiveRecovery(int value) {
46111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return ((value == RecoveryAction.CLEANUP) ||
46121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    (value == RecoveryAction.REREGISTER) ||
4613fc7e59579742d8888abd288ac5c36f2da17c29dbNathan Harold                    (value == RecoveryAction.RADIO_RESTART));
46141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
46161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int getRecoveryAction() {
46181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int action = Settings.System.getInt(mResolver,
46191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                "radio.data.stall.recovery.action", RecoveryAction.GET_DATA_CALL_LIST);
46201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("getRecoveryAction: " + action);
46211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return action;
46221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
46231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void putRecoveryAction(int action) {
46251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Settings.System.putInt(mResolver, "radio.data.stall.recovery.action", action);
46261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("putRecoveryAction: " + action);
46271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
46281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
462964928c72f74688d63a20cd233c28fc089d336a7aJayachandran C    private void broadcastDataStallDetected(int recoveryAction) {
463064928c72f74688d63a20cd233c28fc089d336a7aJayachandran C        Intent intent = new Intent(TelephonyManager.ACTION_DATA_STALL_DETECTED);
463164928c72f74688d63a20cd233c28fc089d336a7aJayachandran C        SubscriptionManager.putPhoneIdAndSubIdExtra(intent, mPhone.getPhoneId());
463264928c72f74688d63a20cd233c28fc089d336a7aJayachandran C        intent.putExtra(TelephonyManager.EXTRA_RECOVERY_ACTION, recoveryAction);
463364928c72f74688d63a20cd233c28fc089d336a7aJayachandran C        mPhone.getContext().sendBroadcast(intent, READ_PHONE_STATE);
463464928c72f74688d63a20cd233c28fc089d336a7aJayachandran C    }
463564928c72f74688d63a20cd233c28fc089d336a7aJayachandran C
46361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void doRecovery() {
46371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (getOverallState() == DctConstants.State.CONNECTED) {
46381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Go through a series of recovery steps, each action transitions to the next action
46390a39f581e11eb7b040a5412229164ef72044279fRobert Greenwalt            final int recoveryAction = getRecoveryAction();
4640f2d0fa64860a12423fb8709766d6af90fba5e6cfJack Yu            TelephonyMetrics.getInstance().writeDataStallEvent(mPhone.getPhoneId(), recoveryAction);
464164928c72f74688d63a20cd233c28fc089d336a7aJayachandran C            broadcastDataStallDetected(recoveryAction);
464264928c72f74688d63a20cd233c28fc089d336a7aJayachandran C
46431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            switch (recoveryAction) {
464471f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                case RecoveryAction.GET_DATA_CALL_LIST:
464571f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_GET_DATA_CALL_LIST,
464671f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                            mSentSinceLastRecv);
464771f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    if (DBG) log("doRecovery() get data call list");
464871f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    mDataServiceManager.getDataCallList(obtainMessage());
464971f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    putRecoveryAction(RecoveryAction.CLEANUP);
465071f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    break;
465171f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                case RecoveryAction.CLEANUP:
465271f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_CLEANUP,
465371f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                            mSentSinceLastRecv);
465471f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    if (DBG) log("doRecovery() cleanup all connections");
465571f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    cleanUpAllConnections(Phone.REASON_PDP_RESET);
465671f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    putRecoveryAction(RecoveryAction.REREGISTER);
465771f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    break;
465871f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                case RecoveryAction.REREGISTER:
465971f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_REREGISTER,
466071f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                            mSentSinceLastRecv);
466171f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    if (DBG) log("doRecovery() re-register");
466271f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    mPhone.getServiceStateTracker().reRegisterNetwork(null);
466371f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    putRecoveryAction(RecoveryAction.RADIO_RESTART);
466471f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    break;
466571f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                case RecoveryAction.RADIO_RESTART:
466671f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART,
466771f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                            mSentSinceLastRecv);
466871f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    if (DBG) log("restarting radio");
466971f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    restartRadio();
467071f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
467171f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    break;
467271f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                default:
467371f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    throw new RuntimeException("doRecovery: Invalid recoveryAction="
467471f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                            + recoveryAction);
46751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSentSinceLastRecv = 0;
46771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
46791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void updateDataStallInfo() {
46811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        long sent, received;
46821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        TxRxSum preTxRxSum = new TxRxSum(mDataStallTxRxSum);
46841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDataStallTxRxSum.updateTxRxSum();
46851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) {
46871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("updateDataStallInfo: mDataStallTxRxSum=" + mDataStallTxRxSum +
46881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " preTxRxSum=" + preTxRxSum);
46891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sent = mDataStallTxRxSum.txPkts - preTxRxSum.txPkts;
46921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        received = mDataStallTxRxSum.rxPkts - preTxRxSum.rxPkts;
46931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (RADIO_TESTS) {
46951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (SystemProperties.getBoolean("radio.test.data.stall", false)) {
46961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("updateDataStallInfo: radio.test.data.stall true received = 0;");
46971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                received = 0;
46981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if ( sent > 0 && received > 0 ) {
47011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) log("updateDataStallInfo: IN/OUT");
47021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSentSinceLastRecv = 0;
47031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
47041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (sent > 0 && received == 0) {
47056a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta            if (isPhoneStateIdle()) {
47061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mSentSinceLastRecv += sent;
47071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
47081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mSentSinceLastRecv = 0;
47091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
47111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("updateDataStallInfo: OUT sent=" + sent +
47121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        " mSentSinceLastRecv=" + mSentSinceLastRecv);
47131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (sent == 0 && received > 0) {
47151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) log("updateDataStallInfo: IN");
47161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSentSinceLastRecv = 0;
47171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
47181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
47191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) log("updateDataStallInfo: NONE");
47201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47236a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta    private boolean isPhoneStateIdle() {
47246a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta        for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
47256a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta            Phone phone = PhoneFactory.getPhone(i);
47266a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta            if (phone != null && phone.getState() != PhoneConstants.State.IDLE) {
47276a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta                log("isPhoneStateIdle false: Voice call active on phone " + i);
47286a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta                return false;
47296a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta            }
47306a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta        }
47316a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta        return true;
47326a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta    }
47336a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta
47341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataStallAlarm(int tag) {
47351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mDataStallAlarmTag != tag) {
47361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
47371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("onDataStallAlarm: ignore, tag=" + tag + " expecting " + mDataStallAlarmTag);
47381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return;
47401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        updateDataStallInfo();
47421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int hangWatchdogTrigger = Settings.Global.getInt(mResolver,
47441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Settings.Global.PDP_WATCHDOG_TRIGGER_PACKET_COUNT,
47451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                NUMBER_SENT_PACKETS_OF_HANG);
47461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        boolean suspectedStall = DATA_STALL_NOT_SUSPECTED;
47481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mSentSinceLastRecv >= hangWatchdogTrigger) {
47491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
47501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("onDataStallAlarm: tag=" + tag + " do recovery action=" + getRecoveryAction());
47511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            suspectedStall = DATA_STALL_SUSPECTED;
47531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            sendMessage(obtainMessage(DctConstants.EVENT_DO_RECOVERY));
47541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
47551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) {
47561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("onDataStallAlarm: tag=" + tag + " Sent " + String.valueOf(mSentSinceLastRecv) +
47571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " pkts since last received, < watchdogTrigger=" + hangWatchdogTrigger);
47581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startDataStallAlarm(suspectedStall);
47611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void startDataStallAlarm(boolean suspectedStall) {
47641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int nextAction = getRecoveryAction();
47651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int delayInMs;
47661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mDataStallDetectionEnabled && getOverallState() == DctConstants.State.CONNECTED) {
47681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // If screen is on or data stall is currently suspected, set the alarm
47690e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // with an aggressive timeout.
47701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mIsScreenOn || suspectedStall || RecoveryAction.isAggressiveRecovery(nextAction)) {
47711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                delayInMs = Settings.Global.getInt(mResolver,
47721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS,
47731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
47741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
47751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                delayInMs = Settings.Global.getInt(mResolver,
47761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS,
47771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
47781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mDataStallAlarmTag += 1;
47811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) {
47821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("startDataStallAlarm: tag=" + mDataStallAlarmTag +
47831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        " delay=" + (delayInMs / 1000) + "s");
47841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Intent intent = new Intent(INTENT_DATA_STALL_ALARM);
47861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            intent.putExtra(DATA_STALL_ALARM_TAG_EXTRA, mDataStallAlarmTag);
47871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mDataStallAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
47881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    PendingIntent.FLAG_UPDATE_CURRENT);
4789128f3f36854fe183a6dd4d9917906b4723dd234fAjay Dudani            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME,
47901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    SystemClock.elapsedRealtime() + delayInMs, mDataStallAlarmIntent);
47911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
47921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) {
47931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("startDataStallAlarm: NOT started, no connection tag=" + mDataStallAlarmTag);
47941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void stopDataStallAlarm() {
47991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) {
48001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("stopDataStallAlarm: current tag=" + mDataStallAlarmTag +
48011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " mDataStallAlarmIntent=" + mDataStallAlarmIntent);
48021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
48031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDataStallAlarmTag += 1;
48041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mDataStallAlarmIntent != null) {
48051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mAlarmManager.cancel(mDataStallAlarmIntent);
48061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mDataStallAlarmIntent = null;
48071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
48081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
48091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
48101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void restartDataStallAlarm() {
48111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (isConnected() == false) return;
48121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // To be called on screen status change.
48131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // Do not cancel the alarm if it is set with aggressive timeout.
48141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int nextAction = getRecoveryAction();
48151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
48161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (RecoveryAction.isAggressiveRecovery(nextAction)) {
48171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("restartDataStallAlarm: action is pending. not resetting the alarm.");
48181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return;
48191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
48201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("restartDataStallAlarm: stop then start.");
48211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        stopDataStallAlarm();
48221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
48231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
48241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
48251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
48261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Provisioning APN
48271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
48281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onActionIntentProvisioningApnAlarm(Intent intent) {
48291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("onActionIntentProvisioningApnAlarm: action=" + intent.getAction());
48301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_PROVISIONING_APN_ALARM,
48311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                intent.getAction());
48321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = intent.getIntExtra(PROVISIONING_APN_ALARM_TAG_EXTRA, 0);
48331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
48341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
48351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
48361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void startProvisioningApnAlarm() {
48371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int delayInMs = Settings.Global.getInt(mResolver,
48381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                Settings.Global.PROVISIONING_APN_ALARM_DELAY_IN_MS,
48391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                PROVISIONING_APN_ALARM_DELAY_IN_MS_DEFAULT);
48401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (Build.IS_DEBUGGABLE) {
48411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Allow debug code to use a system property to provide another value
48421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            String delayInMsStrg = Integer.toString(delayInMs);
48431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            delayInMsStrg = System.getProperty(DEBUG_PROV_APN_ALARM, delayInMsStrg);
48441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            try {
48451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                delayInMs = Integer.parseInt(delayInMsStrg);
48461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } catch (NumberFormatException e) {
48471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                loge("startProvisioningApnAlarm: e=" + e);
48481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
48491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
48501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisioningApnAlarmTag += 1;
48511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
48521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("startProvisioningApnAlarm: tag=" + mProvisioningApnAlarmTag +
48531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " delay=" + (delayInMs / 1000) + "s");
48541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
48551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Intent intent = new Intent(INTENT_PROVISIONING_APN_ALARM);
48561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        intent.putExtra(PROVISIONING_APN_ALARM_TAG_EXTRA, mProvisioningApnAlarmTag);
48571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisioningApnAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
48581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                PendingIntent.FLAG_UPDATE_CURRENT);
48591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
48601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                SystemClock.elapsedRealtime() + delayInMs, mProvisioningApnAlarmIntent);
48611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
48621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
48631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void stopProvisioningApnAlarm() {
48641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
48651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("stopProvisioningApnAlarm: current tag=" + mProvisioningApnAlarmTag +
48661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " mProvsioningApnAlarmIntent=" + mProvisioningApnAlarmIntent);
48671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
48681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisioningApnAlarmTag += 1;
48691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mProvisioningApnAlarmIntent != null) {
48701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mAlarmManager.cancel(mProvisioningApnAlarmIntent);
48711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mProvisioningApnAlarmIntent = null;
48721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
48731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
48741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4875886183cde1263ea524cdf08524442724e246ed42Jack Yu    private static DataProfile createDataProfile(ApnSetting apn) {
4876886183cde1263ea524cdf08524442724e246ed42Jack Yu        return createDataProfile(apn, apn.profileId);
4877886183cde1263ea524cdf08524442724e246ed42Jack Yu    }
4878886183cde1263ea524cdf08524442724e246ed42Jack Yu
4879886183cde1263ea524cdf08524442724e246ed42Jack Yu    @VisibleForTesting
4880886183cde1263ea524cdf08524442724e246ed42Jack Yu    public static DataProfile createDataProfile(ApnSetting apn, int profileId) {
4881886183cde1263ea524cdf08524442724e246ed42Jack Yu        int profileType;
4882176f28521fd45bb739709d309e7970b1558c9f61Cassie
4883176f28521fd45bb739709d309e7970b1558c9f61Cassie        int bearerBitmap = 0;
4884176f28521fd45bb739709d309e7970b1558c9f61Cassie        bearerBitmap = ServiceState.convertNetworkTypeBitmaskToBearerBitmask(
4885176f28521fd45bb739709d309e7970b1558c9f61Cassie                apn.networkTypeBitmask);
4886176f28521fd45bb739709d309e7970b1558c9f61Cassie
4887176f28521fd45bb739709d309e7970b1558c9f61Cassie        if (bearerBitmap == 0) {
4888886183cde1263ea524cdf08524442724e246ed42Jack Yu            profileType = DataProfile.TYPE_COMMON;
4889176f28521fd45bb739709d309e7970b1558c9f61Cassie        } else if (ServiceState.bearerBitmapHasCdma(bearerBitmap)) {
4890886183cde1263ea524cdf08524442724e246ed42Jack Yu            profileType = DataProfile.TYPE_3GPP2;
4891886183cde1263ea524cdf08524442724e246ed42Jack Yu        } else {
4892886183cde1263ea524cdf08524442724e246ed42Jack Yu            profileType = DataProfile.TYPE_3GPP;
4893886183cde1263ea524cdf08524442724e246ed42Jack Yu        }
4894886183cde1263ea524cdf08524442724e246ed42Jack Yu
4895886183cde1263ea524cdf08524442724e246ed42Jack Yu        return new DataProfile(profileId, apn.apn, apn.protocol,
4896886183cde1263ea524cdf08524442724e246ed42Jack Yu                apn.authType, apn.user, apn.password, profileType,
4897886183cde1263ea524cdf08524442724e246ed42Jack Yu                apn.maxConnsTime, apn.maxConns, apn.waitTime, apn.carrierEnabled, apn.typesBitmap,
4898176f28521fd45bb739709d309e7970b1558c9f61Cassie                apn.roamingProtocol, bearerBitmap, apn.mtu, apn.mvnoType, apn.mvnoMatchData,
4899886183cde1263ea524cdf08524442724e246ed42Jack Yu                apn.modemCognitive);
4900886183cde1263ea524cdf08524442724e246ed42Jack Yu    }
490171f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu
490271f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu    private void onDataServiceBindingChanged(boolean bound) {
490371f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        if (bound) {
490471f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu            mDcc.start();
490571f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        } else {
490671f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu            mDcc.dispose();
490771f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        }
490871f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu    }
4909c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville}
4910