DcTracker.java revision 71f909237a9921f52d91440fb8f9c6fc97465a52
1c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/*
2c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Copyright (C) 2006 The Android Open Source Project
3c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
4c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Licensed under the Apache License, Version 2.0 (the "License");
5c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * you may not use this file except in compliance with the License.
6c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * You may obtain a copy of the License at
7c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
8c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *      http://www.apache.org/licenses/LICENSE-2.0
9c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
10c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Unless required by applicable law or agreed to in writing, software
11c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * distributed under the License is distributed on an "AS IS" BASIS,
12c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * See the License for the specific language governing permissions and
14c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * limitations under the License.
15c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
16c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
174918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savillepackage com.android.internal.telephony.dataconnection;
18c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
19cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kallaimport android.app.AlarmManager;
20c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.app.PendingIntent;
212b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensenimport android.app.ProgressDialog;
22c9b81a0c05128694c617fcdd67e73821895822feWink Savilleimport android.content.ActivityNotFoundException;
23b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensenimport android.content.BroadcastReceiver;
24c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.ContentResolver;
25cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.content.ContentValues;
26c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Context;
27c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Intent;
28c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.IntentFilter;
291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.content.SharedPreferences;
30cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.content.res.Resources;
31c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.database.ContentObserver;
32cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.database.Cursor;
33cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.ConnectivityManager;
34c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.net.LinkProperties;
3596cce86cf08e37e0f09ed5057b1196e26b302743Robert Greenwaltimport android.net.NetworkCapabilities;
36cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.NetworkConfig;
37af5593594070f825032be46dced573cd195956e1Robert Greenwaltimport android.net.NetworkRequest;
38cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.NetworkUtils;
399c180aedfc9f0d20525c0128487d3500e6c0a715Jason Monkimport android.net.ProxyInfo;
401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.net.TrafficStats;
41cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.Uri;
42c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.AsyncResult;
433fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwaltimport android.os.Build;
44b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensenimport android.os.Bundle;
45a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.Handler;
461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.os.HandlerThread;
47c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Message;
48bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liuimport android.os.PersistableBundle;
49a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.RegistrantList;
50b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensenimport android.os.ServiceManager;
51c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemClock;
52c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemProperties;
531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.preference.PreferenceManager;
54c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.provider.Settings;
551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.provider.Settings.SettingNotFoundException;
56cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.provider.Telephony;
5771f909237a9921f52d91440fb8f9c6fc97465a52Jack Yuimport android.telephony.AccessNetworkConstants.TransportType;
58bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liuimport android.telephony.CarrierConfigManager;
59cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.CellLocation;
602e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwaltimport android.telephony.PcoData;
614c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport android.telephony.Rlog;
620e776303ca82b5bec5db19bb44e0f13b0c7c6400Etan Cohenimport android.telephony.ServiceState;
63a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.SubscriptionManager;
641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
654c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport android.telephony.TelephonyManager;
66cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.cdma.CdmaCellLocation;
67886183cde1263ea524cdf08524442724e246ed42Jack Yuimport android.telephony.data.DataProfile;
68cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.gsm.GsmCellLocation;
69c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.text.TextUtils;
70cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kallaimport android.util.EventLog;
712dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwaltimport android.util.LocalLog;
72ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwaltimport android.util.Pair;
73af5593594070f825032be46dced573cd195956e1Robert Greenwaltimport android.util.SparseArray;
742b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensenimport android.view.WindowManager;
75c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport com.android.internal.R;
77af5593594070f825032be46dced573cd195956e1Robert Greenwaltimport com.android.internal.annotations.VisibleForTesting;
786a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxuimport com.android.internal.telephony.CarrierActionAgent;
79cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.DctConstants;
80cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.EventLogTags;
814c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport com.android.internal.telephony.GsmCdmaPhone;
82b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensenimport com.android.internal.telephony.ITelephony;
834c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport com.android.internal.telephony.Phone;
844918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savilleimport com.android.internal.telephony.PhoneConstants;
856a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Guttaimport com.android.internal.telephony.PhoneFactory;
86cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.RILConstants;
87b8fa5c7082deeeb17434b42ed4838a5891a38769Jack Yuimport com.android.internal.telephony.SettingsObserver;
88a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxuimport com.android.internal.telephony.TelephonyIntents;
8999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yuimport com.android.internal.telephony.dataconnection.DataConnectionReasons.DataAllowedReasonType;
9099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yuimport com.android.internal.telephony.dataconnection.DataConnectionReasons.DataDisallowedReasonType;
91f2d0fa64860a12423fb8709766d6af90fba5e6cfJack Yuimport com.android.internal.telephony.metrics.TelephonyMetrics;
92d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccRecords;
93bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenkaimport com.android.internal.telephony.uicc.UiccController;
9476f43316a5a6082d601bffd4b6898d0bd81e11fcramimport com.android.internal.util.ArrayUtils;
954c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport com.android.internal.util.AsyncChannel;
96c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
97c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.io.FileDescriptor;
98c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.io.PrintWriter;
99c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.ArrayList;
10029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwaltimport java.util.Arrays;
1011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.Comparator;
1021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.HashMap;
1031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.Map.Entry;
1041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.PriorityQueue;
1051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.Set;
1061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.concurrent.ConcurrentHashMap;
1071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.concurrent.atomic.AtomicBoolean;
1081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.concurrent.atomic.AtomicInteger;
1091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.concurrent.atomic.AtomicReference;
110c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/**
111c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * {@hide}
112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
1130c3ec24396bb8c21b4d89f743b626c13dd35ba7bAmit Mahajanpublic class DcTracker extends Handler {
1141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String LOG_TAG = "DCT";
1151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean DBG = true;
1161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean VDBG = false; // STOPSHIP if true
1171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean VDBG_STALL = false; // STOPSHIP if true
1181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean RADIO_TESTS = false;
1191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1200e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    public AtomicBoolean isCleanupRequired = new AtomicBoolean(false);
1211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final AlarmManager mAlarmManager;
1231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Currently requested APN type (TODO: This should probably be a parameter not a member) */
1251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private String mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
1261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
127a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    // All data enabling/disabling related settings
128985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen    private final DataEnabledSettings mDataEnabledSettings;
129a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
1300a39f581e11eb7b040a5412229164ef72044279fRobert Greenwalt
1311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
1321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * After detecting a potential connection problem, this is the max number
1331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * of subsequent polls before attempting recovery.
1341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
1351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // 1 sec. default polling interval when screen is on.
1361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int POLL_NETSTAT_MILLIS = 1000;
1371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // 10 min. default polling interval when screen is off.
1381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int POLL_NETSTAT_SCREEN_OFF_MILLIS = 1000*60*10;
1391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Default sent packets without ack which triggers initial recovery steps
1401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int NUMBER_SENT_PACKETS_OF_HANG = 10;
1411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Default for the data stall alarm while non-aggressive stall detection
1431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60 * 6;
1441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Default for the data stall alarm for aggressive stall detection
1451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60;
1461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Tag for tracking stale alarms
1471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String DATA_STALL_ALARM_TAG_EXTRA = "data.stall.alram.tag";
1481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean DATA_STALL_SUSPECTED = true;
1501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean DATA_STALL_NOT_SUSPECTED = false;
1511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_RECONNECT_ALARM =
1531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "com.android.internal.telephony.data-reconnect";
1541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_RECONNECT_ALARM_EXTRA_TYPE = "reconnect_alarm_extra_type";
1551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_RECONNECT_ALARM_EXTRA_REASON =
1561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "reconnect_alarm_extra_reason";
1571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_DATA_STALL_ALARM =
1591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "com.android.internal.telephony.data-stall";
1601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DcTesterFailBringUpAll mDcTesterFailBringUpAll;
1621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DcController mDcc;
1631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** kept in sync with mApnContexts
1651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Higher numbers are higher priority and sorted so highest priority is first */
1661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final PriorityQueue<ApnContext>mPrioritySortedApnContexts =
1671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new PriorityQueue<ApnContext>(5,
1681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new Comparator<ApnContext>() {
1691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                public int compare(ApnContext c1, ApnContext c2) {
1701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    return c2.priority - c1.priority;
1711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
1721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } );
1731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** allApns holds all apns */
1751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ArrayList<ApnSetting> mAllApnSettings = null;
1761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** preferred apn */
1781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ApnSetting mPreferredApn = null;
1791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Is packet service restricted by network */
1811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsPsRestricted = false;
1821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** emergency apn Setting*/
1841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ApnSetting mEmergencyApn = null;
1851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Once disposed dont handle any messages */
1871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsDisposed = false;
1881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ContentResolver mResolver;
1901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Set to true with CMD_ENABLE_MOBILE_PROVISIONING */
1921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsProvisioning = false;
1931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* The Url passed as object parameter in CMD_ENABLE_MOBILE_PROVISIONING */
1951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private String mProvisioningUrl = null;
1961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Intent for the provisioning apn alarm */
1981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_PROVISIONING_APN_ALARM =
1991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "com.android.internal.telephony.provisioning_apn_alarm";
2001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Tag for tracking stale alarms */
2021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String PROVISIONING_APN_ALARM_TAG_EXTRA = "provisioning.apn.alarm.tag";
2031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Debug property for overriding the PROVISIONING_APN_ALARM_DELAY_IN_MS */
2051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String DEBUG_PROV_APN_ALARM = "persist.debug.prov_apn_alarm";
2061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Default for the provisioning apn alarm timeout */
2081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int PROVISIONING_APN_ALARM_DELAY_IN_MS_DEFAULT = 1000 * 60 * 15;
2091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* The provision apn alarm intent used to disable the provisioning apn */
2111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private PendingIntent mProvisioningApnAlarmIntent = null;
2121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Used to track stale provisioning apn alarms */
2141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mProvisioningApnAlarmTag = (int) SystemClock.elapsedRealtime();
2151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private AsyncChannel mReplyAc = new AsyncChannel();
2171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
218d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen    private final LocalLog mDataRoamingLeakageLog = new LocalLog(50);
219d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen
2201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver () {
2211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
2221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void onReceive(Context context, Intent intent) {
2231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            String action = intent.getAction();
224c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu
2251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (action.equals(Intent.ACTION_SCREEN_ON)) {
226baecdb610b30a5d4b35345f8fc63fcbc2133c149Jack Yu                // TODO: Evaluate hooking this up with DeviceStateMonitor
227c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("screen on");
2281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mIsScreenOn = true;
2291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                stopNetStatPoll();
2301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                startNetStatPoll();
2311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartDataStallAlarm();
2321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
233c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("screen off");
2341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mIsScreenOn = false;
2351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                stopNetStatPoll();
2361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                startNetStatPoll();
2371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartDataStallAlarm();
2381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.startsWith(INTENT_RECONNECT_ALARM)) {
2391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("Reconnect alarm. Previous state was " + mState);
2401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onActionIntentReconnectAlarm(intent);
2411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(INTENT_DATA_STALL_ALARM)) {
242c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("Data stall alarm");
2431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onActionIntentDataStallAlarm(intent);
2441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(INTENT_PROVISIONING_APN_ALARM)) {
245c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("Provisioning apn alarm");
2461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onActionIntentProvisioningApnAlarm(intent);
24721e6af8d6197a071d025733fffeffc157d0085bcfionaxu            } else if (action.equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
24821e6af8d6197a071d025733fffeffc157d0085bcfionaxu                if (mIccRecords.get() != null && mIccRecords.get().getRecordsLoaded()) {
24921e6af8d6197a071d025733fffeffc157d0085bcfionaxu                    setDefaultDataRoamingEnabled();
25021e6af8d6197a071d025733fffeffc157d0085bcfionaxu                }
251c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            } else {
252c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("onReceive: Unknown action=" + action);
2531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
2541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
2551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    };
2561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final Runnable mPollNetStat = new Runnable() {
2581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
2591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void run() {
2601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            updateDataActivity();
2611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mIsScreenOn) {
2631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mNetStatPollPeriod = Settings.Global.getInt(mResolver,
2641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.PDP_WATCHDOG_POLL_INTERVAL_MS, POLL_NETSTAT_MILLIS);
2651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
2661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mNetStatPollPeriod = Settings.Global.getInt(mResolver,
2671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS,
2681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        POLL_NETSTAT_SCREEN_OFF_MILLIS);
2691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
2701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mNetStatPollEnabled) {
2721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mDataConnectionTracker.postDelayed(this, mNetStatPollPeriod);
2731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
2741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
2751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    };
2761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private SubscriptionManager mSubscriptionManager;
2781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final OnSubscriptionsChangedListener mOnSubscriptionsChangedListener =
2791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new OnSubscriptionsChangedListener() {
2801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                public final AtomicInteger mPreviousSubId =
2811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        new AtomicInteger(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
2821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                /**
2841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                 * Callback invoked when there is any change to any SubscriptionInfo. Typically
2851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                 * this method invokes {@link SubscriptionManager#getActiveSubscriptionInfoList}
2861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                 */
2871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                @Override
2881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                public void onSubscriptionsChanged() {
2891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (DBG) log("SubscriptionListener.onSubscriptionInfoChanged");
2901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // Set the network type, in case the radio does not restore it.
2911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    int subId = mPhone.getSubId();
2921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (SubscriptionManager.isValidSubscriptionId(subId)) {
293f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                        registerSettingsObserver();
2941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
2951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mPreviousSubId.getAndSet(subId) != subId &&
2961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            SubscriptionManager.isValidSubscriptionId(subId)) {
2971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onRecordsLoadedOrSubIdChanged();
2981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
2991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
3001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            };
3011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
302f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    private final SettingsObserver mSettingsObserver;
303f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
304f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    private void registerSettingsObserver() {
305f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.unobserve();
306f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        String simSuffix = "";
307f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu        if (TelephonyManager.getDefault().getSimCount() > 1) {
308f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            simSuffix = Integer.toString(mPhone.getSubId());
309f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        }
310f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu
311f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.observe(
312f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                Settings.Global.getUriFor(Settings.Global.DATA_ROAMING + simSuffix),
313d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                DctConstants.EVENT_ROAMING_SETTING_CHANGE);
314f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.observe(
315f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
316f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE);
317f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.observe(
318f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED),
319f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE);
320f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    }
3211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
3231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Maintain the sum of transmit and receive packets.
3241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     *
3251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * The packet counts are initialized and reset to -1 and
3261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * remain -1 until they can be updated.
3271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
3281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public static class TxRxSum {
3291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public long txPkts;
3301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public long rxPkts;
3311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public TxRxSum() {
3331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            reset();
3341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public TxRxSum(long txPkts, long rxPkts) {
3371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.txPkts = txPkts;
3381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.rxPkts = rxPkts;
3391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public TxRxSum(TxRxSum sum) {
3421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            txPkts = sum.txPkts;
3431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            rxPkts = sum.rxPkts;
3441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void reset() {
3471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            txPkts = -1;
3481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            rxPkts = -1;
3491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
3521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public String toString() {
3531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return "{txSum=" + txPkts + " rxSum=" + rxPkts + "}";
3541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void updateTxRxSum() {
3571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.txPkts = TrafficStats.getMobileTcpTxPackets();
3581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.rxPkts = TrafficStats.getMobileTcpRxPackets();
3591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
3611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onActionIntentReconnectAlarm(Intent intent) {
363e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        Message msg = obtainMessage(DctConstants.EVENT_DATA_RECONNECT);
364e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        msg.setData(intent.getExtras());
365e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        sendMessage(msg);
366e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu    }
367e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu
368e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu    private void onDataReconnect(Bundle bundle) {
369e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        String reason = bundle.getString(INTENT_RECONNECT_ALARM_EXTRA_REASON);
370e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        String apnType = bundle.getString(INTENT_RECONNECT_ALARM_EXTRA_TYPE);
3711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int phoneSubId = mPhone.getSubId();
373e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        int currSubId = bundle.getInt(PhoneConstants.SUBSCRIPTION_KEY,
3741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
375e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        log("onDataReconnect: currSubId = " + currSubId + " phoneSubId=" + phoneSubId);
3761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // Stop reconnect if not current subId is not correct.
3781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // FIXME STOPSHIP - phoneSubId is coming up as -1 way after boot and failing this?
3791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (!SubscriptionManager.isValidSubscriptionId(currSubId) || (currSubId != phoneSubId)) {
3801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("receive ReconnectAlarm but subId incorrect, ignore");
3811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return;
3821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnContext apnContext = mApnContexts.get(apnType);
3851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
387e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu            log("onDataReconnect: mState=" + mState + " reason=" + reason + " apnType=" + apnType
388e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                    + " apnContext=" + apnContext + " mDataConnectionAsyncChannels="
389e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                    + mDataConnectionAcHashMap);
3901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if ((apnContext != null) && (apnContext.isEnabled())) {
3931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            apnContext.setReason(reason);
3941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            DctConstants.State apnContextState = apnContext.getState();
3951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
396e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                log("onDataReconnect: apnContext state=" + apnContextState);
3971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
3981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if ((apnContextState == DctConstants.State.FAILED)
3991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    || (apnContextState == DctConstants.State.IDLE)) {
4001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
401e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                    log("onDataReconnect: state is FAILED|IDLE, disassociate");
4021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
4031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DcAsyncChannel dcac = apnContext.getDcAc();
4041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (dcac != null) {
4051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (DBG) {
406e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                        log("onDataReconnect: tearDown apnContext=" + apnContext);
4071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
4081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    dcac.tearDown(apnContext, "", null);
4091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
4101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                apnContext.setDataConnectionAc(null);
4111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                apnContext.setState(DctConstants.State.IDLE);
4121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
413e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                if (DBG) log("onDataReconnect: keep associated");
4141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
4151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // TODO: IF already associated should we send the EVENT_TRY_SETUP_DATA???
4161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            sendMessage(obtainMessage(DctConstants.EVENT_TRY_SETUP_DATA, apnContext));
4171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            apnContext.setReconnectIntent(null);
4191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
4211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onActionIntentDataStallAlarm(Intent intent) {
4231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("onActionIntentDataStallAlarm: action=" + intent.getAction());
4241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_DATA_STALL_ALARM,
4251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                intent.getAction());
4261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = intent.getIntExtra(DATA_STALL_ALARM_TAG_EXTRA, 0);
4271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
4281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
4291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final ConnectivityManager mCm;
431c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
432b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla    /**
433a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * List of messages that are waiting to be posted, when data call disconnect
434a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * is complete
435a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
436a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ArrayList<Message> mDisconnectAllCompleteMsgList = new ArrayList<Message>();
437a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
438a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private RegistrantList mAllDataDisconnectedRegistrants = new RegistrantList();
439a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // member variables
4411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final Phone mPhone;
4421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final UiccController mUiccController;
4431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
4441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DctConstants.Activity mActivity = DctConstants.Activity.NONE;
4451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DctConstants.State mState = DctConstants.State.IDLE;
4461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final Handler mDataConnectionTracker;
4471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private long mTxPkts;
4491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private long mRxPkts;
4501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mNetStatPollPeriod;
4511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mNetStatPollEnabled = false;
4521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private TxRxSum mDataStallTxRxSum = new TxRxSum(0, 0);
4541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Used to track stale data stall alarms.
4551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mDataStallAlarmTag = (int) SystemClock.elapsedRealtime();
4561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // The current data stall alarm intent
4571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private PendingIntent mDataStallAlarmIntent = null;
4581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Number of packets sent since the last received packet
4591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private long mSentSinceLastRecv;
4601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Controls when a simple recovery attempt it to be tried
4611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mNoRecvPollCount = 0;
4620e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    // Reference counter for enabling fail fast
4631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static int sEnableFailFastRefCounter = 0;
4641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // True if data stall detection is enabled
4651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private volatile boolean mDataStallDetectionEnabled = true;
4661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private volatile boolean mFailFast = false;
4681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // True when in voice call
4701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mInVoiceCall = false;
4711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Intent sent when the reconnect alarm fires. */
4731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private PendingIntent mReconnectIntent = null;
4741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // When false we will not auto attach and manually attaching is required.
4761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mAutoAttachOnCreationConfig = false;
4771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private AtomicBoolean mAutoAttachOnCreation = new AtomicBoolean(false);
4781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // State of screen
4801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // (TODO: Reconsider tying directly to screen, maybe this is
4811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    //        really a lower power mode")
4821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsScreenOn = true;
4831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Indicates if we found mvno-specific APNs in the full APN list.
4851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // used to determine if we can accept mno-specific APN for tethering.
4861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mMvnoMatched = false;
4871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Allows the generation of unique Id's for DataConnection objects */
4891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private AtomicInteger mUniqueIdGenerator = new AtomicInteger(0);
4901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** The data connections. */
4921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private HashMap<Integer, DataConnection> mDataConnections =
4931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new HashMap<Integer, DataConnection>();
4941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** The data connection async channels */
4961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private HashMap<Integer, DcAsyncChannel> mDataConnectionAcHashMap =
4971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new HashMap<Integer, DcAsyncChannel>();
4981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Convert an ApnType string to Id (TODO: Use "enumeration" instead of String for ApnType) */
5001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private HashMap<String, Integer> mApnToDataConnectionId = new HashMap<String, Integer>();
5011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Phone.APN_TYPE_* ===> ApnContext */
5031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final ConcurrentHashMap<String, ApnContext> mApnContexts =
5041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new ConcurrentHashMap<String, ApnContext>();
5051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
506af5593594070f825032be46dced573cd195956e1Robert Greenwalt    private final SparseArray<ApnContext> mApnContextsById = new SparseArray<ApnContext>();
507af5593594070f825032be46dced573cd195956e1Robert Greenwalt
5081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mDisconnectPendingCount = 0;
509a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
5104c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu    /** Indicate if metered APNs are disabled.
5114c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu     *  set to block all the metered APNs from continuously sending requests, which causes
5124c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu     *  undesired network load */
5134c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu    private boolean mMeteredApnDisabled = false;
51468f4f4a0bc8d4060b5775e7a24a97ea5b485989efionaxu
515a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
5164b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * int to remember whether has setDataProfiles and with roaming or not.
5174b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * 0: default, has never set data profile
5184b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * 1: has set data profile with home protocol
5194b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * 2: has set data profile with roaming protocol
5204b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * This is not needed once RIL command is updated to support both home and roaming protocol.
5214b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     */
5224b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu    private int mSetDataProfileStatus = 0;
5234b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu
5244b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu    /**
525cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Handles changes to the APN db.
526b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla     */
527cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private class ApnChangeObserver extends ContentObserver {
528cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public ApnChangeObserver () {
529cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            super(mDataConnectionTracker);
530cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
531c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
532cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
533cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public void onChange(boolean selfChange) {
534cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            sendMessage(obtainMessage(DctConstants.EVENT_APN_CHANGED));
535cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
536cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
537c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
538cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Instance Variables
539c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
540cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean mReregisterOnReconnectFailure = false;
541c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
542c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
543cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Constants
544c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
545ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    // Used by puppetmaster/*/radio_stress.py
546ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private static final String PUPPET_MASTER_RADIO_STRESS_TEST = "gsm.defaultpdpcontext.active";
547c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
548ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private static final int POLL_PDP_MILLIS = 5 * 1000;
549c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
5502b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen    private static final int PROVISIONING_SPINNER_TIMEOUT_MILLIS = 120 * 1000;
5512b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen
5526bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville    static final Uri PREFERAPN_NO_UPDATE_URI_USING_SUBID =
5536bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville                        Uri.parse("content://telephony/carriers/preferapn_no_update/subId/");
554cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final String APN_ID = "apn_id";
555cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
556ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private boolean mCanSetPreferApn = false;
557c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
558187a39f896f88eb6c5e4306d9595546654825976Wink Saville    private AtomicBoolean mAttached = new AtomicBoolean(false);
559187a39f896f88eb6c5e4306d9595546654825976Wink Saville
560cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** Watches for changes to the APN db. */
561cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ApnChangeObserver mApnObserver;
562cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
563b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private final String mProvisionActionName;
564b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private BroadcastReceiver mProvisionBroadcastReceiver;
5652b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen    private ProgressDialog mProvisioningSpinner;
566b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
56771f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu    private final DataServiceManager mDataServiceManager;
56871f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu
56971f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu    private final int mTransportType;
570a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
571cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Constructor
57271f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu    public DcTracker(Phone phone, int transportType) {
5731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        super();
5741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone = phone;
5751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("DCT.constructor");
57671f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        mTransportType = transportType;
57771f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        mDataServiceManager = new DataServiceManager(phone, transportType);
5781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mResolver = mPhone.getContext().getContentResolver();
5801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mUiccController = UiccController.getInstance();
5811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mUiccController.registerForIccChanged(this, DctConstants.EVENT_ICC_CHANGED, null);
5821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mAlarmManager =
5831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
5841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mCm = (ConnectivityManager) mPhone.getContext().getSystemService(
5851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Context.CONNECTIVITY_SERVICE);
5861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        IntentFilter filter = new IntentFilter();
5891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(Intent.ACTION_SCREEN_ON);
5901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(Intent.ACTION_SCREEN_OFF);
5911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(INTENT_DATA_STALL_ALARM);
5921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(INTENT_PROVISIONING_APN_ALARM);
59321e6af8d6197a071d025733fffeffc157d0085bcfionaxu        filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
594985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen
595985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen        mDataEnabledSettings = new DataEnabledSettings(phone);
5961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
5981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
6001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mAutoAttachOnCreation.set(sp.getBoolean(Phone.DATA_DISABLED_ON_BOOT_KEY, false));
6011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mSubscriptionManager = SubscriptionManager.from(mPhone.getContext());
6031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
6041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        HandlerThread dcHandlerThread = new HandlerThread("DcHandlerThread");
6061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        dcHandlerThread.start();
6071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Handler dcHandler = new Handler(dcHandlerThread.getLooper());
60871f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        mDcc = DcController.makeDcc(mPhone, this, mDataServiceManager, dcHandler);
6091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcTesterFailBringUpAll = new DcTesterFailBringUpAll(mPhone, dcHandler);
610cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
611cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mDataConnectionTracker = this;
612c374098c17a81f73f51e9d7df99eba574882949bYifan Bai        registerForAllEvents();
613a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        update();
614cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mApnObserver = new ApnChangeObserver();
6151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        phone.getContext().getContentResolver().registerContentObserver(
616cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                Telephony.Carriers.CONTENT_URI, true, mApnObserver);
617cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
618d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        initApnContexts();
619d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
620d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        for (ApnContext apnContext : mApnContexts.values()) {
621d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            // Register the reconnect and restart actions.
6221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            filter = new IntentFilter();
623d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            filter.addAction(INTENT_RECONNECT_ALARM + '.' + apnContext.getApnType());
624d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
625d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        }
626d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
62776f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Add Emergency APN to APN setting list by default to support EPDN in sim absent cases
62876f43316a5a6082d601bffd4b6898d0bd81e11fcram        initEmergencyApnSetting();
62976f43316a5a6082d601bffd4b6898d0bd81e11fcram        addEmergencyApnSetting();
630b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
6311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisionActionName = "com.android.internal.telephony.PROVISION" + phone.getPhoneId();
632f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
633f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver = new SettingsObserver(mPhone.getContext(), this);
634f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        registerSettingsObserver();
6351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
6361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
637af5593594070f825032be46dced573cd195956e1Robert Greenwalt    @VisibleForTesting
638af5593594070f825032be46dced573cd195956e1Robert Greenwalt    public DcTracker() {
639af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mAlarmManager = null;
640af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mCm = null;
641af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mPhone = null;
642af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mUiccController = null;
643af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mDataConnectionTracker = null;
644af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mProvisionActionName = null;
645f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver = new SettingsObserver(null, this);
646985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen        mDataEnabledSettings = null;
64771f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        mTransportType = 0;
64871f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        mDataServiceManager = null;
649af5593594070f825032be46dced573cd195956e1Robert Greenwalt    }
650af5593594070f825032be46dced573cd195956e1Robert Greenwalt
6511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void registerServiceStateTrackerEvents() {
6521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataConnectionAttached(this,
6531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null);
6541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataConnectionDetached(this,
6551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_DATA_CONNECTION_DETACHED, null);
6561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataRoamingOn(this,
6571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_ROAMING_ON, null);
6581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataRoamingOff(this,
6590d6ff7958dac61b9e2d689267c34ddfa0c666d9dfionaxu                DctConstants.EVENT_ROAMING_OFF, null, true);
6601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForPsRestrictedEnabled(this,
6611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_PS_RESTRICT_ENABLED, null);
6621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForPsRestrictedDisabled(this,
6631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_PS_RESTRICT_DISABLED, null);
6641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(this,
6651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_DATA_RAT_CHANGED, null);
666cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
667c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
6681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void unregisterServiceStateTrackerEvents() {
6691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataConnectionAttached(this);
6701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataConnectionDetached(this);
6711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataRoamingOn(this);
6721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataRoamingOff(this);
6731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForPsRestrictedEnabled(this);
6741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForPsRestrictedDisabled(this);
6751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged(this);
6761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
6771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void registerForAllEvents() {
67971f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        if (mTransportType == TransportType.WWAN) {
68071f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu            mPhone.mCi.registerForAvailable(this, DctConstants.EVENT_RADIO_AVAILABLE, null);
68171f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu            mPhone.mCi.registerForOffOrNotAvailable(this,
68271f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
68371f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu            mPhone.mCi.registerForPcoData(this, DctConstants.EVENT_PCO_DATA_RECEIVED, null);
68471f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        }
68571f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu
6860710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // Note, this is fragile - the Phone is now presenting a merged picture
6870710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // of PS (volte) & CS and by diving into its internals you're just seeing
6880710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // the CS data.  This works well for the purposes this is currently used for
6890710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // but that may not always be the case.  Should probably be redesigned to
6900710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // accurately reflect what we're really interested in (registerForCSVoiceCallEnded).
6911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getCallTracker().registerForVoiceCallEnded(this,
6921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_VOICE_CALL_ENDED, null);
6931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getCallTracker().registerForVoiceCallStarted(this,
6941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_VOICE_CALL_STARTED, null);
6951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        registerServiceStateTrackerEvents();
6962e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        mPhone.mCi.registerForPcoData(this, DctConstants.EVENT_PCO_DATA_RECEIVED, null);
6976a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu        mPhone.getCarrierActionAgent().registerForCarrierAction(
6986a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu                CarrierActionAgent.CARRIER_ACTION_SET_METERED_APNS_ENABLED, this,
6996a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu                DctConstants.EVENT_SET_CARRIER_DATA_ENABLED, null, false);
70071f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        mDataServiceManager.registerForServiceBindingChanged(this,
70171f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                DctConstants.EVENT_DATA_SERVICE_BINDING_CHANGED, null);
702a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
7031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
704cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void dispose() {
7051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("DCT.dispose");
7064dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt
707b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        if (mProvisionBroadcastReceiver != null) {
708b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            mPhone.getContext().unregisterReceiver(mProvisionBroadcastReceiver);
709b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            mProvisionBroadcastReceiver = null;
710b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
7112b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        if (mProvisioningSpinner != null) {
7122b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.dismiss();
7132b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner = null;
7142b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        }
715b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
716cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, null);
717cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
7181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
7191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            dcac.disconnect();
7201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
7211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDataConnectionAcHashMap.clear();
7221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mIsDisposed = true;
7231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getContext().unregisterReceiver(mIntentReceiver);
7241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mUiccController.unregisterForIccChanged(this);
725f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.unobserve();
726f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
7271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mSubscriptionManager
7281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                .removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
7291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcc.dispose();
7301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcTesterFailBringUpAll.dispose();
731cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
732a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getContext().getContentResolver().unregisterContentObserver(mApnObserver);
733a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mApnContexts.clear();
734af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mApnContextsById.clear();
735a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPrioritySortedApnContexts.clear();
736c374098c17a81f73f51e9d7df99eba574882949bYifan Bai        unregisterForAllEvents();
737a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
738a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        destroyDataConnections();
739a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
7401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void unregisterForAllEvents() {
742a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         //Unregister for all events
74371f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        if (mTransportType == TransportType.WWAN) {
74471f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu            mPhone.mCi.unregisterForAvailable(this);
74571f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu            mPhone.mCi.unregisterForOffOrNotAvailable(this);
74671f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu            mPhone.mCi.unregisterForPcoData(this);
74771f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        }
74871f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu
749cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
750a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (r != null) {
751a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            r.unregisterForRecordsLoaded(this);
752a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mIccRecords.set(null);
753a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
754cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getCallTracker().unregisterForVoiceCallEnded(this);
755cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getCallTracker().unregisterForVoiceCallStarted(this);
7561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        unregisterServiceStateTrackerEvents();
7572e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        mPhone.mCi.unregisterForPcoData(this);
7586a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu        mPhone.getCarrierActionAgent().unregisterForCarrierAction(this,
7596a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu                CarrierActionAgent.CARRIER_ACTION_SET_METERED_APNS_ENABLED);
76071f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        mDataServiceManager.unregisterForServiceBindingChanged(this);
7611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
7621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
7641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Modify {@link android.provider.Settings.Global#MOBILE_DATA} value.
7651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
766a64092befe003884c4c8951438ab311ce8f92824Malcolm Chen    public void setUserDataEnabled(boolean enable) {
7671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.CMD_SET_USER_DATA_ENABLE);
7681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = enable ? 1 : 0;
7691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("setDataEnabled: sendMessage: enable=" + enable);
7701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
7711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
7721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetUserDataEnabled(boolean enabled) {
774a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        synchronized (mDataEnabledSettings) {
775a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            if (mDataEnabledSettings.isUserDataEnabled() != enabled) {
776a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                mDataEnabledSettings.setUserDataEnabled(enabled);
7775b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu                if (!getDataRoamingEnabled() && mPhone.getServiceState().getDataRoaming()) {
7781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (enabled) {
7791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
7801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
7811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        notifyOffApnsOfAvailability(Phone.REASON_DATA_DISABLED);
7821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
7831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
7841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
785fcd5efef57e734966ed373ab7a4ce419d0034ceczxuan                mPhone.notifyUserMobileDataStateChanged(enabled);
786fcd5efef57e734966ed373ab7a4ce419d0034ceczxuan
787a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                // TODO: We should register for DataEnabledSetting's data enabled/disabled event and
788a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                // handle the rest from there.
7891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (enabled) {
790120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    reevaluateDataConnections();
7911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onTrySetupData(Phone.REASON_DATA_ENABLED);
7921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
7931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);
7941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
7951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
7961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
7971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
7981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7995292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt    /**
800120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * Reevaluate existing data connections when conditions change.
801120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     *
802120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * For example, handle reverting restricted networks back to unrestricted. If we're changing
803120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * user data to enabled and this makes data truly enabled (not disabled by other factors) we
804120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * need to tear down any metered apn type that was enabled anyway by a privileged request.
805120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * This allows us to reconnect to it in an unrestricted way.
806120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     *
807120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * Or when we brought up a unmetered data connection while data is off, we only limit this
808120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * data connection for unmetered use only. When data is turned back on, we need to tear that
809120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * down so a full capable data connection can be re-established.
8105292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt     */
811120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu    private void reevaluateDataConnections() {
812120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        if (mDataEnabledSettings.isDataEnabled()) {
8135292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt            for (ApnContext apnContext : mApnContexts.values()) {
814120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                if (apnContext.isConnectedOrConnecting()) {
815120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    final DcAsyncChannel dcac = apnContext.getDcAc();
816120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    if (dcac != null) {
817120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                        final NetworkCapabilities netCaps = dcac.getNetworkCapabilitiesSync();
818120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                        if (netCaps != null && !netCaps.hasCapability(NetworkCapabilities
819ee00c053e0cbbbdb22737c923b1a214e10453646Jack Yu                                .NET_CAPABILITY_NOT_RESTRICTED) && !netCaps.hasCapability(
820ee00c053e0cbbbdb22737c923b1a214e10453646Jack Yu                                NetworkCapabilities.NET_CAPABILITY_NOT_METERED)) {
821120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            if (DBG) {
822ee00c053e0cbbbdb22737c923b1a214e10453646Jack Yu                                log("Tearing down restricted metered net:" + apnContext);
823120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            }
824ee00c053e0cbbbdb22737c923b1a214e10453646Jack Yu                            // Tearing down the restricted metered data call when
825120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // conditions change. This will allow reestablishing a new unrestricted
826120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // data connection.
827120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            apnContext.setReason(Phone.REASON_DATA_ENABLED);
828120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            cleanUpConnection(true, apnContext);
82950734be549285702de00295778b8c2a4360215a0Jack Yu                        } else if (apnContext.getApnSetting().isMetered(mPhone)
830120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                                && (netCaps != null && netCaps.hasCapability(
831120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                                        NetworkCapabilities.NET_CAPABILITY_NOT_METERED))) {
832120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            if (DBG) {
833120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                                log("Tearing down unmetered net:" + apnContext);
834120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            }
835120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // The APN settings is metered, but the data was still marked as
836120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // unmetered data, must be the unmetered data connection brought up when
837120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // data is off. We need to tear that down when data is enabled again.
838120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // This will allow reestablishing a new full capability data connection.
839120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            apnContext.setReason(Phone.REASON_DATA_ENABLED);
840120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            cleanUpConnection(true, apnContext);
84176c5a9479d312139740dcaf7644172f2beb2f7e0Robert Greenwalt                        }
84276c5a9479d312139740dcaf7644172f2beb2f7e0Robert Greenwalt                    }
8435292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt                }
8445292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt            }
8455292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt        }
8465292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt    }
8475292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt
848f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    private void onDeviceProvisionedChange() {
849985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen        if (isDataEnabled()) {
850120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu            reevaluateDataConnections();
851f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            onTrySetupData(Phone.REASON_DATA_ENABLED);
852f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        } else {
853f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);
854f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        }
855f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    }
8561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public long getSubId() {
8591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mPhone.getSubId();
8601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
8611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public DctConstants.Activity getActivity() {
8631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mActivity;
8641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
8651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void setActivity(DctConstants.Activity activity) {
8671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("setActivity = " + activity);
8681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mActivity = activity;
8691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.notifyDataActivity();
8701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
8711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
872af5593594070f825032be46dced573cd195956e1Robert Greenwalt    public void requestNetwork(NetworkRequest networkRequest, LocalLog log) {
873af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final int apnId = ApnContext.apnIdForNetworkRequest(networkRequest);
874af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final ApnContext apnContext = mApnContextsById.get(apnId);
875af5593594070f825032be46dced573cd195956e1Robert Greenwalt        log.log("DcTracker.requestNetwork for " + networkRequest + " found " + apnContext);
876692640f429efa8e292c6261472b2c682e1079f8eRobert Greenwalt        if (apnContext != null) apnContext.requestNetwork(networkRequest, log);
877af5593594070f825032be46dced573cd195956e1Robert Greenwalt    }
878af5593594070f825032be46dced573cd195956e1Robert Greenwalt
879af5593594070f825032be46dced573cd195956e1Robert Greenwalt    public void releaseNetwork(NetworkRequest networkRequest, LocalLog log) {
880af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final int apnId = ApnContext.apnIdForNetworkRequest(networkRequest);
881af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final ApnContext apnContext = mApnContextsById.get(apnId);
882af5593594070f825032be46dced573cd195956e1Robert Greenwalt        log.log("DcTracker.releaseNetwork for " + networkRequest + " found " + apnContext);
883692640f429efa8e292c6261472b2c682e1079f8eRobert Greenwalt        if (apnContext != null) apnContext.releaseNetwork(networkRequest, log);
884af5593594070f825032be46dced573cd195956e1Robert Greenwalt    }
885af5593594070f825032be46dced573cd195956e1Robert Greenwalt
886bda761320929f714951c328bfec6a51a1978db97Wink Saville    public boolean isApnSupported(String name) {
88791bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal        if (name == null) {
88891bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal            loge("isApnSupported: name=null");
88991bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal            return false;
89091bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal        }
891bda761320929f714951c328bfec6a51a1978db97Wink Saville        ApnContext apnContext = mApnContexts.get(name);
892bda761320929f714951c328bfec6a51a1978db97Wink Saville        if (apnContext == null) {
893bda761320929f714951c328bfec6a51a1978db97Wink Saville            loge("Request for unsupported mobile name: " + name);
894bda761320929f714951c328bfec6a51a1978db97Wink Saville            return false;
895071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
896bda761320929f714951c328bfec6a51a1978db97Wink Saville        return true;
897bda761320929f714951c328bfec6a51a1978db97Wink Saville    }
898071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
899bda761320929f714951c328bfec6a51a1978db97Wink Saville    public int getApnPriority(String name) {
900071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        ApnContext apnContext = mApnContexts.get(name);
901071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (apnContext == null) {
902bda761320929f714951c328bfec6a51a1978db97Wink Saville            loge("Request for unsupported mobile name: " + name);
903071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
904bda761320929f714951c328bfec6a51a1978db97Wink Saville        return apnContext.priority;
905071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt    }
906071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
907b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    // Turn telephony radio on or off.
908b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private void setRadio(boolean on) {
909b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        final ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
910b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        try {
911b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            phone.setRadio(on);
912b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        } catch (Exception e) {
913b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            // Ignore.
914b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
915b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    }
916b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
917b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    // Class to handle Intent dispatched with user selects the "Sign-in to network"
918b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    // notification.
919b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private class ProvisionNotificationBroadcastReceiver extends BroadcastReceiver {
9202b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        private final String mNetworkOperator;
921b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        // Mobile provisioning URL.  Valid while provisioning notification is up.
922b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        // Set prior to notification being posted as URL contains ICCID which
923b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        // disappears when radio is off (which is the case when notification is up).
924b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        private final String mProvisionUrl;
925b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
9262b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        public ProvisionNotificationBroadcastReceiver(String provisionUrl, String networkOperator) {
9272b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mNetworkOperator = networkOperator;
928b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            mProvisionUrl = provisionUrl;
929b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
930b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
931b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        private void setEnableFailFastMobileData(int enabled) {
9326395443719ec3ee0257085945e753d02f603886bRobert Greenwalt            sendMessage(obtainMessage(DctConstants.CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA, enabled, 0));
933b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
934b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
935b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        private void enableMobileProvisioning() {
936b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            final Message msg = obtainMessage(DctConstants.CMD_ENABLE_MOBILE_PROVISIONING);
937b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            msg.setData(Bundle.forPair(DctConstants.PROVISIONING_URL_KEY, mProvisionUrl));
938b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            sendMessage(msg);
939b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
940b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
941b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        @Override
942b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        public void onReceive(Context context, Intent intent) {
9432b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // Turning back on the radio can take time on the order of a minute, so show user a
9442b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // spinner so they know something is going on.
945636fbb01fd32e23d1e9ef86497115b2c992b03daSanket Padawe            log("onReceive : ProvisionNotificationBroadcastReceiver");
9462b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner = new ProgressDialog(context);
9472b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setTitle(mNetworkOperator);
9482b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setMessage(
9492b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    // TODO: Don't borrow "Connecting..." i18n string; give Telephony a version.
9502b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    context.getText(com.android.internal.R.string.media_route_status_connecting));
9512b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setIndeterminate(true);
9522b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setCancelable(true);
9532b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // Allow non-Activity Service Context to create a View.
9542b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.getWindow().setType(
9552b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
9562b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.show();
9572b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // After timeout, hide spinner so user can at least use their device.
9582b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // TODO: Indicate to user that it is taking an unusually long time to connect?
9592b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            sendMessageDelayed(obtainMessage(DctConstants.CMD_CLEAR_PROVISIONING_SPINNER,
9602b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner), PROVISIONING_SPINNER_TIMEOUT_MILLIS);
961b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            // This code is almost identical to the old
962b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            // ConnectivityService.handleMobileProvisioningAction code.
963b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            setRadio(true);
964b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            setEnableFailFastMobileData(DctConstants.ENABLED);
965b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            enableMobileProvisioning();
966b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
967b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    }
968b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
969cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
970cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void finalize() {
9717e9240253edb59e0aa657de434faa1ccdf17a742Amit Mahajan        if(DBG && mPhone != null) log("finalize");
972cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
973cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
9744a9b3afeb2ec4d573eca335a3706392ecf9f281eWink Saville    private ApnContext addApnContext(String type, NetworkConfig networkConfig) {
9750e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        ApnContext apnContext = new ApnContext(mPhone, type, LOG_TAG, networkConfig, this);
976cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mApnContexts.put(type, apnContext);
977af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mApnContextsById.put(ApnContext.apnIdForApnName(type), apnContext);
9783fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        mPrioritySortedApnContexts.add(apnContext);
979bce3d2575122929bb27ec8a37d56e96da39a3ca2Robert Greenwalt        return apnContext;
980cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
981c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
9821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void initApnContexts() {
983d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        log("initApnContexts: E");
984d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        // Load device network attributes from resources
985d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        String[] networkConfigStrings = mPhone.getContext().getResources().getStringArray(
986d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                com.android.internal.R.array.networkAttributes);
987d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        for (String networkConfigString : networkConfigStrings) {
988d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            NetworkConfig networkConfig = new NetworkConfig(networkConfigString);
989d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            ApnContext apnContext = null;
990d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
991d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            switch (networkConfig.type) {
992d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE:
993d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_DEFAULT, networkConfig);
994d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
995d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_MMS:
996d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_MMS, networkConfig);
997d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
998d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_SUPL:
999d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_SUPL, networkConfig);
1000d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1001d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_DUN:
1002d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_DUN, networkConfig);
1003d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1004d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_HIPRI:
1005d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_HIPRI, networkConfig);
1006d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1007d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_FOTA:
1008d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_FOTA, networkConfig);
1009d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1010d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_IMS:
1011d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_IMS, networkConfig);
1012d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1013d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_CBS:
1014d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_CBS, networkConfig);
1015d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1016d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_IA:
1017d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_IA, networkConfig);
1018d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1019cf5205f70eb1eac497164124187a088ecb03fff5Ram            case ConnectivityManager.TYPE_MOBILE_EMERGENCY:
1020cf5205f70eb1eac497164124187a088ecb03fff5Ram                apnContext = addApnContext(PhoneConstants.APN_TYPE_EMERGENCY, networkConfig);
1021cf5205f70eb1eac497164124187a088ecb03fff5Ram                break;
1022d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            default:
1023d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                log("initApnContexts: skipping unknown type=" + networkConfig.type);
1024d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                continue;
1025d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            }
1026d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            log("initApnContexts: apnContext=" + apnContext);
1027d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        }
1028092e6bd60f1a4a3a55fb73ad0efca1122b8e15e2Jack Yu
1029092e6bd60f1a4a3a55fb73ad0efca1122b8e15e2Jack Yu        if (VDBG) log("initApnContexts: X mApnContexts=" + mApnContexts);
1030d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt    }
1031d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
1032cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public LinkProperties getLinkProperties(String apnType) {
1033cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1034cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
1035454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = apnContext.getDcAc();
1036cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac != null) {
1037cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("return link properites for " + apnType);
1038cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return dcac.getLinkPropertiesSync();
1039cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1040cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1041cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("return new LinkProperties");
1042cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return new LinkProperties();
1043cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1044cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1045608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt    public NetworkCapabilities getNetworkCapabilities(String apnType) {
1046608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        ApnContext apnContext = mApnContexts.get(apnType);
1047608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        if (apnContext!=null) {
1048608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            DcAsyncChannel dataConnectionAc = apnContext.getDcAc();
1049608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            if (dataConnectionAc != null) {
1050608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                if (DBG) {
1051608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                    log("get active pdp is not null, return NetworkCapabilities for " + apnType);
1052608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                }
1053608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                return dataConnectionAc.getNetworkCapabilitiesSync();
1054608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            }
1055608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        }
1056608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        if (DBG) log("return new NetworkCapabilities");
1057608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        return new NetworkCapabilities();
1058608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt    }
1059cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1060cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return all active apn types
1061cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public String[] getActiveApnTypes() {
1062cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("get all active apn types");
1063cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ArrayList<String> result = new ArrayList<String>();
1064cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1065cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1066187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (mAttached.get() && apnContext.isReady()) {
1067cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                result.add(apnContext.getApnType());
1068cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
1069cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1070c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1071cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result.toArray(new String[0]);
1072cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1073cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1074cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return active apn of specific apn type
1075cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public String getActiveApnString(String apnType) {
1076ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (VDBG) log( "get active apn string for type:" + apnType);
1077cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1078cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
1079cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ApnSetting apnSetting = apnContext.getApnSetting();
1080cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnSetting != null) {
1081cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return apnSetting.apn;
1082cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1083cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1084cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
1085cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1086cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1087cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return state of specific apn type
1088cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public DctConstants.State getState(String apnType) {
1089cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1090cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
1091cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return apnContext.getState();
1092c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1093cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return DctConstants.State.FAILED;
1094cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1095c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1096c9b81a0c05128694c617fcdd67e73821895822feWink Saville    // Return if apn type is a provisioning apn.
10971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean isProvisioningApn(String apnType) {
1098c9b81a0c05128694c617fcdd67e73821895822feWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1099c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (apnContext != null) {
1100c9b81a0c05128694c617fcdd67e73821895822feWink Saville            return apnContext.isProvisioningApn();
1101c9b81a0c05128694c617fcdd67e73821895822feWink Saville        }
1102c9b81a0c05128694c617fcdd67e73821895822feWink Saville        return false;
1103c9b81a0c05128694c617fcdd67e73821895822feWink Saville    }
1104c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1105cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return state of overall
1106cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public DctConstants.State getOverallState() {
1107cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isConnecting = false;
1108cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isFailed = true; // All enabled Apns should be FAILED.
1109cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isAnyEnabled = false;
1110cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1111cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1112cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.isEnabled()) {
1113cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                isAnyEnabled = true;
1114cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                switch (apnContext.getState()) {
1115cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case CONNECTED:
1116cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case DISCONNECTING:
11171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (VDBG) log("overall state is CONNECTED");
1118cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return DctConstants.State.CONNECTED;
1119ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                case RETRYING:
1120cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case CONNECTING:
1121cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isConnecting = true;
1122cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isFailed = false;
1123cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
1124cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case IDLE:
1125cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case SCANNING:
1126cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isFailed = false;
1127cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
1128cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                default:
1129cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isAnyEnabled = true;
1130cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
1131cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1132cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1133c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1134c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1135cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (!isAnyEnabled) { // Nothing enabled. return IDLE.
11361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is IDLE");
1137cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.IDLE;
1138c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1139c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1140cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnecting) {
11411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is CONNECTING");
1142cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.CONNECTING;
1143cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (!isFailed) {
11441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is IDLE");
1145cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.IDLE;
1146cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
11471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is FAILED");
1148cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.FAILED;
1149c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1150c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1151c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1152a64092befe003884c4c8951438ab311ce8f92824Malcolm Chen    /**
1153a64092befe003884c4c8951438ab311ce8f92824Malcolm Chen     * Whether data is enabled. This does not only check isUserDataEnabled(), but also
1154a64092befe003884c4c8951438ab311ce8f92824Malcolm Chen     * others like CarrierDataEnabled and internalDataEnabled.
1155a64092befe003884c4c8951438ab311ce8f92824Malcolm Chen     */
11560b03bcd1eccc833d5cac5ecf937cf0e037375561Jack Yu    @VisibleForTesting
1157120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu    public boolean isDataEnabled() {
1158120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        return mDataEnabledSettings.isDataEnabled();
1159a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1160a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1161cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //****** Called from ServiceStateTracker
1162c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1163cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Invoked when ServiceStateTracker observes a transition from GPRS
1164cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * attach to detach.
1165c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
11661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataConnectionDetached() {
1167cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        /*
1168cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * We presently believe it is unnecessary to tear down the PDP context
1169cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * when GPRS detaches, but we should stop the network polling.
1170cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         */
1171cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log ("onDataConnectionDetached: stop polling and notify detached");
1172cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopNetStatPoll();
1173cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopDataStallAlarm();
1174cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyDataConnection(Phone.REASON_DATA_DETACHED);
1175187a39f896f88eb6c5e4306d9595546654825976Wink Saville        mAttached.set(false);
1176cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1177c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1178cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onDataConnectionAttached() {
1179cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onDataConnectionAttached");
11807ab10e4710bdb54c6d9a5ee01cd443a42a2689f5Sungmin Choi        mAttached.set(true);
1181cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getOverallState() == DctConstants.State.CONNECTED) {
1182cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onDataConnectionAttached: start polling notify attached");
1183cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            startNetStatPoll();
1184cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
1185cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_DATA_ATTACHED);
1186cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1187cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // update APN availability so that APN can be enabled.
1188cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_DATA_ATTACHED);
1189cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
119012fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        if (mAutoAttachOnCreationConfig) {
1191aacc11b299ac047e73e1e712aa396ea0a6a80158Robert Greenwalt            mAutoAttachOnCreation.set(true);
119212fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        }
1193ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(Phone.REASON_DATA_ATTACHED);
1194cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1195c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
119699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu    /**
119799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * Check if it is allowed to make a data connection (without checking APN context specific
119899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * conditions).
119999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *
120099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @param dataConnectionReasons Data connection allowed or disallowed reasons as the output
120199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *                              param. It's okay to pass null here and no reasons will be
120299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *                              provided.
120399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @return True if data connection is allowed, otherwise false.
120499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     */
120599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu    public boolean isDataAllowed(DataConnectionReasons dataConnectionReasons) {
120699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        return isDataAllowed(null, dataConnectionReasons);
120799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu    }
120899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
120999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu    /**
121099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * Check if it is allowed to make a data connection for a given APN type.
121199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *
121299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @param apnContext APN context. If passing null, then will only check general but not APN
121399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *                   specific conditions (e.g. APN state, metered/unmetered APN).
121499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @param dataConnectionReasons Data connection allowed or disallowed reasons as the output
121599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *                              param. It's okay to pass null here and no reasons will be
121699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *                              provided.
121799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @return True if data connection is allowed, otherwise false.
121899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     */
121999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu    boolean isDataAllowed(ApnContext apnContext, DataConnectionReasons dataConnectionReasons) {
122099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 1: Get all environment conditions.
122199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 2: Special handling for emergency APN.
122299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 3. Build disallowed reasons.
122399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 4: Determine if data should be allowed in some special conditions.
122499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
122599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        DataConnectionReasons reasons = new DataConnectionReasons();
1226cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
122799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 1: Get all environment conditions.
122899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        final boolean internalDataEnabled = mDataEnabledSettings.isInternalDataEnabled();
12299894b3fb2f35e21d9cfd45f233ed093589e14c26sy.yun        boolean attachedState = mAttached.get();
1230cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
12310d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu        boolean radioStateFromCarrier = mPhone.getServiceStateTracker().getPowerStateFromCarrier();
123299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // TODO: Remove this hack added by ag/641832.
12330e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
12340e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        if (radioTech == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN) {
12350e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            desiredPowerState = true;
12360d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu            radioStateFromCarrier = true;
12370e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        }
12380e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh
123999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        boolean recordsLoaded = mIccRecords.get() != null && mIccRecords.get().getRecordsLoaded();
124099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
124199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        boolean defaultDataSelected = SubscriptionManager.isValidSubscriptionId(
124299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                SubscriptionManager.getDefaultDataSubscriptionId());
1243cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
124499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        boolean isMeteredApnType = apnContext == null
124550734be549285702de00295778b8c2a4360215a0Jack Yu                || ApnSetting.isMeteredApnType(apnContext.getApnType(), mPhone);
12463d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
124799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        PhoneConstants.State phoneState = PhoneConstants.State.IDLE;
12480710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // Note this is explicitly not using mPhone.getState.  See b/19090488.
12490710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // mPhone.getState reports the merge of CS and PS (volte) voice call state
12500710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // but we only care about CS calls here for data/voice concurrency issues.
12510710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // Calling getCallTracker currently gives you just the CS side where the
12520710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // ImsCallTracker is held internally where applicable.
12530710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // This should be redesigned to ask explicitly what we want:
12540710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // voiceCallStateAllowDataCall, or dataCallAllowed or something similar.
1255b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com        if (mPhone.getCallTracker() != null) {
125699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            phoneState = mPhone.getCallTracker().getState();
125799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
125899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
125999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 2: Special handling for emergency APN.
126099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (apnContext != null
126199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                && apnContext.getApnType().equals(PhoneConstants.APN_TYPE_EMERGENCY)
126299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                && apnContext.isConnectable()) {
126399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            // If this is an emergency APN, as long as the APN is connectable, we
126499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            // should allow it.
126599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            if (dataConnectionReasons != null) {
126699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                dataConnectionReasons.add(DataAllowedReasonType.EMERGENCY_APN);
126799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            }
126899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            // Bail out without further checks.
126999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            return true;
127099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
127199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
127299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 3. Build disallowed reasons.
127399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (apnContext != null && !apnContext.isConnectable()) {
127499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.APN_NOT_CONNECTABLE);
127599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
127699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
127799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // If RAT is IWLAN then don't allow default/IA PDP at all.
127899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Rest of APN types can be evaluated for remaining conditions.
127999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if ((apnContext != null && (apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
128099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                || apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IA)))
128199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                && (radioTech == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN)) {
128299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.ON_IWLAN);
128399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
128499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
128599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (isEmergency()) {
128699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.IN_ECBM);
1287b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com        }
12881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
12893d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!(attachedState || mAutoAttachOnCreation.get())) {
129099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.NOT_ATTACHED);
12913d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
12923d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!recordsLoaded) {
129399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.RECORD_NOT_LOADED);
12943d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
129599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (phoneState != PhoneConstants.State.IDLE
129699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                && !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
129799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.INVALID_PHONE_STATE);
129899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.CONCURRENT_VOICE_DATA_NOT_ALLOWED);
12993d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13003d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!internalDataEnabled) {
130199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.INTERNAL_DATA_DISABLED);
13023d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13033d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!defaultDataSelected) {
130499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.DEFAULT_DATA_UNSELECTED);
13053d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13065b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (mPhone.getServiceState().getDataRoaming() && !getDataRoamingEnabled()) {
130799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.ROAMING_DISABLED);
1308c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
13093d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (mIsPsRestricted) {
131099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.PS_RESTRICTED);
13113d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13123d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!desiredPowerState) {
131399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.UNDESIRED_POWER_STATE);
13143d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13150d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu        if (!radioStateFromCarrier) {
131699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.RADIO_DISABLED_BY_CARRIER);
131799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
131899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (!mDataEnabledSettings.isDataEnabled()) {
131999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.DATA_DISABLED);
13200d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu        }
13213d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
132299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // If there are hard disallowed reasons, we should not allow data connection no matter what.
132399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (reasons.containsHardDisallowedReasons()) {
132499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            if (dataConnectionReasons != null) {
132599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                dataConnectionReasons.copyFrom(reasons);
132699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            }
132799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            return false;
132899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
132999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
133099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 4: Determine if data should be allowed in some special conditions.
133199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
133299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // At this point, if data is not allowed, it must be because of the soft reasons. We
133399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // should start to check some special conditions that data will be allowed.
133499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
133599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // If the request APN type is unmetered and there are soft disallowed reasons (e.g. data
133699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // disabled, data roaming disabled) existing, we should allow the data because the user
133799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // won't be charged anyway.
133899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (!isMeteredApnType && !reasons.allowed()) {
133999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataAllowedReasonType.UNMETERED_APN);
134099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
134199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
134299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // If the request is restricted and there are only soft disallowed reasons (e.g. data
134399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // disabled, data roaming disabled) existing, we should allow the data.
134499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (apnContext != null
134599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                && !apnContext.hasNoRestrictedRequests(true)
134699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                && !reasons.allowed()) {
134799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataAllowedReasonType.RESTRICTED_REQUEST);
134899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
134999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
135099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // If at this point, we still haven't built any disallowed reasons, we should allow data.
135199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (reasons.allowed()) {
135299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataAllowedReasonType.NORMAL);
135399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
135499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
135599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (dataConnectionReasons != null) {
135699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            dataConnectionReasons.copyFrom(reasons);
135799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
135899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
135999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        return reasons.allowed();
1360cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1361c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1362c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    // arg for setupDataOnConnectableApns
1363c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    private enum RetryFailures {
1364c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        // retry failed networks always (the old default)
1365c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        ALWAYS,
13660e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        // retry only when a substantial change has occurred.  Either:
1367c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        // 1) we were restricted by voice/data concurrency and aren't anymore
1368c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        // 2) our apn list has change
1369c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        ONLY_ON_CHANGE
1370c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    };
1371c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt
1372ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void setupDataOnConnectableApns(String reason) {
1373c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        setupDataOnConnectableApns(reason, RetryFailures.ALWAYS);
1374c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    }
1375c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt
1376c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    private void setupDataOnConnectableApns(String reason, RetryFailures retryFailures) {
13779c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        if (VDBG) log("setupDataOnConnectableApns: " + reason);
13783fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
1379c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu        if (DBG && !VDBG) {
1380c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            StringBuilder sb = new StringBuilder(120);
1381c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            for (ApnContext apnContext : mPrioritySortedApnContexts) {
1382c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(apnContext.getApnType());
1383c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(":[state=");
1384c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(apnContext.getState());
1385c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(",enabled=");
1386c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(apnContext.isEnabled());
1387c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append("] ");
1388c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            }
13899c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            log("setupDataOnConnectableApns: " + reason + " " + sb);
1390c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu        }
1391c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu
13923fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        for (ApnContext apnContext : mPrioritySortedApnContexts) {
1393c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            if (VDBG) log("setupDataOnConnectableApns: apnContext " + apnContext);
1394c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu
1395735bc2f4524d68155765351912ffae11306c3bd5Chris Manton            if (apnContext.getState() == DctConstants.State.FAILED
13960e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                    || apnContext.getState() == DctConstants.State.SCANNING) {
1397c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                if (retryFailures == RetryFailures.ALWAYS) {
1398ee665b78ad648abd98b019a9c9047f206ed22994Robert Greenwalt                    apnContext.releaseDataConnection(reason);
1399c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                } else if (apnContext.isConcurrentVoiceAndDataAllowed() == false &&
14000e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                        mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
1401c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    // RetryFailures.ONLY_ON_CHANGE - check if voice concurrency has changed
1402ee665b78ad648abd98b019a9c9047f206ed22994Robert Greenwalt                    apnContext.releaseDataConnection(reason);
1403c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                }
1404cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1405ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.isConnectable()) {
14069c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                log("isConnectable() call trySetupData");
1407ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setReason(reason);
1408ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                trySetupData(apnContext);
1409cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1410cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1411c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1412c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
14131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    boolean isEmergency() {
1414a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        final boolean result = mPhone.isInEcm() || mPhone.isInEmergencyCall();
14151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("isEmergency: result=" + result);
14161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return result;
14171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
14181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1419cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean trySetupData(ApnContext apnContext) {
1420cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1421cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
1422cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
1423cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
1424cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setState(DctConstants.State.CONNECTED);
1425cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1426cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1427cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("trySetupData: X We're on the simulator; assuming connected retValue=true");
1428cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return true;
1429cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1430cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
143199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        DataConnectionReasons dataConnectionReasons = new DataConnectionReasons();
143299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        boolean isDataAllowed = isDataAllowed(apnContext, dataConnectionReasons);
143399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        String logStr = "trySetupData for APN type " + apnContext.getApnType() + ", reason: "
143499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                + apnContext.getReason() + ". " + dataConnectionReasons.toString();
143599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (DBG) log(logStr);
143699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        apnContext.requestLog(logStr);
1437120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        if (isDataAllowed) {
1438ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getState() == DctConstants.State.FAILED) {
14393d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                String str = "trySetupData: make a FAILED ApnContext IDLE so its reusable";
14402dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                if (DBG) log(str);
14412dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                apnContext.requestLog(str);
1442ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setState(DctConstants.State.IDLE);
1443ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1444203e588e3c42a81aa8a56f595119c181a63b12caWink Saville            int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
144599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            apnContext.setConcurrentVoiceAndDataAllowed(mPhone.getServiceStateTracker()
144699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                    .isConcurrentVoiceAndDataAllowed());
1447cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.getState() == DctConstants.State.IDLE) {
1448ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                ArrayList<ApnSetting> waitingApns =
1449ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                        buildWaitingApns(apnContext.getApnType(), radioTech);
1450cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (waitingApns.isEmpty()) {
1451ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    notifyNoData(DcFailCause.MISSING_UNKNOWN_APN, apnContext);
1452cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    notifyOffApnsOfAvailability(apnContext.getReason());
14532dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    String str = "trySetupData: X No APN found retValue=false";
14542dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    if (DBG) log(str);
14552dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    apnContext.requestLog(str);
1456cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return false;
1457cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1458cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setWaitingApns(waitingApns);
1459cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) {
1460ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        log ("trySetupData: Create from mAllApnSettings : "
1461ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                    + apnListToString(mAllApnSettings));
1462cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1463cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1464cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1465cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
146699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            boolean retValue = setupData(apnContext, radioTech, dataConnectionReasons.contains(
146799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                    DataAllowedReasonType.UNMETERED_APN));
1468cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(apnContext.getReason());
1469cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1470cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("trySetupData: X retValue=" + retValue);
1471cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return retValue;
1472cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1473cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
1474ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    && apnContext.isConnectable()) {
1475cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
1476ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1477cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(apnContext.getReason());
14782e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
14792e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            StringBuilder str = new StringBuilder();
14802e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
148199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            str.append("trySetupData failed. apnContext = [type=" + apnContext.getApnType()
148299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                    + ", mState=" + apnContext.getState() + ", apnEnabled="
148399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                    + apnContext.isEnabled() + ", mDependencyMet="
148499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                    + apnContext.getDependencyMet() + "] ");
14852e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
1486120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu            if (!mDataEnabledSettings.isDataEnabled()) {
148799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                str.append("isDataEnabled() = false. " + mDataEnabledSettings);
14882e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            }
14892e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
14909d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu            // If this is a data retry, we should set the APN state to FAILED so it won't stay
14919d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu            // in SCANNING forever.
14929d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu            if (apnContext.getState() == DctConstants.State.SCANNING) {
14939d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu                apnContext.setState(DctConstants.State.FAILED);
14949d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu                str.append(" Stop retrying.");
14959d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu            }
14969d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu
14972e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            if (DBG) log(str.toString());
14982e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            apnContext.requestLog(str.toString());
1499cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
1500cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1501c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1502c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
15030e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    // Disabled apn's still need avail/unavail notifications - send them out
15041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyOffApnsOfAvailability(String reason) {
1505cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1506187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (!mAttached.get() || !apnContext.isReady()) {
1507ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) log("notifyOffApnOfAvailability type:" + apnContext.getApnType());
1508cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
1509cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                            apnContext.getApnType(),
1510cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                            PhoneConstants.DataState.DISCONNECTED);
1511cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1512ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) {
1513187a39f896f88eb6c5e4306d9595546654825976Wink Saville                    log("notifyOffApnsOfAvailability skipped apn due to attached && isReady " +
1514cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            apnContext.toString());
1515cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1516c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1517c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1518c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1519c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1520cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1521cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * If tearDown is true, this only tears down a CONNECTED session. Presently,
1522cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * there is no mechanism for abandoning an CONNECTING session,
1523cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * but would likely involve cancelling pending async requests or
1524cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * setting a flag or new state to ignore them when they came in
1525cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param tearDown true if the underlying DataConnection should be
1526cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * disconnected.
1527cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param reason reason for the clean up.
15283fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return boolean - true if we did cleanup any connections, false if they
15293fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     *                   were already all disconnected.
1530cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
15311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean cleanUpAllConnections(boolean tearDown, String reason) {
1532cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("cleanUpAllConnections: tearDown=" + tearDown + " reason=" + reason);
15333fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        boolean didDisconnect = false;
15344c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu        boolean disableMeteredOnly = false;
1535a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
15364c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu        // reasons that only metered apn will be torn down
1537a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (!TextUtils.isEmpty(reason)) {
15384c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            disableMeteredOnly = reason.equals(Phone.REASON_DATA_SPECIFIC_DISABLED) ||
15394c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                    reason.equals(Phone.REASON_ROAMING_ON) ||
15404c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                    reason.equals(Phone.REASON_CARRIER_ACTION_DISABLE_METERED_APN);
1541a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1542cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1543cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
15443fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (apnContext.isDisconnected() == false) didDisconnect = true;
15454c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            if (disableMeteredOnly) {
1546783061ca03572618c01ce244d70d82fa4328d45ffionaxu                // Use ApnSetting to decide metered or non-metered.
1547783061ca03572618c01ce244d70d82fa4328d45ffionaxu                // Tear down all metered data connections.
1548783061ca03572618c01ce244d70d82fa4328d45ffionaxu                ApnSetting apnSetting = apnContext.getApnSetting();
154950734be549285702de00295778b8c2a4360215a0Jack Yu                if (apnSetting != null && apnSetting.isMetered(mPhone)) {
1550783061ca03572618c01ce244d70d82fa4328d45ffionaxu                    if (DBG) log("clean up metered ApnContext Type: " + apnContext.getApnType());
1551a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    apnContext.setReason(reason);
1552a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    cleanUpConnection(tearDown, apnContext);
1553a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1554a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
1555a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // TODO - only do cleanup if not disconnected
1556a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                apnContext.setReason(reason);
1557a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                cleanUpConnection(tearDown, apnContext);
1558a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1559c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1560cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1561cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopNetStatPoll();
1562cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopDataStallAlarm();
1563cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1564cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: Do we need mRequestedApnType?
1565cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
1566a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1567a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("cleanUpConnection: mDisconnectPendingCount = " + mDisconnectPendingCount);
1568a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (tearDown && mDisconnectPendingCount == 0) {
1569a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyDataDisconnectComplete();
1570a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
1571a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1572a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
15733fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return didDisconnect;
1574cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1575cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1576cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1577cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Cleanup all connections.
1578cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1579cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * TODO: Cleanup only a specified connection passed as a parameter.
1580cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *       Also, make sure when you clean up a conn, if it is last apply
1581cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *       logic as though it is cleanupAllConnections
1582cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1583cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param cause for the clean up.
1584cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
15851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onCleanUpAllConnections(String cause) {
1586cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, cause);
1587cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1588cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
15891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    void sendCleanUpConnection(boolean tearDown, ApnContext apnContext) {
15901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("sendCleanUpConnection: tearDown=" + tearDown + " apnContext=" + apnContext);
15911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_CLEAN_UP_CONNECTION);
15921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = tearDown ? 1 : 0;
15931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg2 = 0;
15941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.obj = apnContext;
15951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
15961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
1597cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
15981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void cleanUpConnection(boolean tearDown, ApnContext apnContext) {
1599cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
1600cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("cleanUpConnection: apn context is null");
1601cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
1602cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1603cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1604454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac = apnContext.getDcAc();
16052dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        String str = "cleanUpConnection: tearDown=" + tearDown + " reason=" +
16062dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                apnContext.getReason();
16079c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        if (VDBG) log(str + " apnContext=" + apnContext);
16082dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog(str);
1609cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (tearDown) {
1610cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.isDisconnected()) {
1611cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // The request is tearDown and but ApnContext is not connected.
1612cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // If apnContext is not enabled anymore, break the linkage to the DCAC/DC.
1613cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setState(DctConstants.State.IDLE);
1614cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (!apnContext.isReady()) {
16154750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                    if (dcac != null) {
16160e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                        str = "cleanUpConnection: teardown, disconnected, !ready";
16172dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        if (DBG) log(str + " apnContext=" + apnContext);
16182dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        apnContext.requestLog(str);
16194750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                        dcac.tearDown(apnContext, "", null);
16204750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                    }
1621cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setDataConnectionAc(null);
1622cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1623cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1624cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Connection is still there. Try to clean up.
1625cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (dcac != null) {
1626cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (apnContext.getState() != DctConstants.State.DISCONNECTING) {
1627cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        boolean disconnectAll = false;
1628cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (PhoneConstants.APN_TYPE_DUN.equals(apnContext.getApnType())) {
1629a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            // CAF_MSIM is this below condition required.
1630a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            // if (PhoneConstants.APN_TYPE_DUN.equals(PhoneConstants.APN_TYPE_DEFAULT)) {
16311484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                            if (teardownForDun()) {
163245eaa2335e64a8ff1ad8d5e8224c580ef996f370Wink Saville                                if (DBG) {
163345eaa2335e64a8ff1ad8d5e8224c580ef996f370Wink Saville                                    log("cleanUpConnection: disconnectAll DUN connection");
163445eaa2335e64a8ff1ad8d5e8224c580ef996f370Wink Saville                                }
1635cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // we need to tear it down - we brought it up just for dun and
1636cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // other people are camped on it and now dun is done.  We need
1637cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // to stop using it and let the normal apn list get used to find
1638cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // connections for the remaining desired connections
1639cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                disconnectAll = true;
1640cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            }
1641cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
16421a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                        final int generation = apnContext.getConnectionGeneration();
16431a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                        str = "cleanUpConnection: tearing down" + (disconnectAll ? " all" : "") +
16441a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                                " using gen#" + generation;
16452dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        if (DBG) log(str + "apnContext=" + apnContext);
16462dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        apnContext.requestLog(str);
164737cacdfe7ed079d89fb9e80317b5dfd2acb975e5Robert Greenwalt                        Pair<ApnContext, Integer> pair =
16481a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                                new Pair<ApnContext, Integer>(apnContext, generation);
164937cacdfe7ed079d89fb9e80317b5dfd2acb975e5Robert Greenwalt                        Message msg = obtainMessage(DctConstants.EVENT_DISCONNECT_DONE, pair);
1650cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (disconnectAll) {
1651ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            apnContext.getDcAc().tearDownAll(apnContext.getReason(), msg);
1652cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        } else {
1653ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            apnContext.getDcAc()
1654cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                .tearDown(apnContext, apnContext.getReason(), msg);
1655cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
1656cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.setState(DctConstants.State.DISCONNECTING);
1657a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        mDisconnectPendingCount++;
1658cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1659cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1660cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // apn is connected but no reference to dcac.
1661cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // Should not be happen, but reset the state in case.
1662cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setState(DctConstants.State.IDLE);
16632dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    apnContext.requestLog("cleanUpConnection: connected, bug no DCAC");
1664cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mPhone.notifyDataConnection(apnContext.getReason(),
1665cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                                apnContext.getApnType());
1666cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1667cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1668cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1669cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // force clean up the data connection.
1670ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac != null) dcac.reqReset();
1671cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setState(DctConstants.State.IDLE);
1672cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1673cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setDataConnectionAc(null);
1674cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1675cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1676ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // Make sure reconnection alarm is cleaned up if there is no ApnContext
1677cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // associated to the connection.
1678cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (dcac != null) {
1679ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            cancelReconnectAlarm(apnContext);
1680c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
16812dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        str = "cleanUpConnection: X tearDown=" + tearDown + " reason=" + apnContext.getReason();
16822dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        if (DBG) log(str + " apnContext=" + apnContext + " dcac=" + apnContext.getDcAc());
16832dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog(str);
1684cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1685c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
16865fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan    /**
16875fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan     * Fetch dun apn
16885fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan     * @return ApnSetting to be used for dun
16895fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan     */
16905fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan    @VisibleForTesting
16915fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan    public ApnSetting fetchDunApn() {
16921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (SystemProperties.getBoolean("net.tethering.noprovisioning", false)) {
16931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("fetchDunApn: net.tethering.noprovisioning=true ret: null");
16941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return null;
16951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
16961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int bearer = mPhone.getServiceState().getRilDataRadioTechnology();
1697d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        IccRecords r = mIccRecords.get();
1698d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        String operator = (r != null) ? r.getOperatorNumeric() : "";
1699d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        ArrayList<ApnSetting> dunCandidates = new ArrayList<ApnSetting>();
17001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting retDunSetting = null;
1701d92c67aa965200385acf3182ffb0af25297a366fJunda Liu
17025fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan        // Places to look for tether APN in order: TETHER_DUN_APN setting (to be deprecated soon),
17035fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan        // APN database, and config_tether_apndata resource (to be deprecated soon).
17041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        String apnData = Settings.Global.getString(mResolver, Settings.Global.TETHER_DUN_APN);
1705d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        if (!TextUtils.isEmpty(apnData)) {
1706d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            dunCandidates.addAll(ApnSetting.arrayFromString(apnData));
1707d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            if (VDBG) log("fetchDunApn: dunCandidates from Setting: " + dunCandidates);
1708d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        }
17095fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan
17105fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan        // todo: remove this and config_tether_apndata after APNs are moved from overlay to apns xml
17115fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan        // If TETHER_DUN_APN isn't set or APN database doesn't have dun APN,
1712d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        // try the resource as last resort.
1713d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        if (dunCandidates.isEmpty()) {
1714d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            String[] apnArrayData = mPhone.getContext().getResources()
1715d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                .getStringArray(R.array.config_tether_apndata);
1716ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu            if (!ArrayUtils.isEmpty(apnArrayData)) {
1717ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                for (String apnString : apnArrayData) {
1718ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                    ApnSetting apn = ApnSetting.fromString(apnString);
1719ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                    // apn may be null if apnString isn't valid or has error parsing
1720ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                    if (apn != null) dunCandidates.add(apn);
1721ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                }
1722ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                if (VDBG) log("fetchDunApn: dunCandidates from resource: " + dunCandidates);
1723d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            }
17241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
17251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
17265fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan        if (dunCandidates.isEmpty()) {
17275fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan            if (!ArrayUtils.isEmpty(mAllApnSettings)) {
17285fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan                for (ApnSetting apn : mAllApnSettings) {
17295fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan                    if (apn.canHandleType(PhoneConstants.APN_TYPE_DUN)) {
17305fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan                        dunCandidates.add(apn);
17315fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan                    }
17325fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan                }
17335fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan                if (VDBG) log("fetchDunApn: dunCandidates from database: " + dunCandidates);
17345fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan            }
17355fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan        }
17365fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan
1737d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        for (ApnSetting dunSetting : dunCandidates) {
1738176f28521fd45bb739709d309e7970b1558c9f61Cassie            if (!ServiceState.bitmaskHasTech(dunSetting.networkTypeBitmask,
1739176f28521fd45bb739709d309e7970b1558c9f61Cassie                    ServiceState.rilRadioTechnologyToNetworkType(bearer))) {
1740176f28521fd45bb739709d309e7970b1558c9f61Cassie                continue;
1741176f28521fd45bb739709d309e7970b1558c9f61Cassie            }
1742d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            if (dunSetting.numeric.equals(operator)) {
17431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (dunSetting.hasMvnoParams()) {
17441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (r != null && ApnSetting.mvnoMatches(r, dunSetting.mvnoType,
17451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            dunSetting.mvnoMatchData)) {
1746d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                        retDunSetting = dunSetting;
1747d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                        break;
17481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
17491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else if (mMvnoMatched == false) {
17501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    retDunSetting = dunSetting;
1751d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                    break;
17521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
17531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
17541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
17551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1756d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        if (VDBG) log("fetchDunApn: dunSetting=" + retDunSetting);
17571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return retDunSetting;
17581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
17591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
17601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public boolean hasMatchedTetherApnSetting() {
17611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting matched = fetchDunApn();
17621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("hasMatchedTetherApnSetting: APN=" + matched);
17631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return matched != null;
17641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
17651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1766cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
17671484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt     * Determine if DUN connection is special and we need to teardown on start/stop
17681484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt     */
17691484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt    private boolean teardownForDun() {
17701484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // CDMA always needs to do this the profile id is correct
17711484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        final int rilRat = mPhone.getServiceState().getRilDataRadioTechnology();
17721484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        if (ServiceState.isCdma(rilRat)) return true;
17731484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt
17741484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        return (fetchDunApn() != null);
17751484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt    }
17761484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt
17771484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt    /**
1778ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Cancels the alarm associated with apnContext.
1779cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1780ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * @param apnContext on which the alarm should be stopped.
1781cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1782ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void cancelReconnectAlarm(ApnContext apnContext) {
1783ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnContext == null) return;
1784cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1785ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        PendingIntent intent = apnContext.getReconnectIntent();
1786cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1787cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (intent != null) {
1788cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                AlarmManager am =
1789cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
1790cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                am.cancel(intent);
1791ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setReconnectIntent(null);
1792cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1793c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1794c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1795cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1796cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param types comma delimited list of APN types
1797cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return array of APN types
1798cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1799cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private String[] parseTypes(String types) {
1800c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String[] result;
1801cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // If unset, set to DEFAULT.
1802cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (types == null || types.equals("")) {
1803c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            result = new String[1];
1804cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result[0] = PhoneConstants.APN_TYPE_ALL;
1805cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1806cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result = types.split(",");
1807c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1808c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
1809c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1810c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1811ccfe5ebaf81c1378e8dbe44e45df26b0dc462a21Jack Yu    boolean isPermanentFailure(DcFailCause dcFailCause) {
1812ccfe5ebaf81c1378e8dbe44e45df26b0dc462a21Jack Yu        return (dcFailCause.isPermanentFailure(mPhone.getContext(), mPhone.getSubId()) &&
1813796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan                (mAttached.get() == false || dcFailCause != DcFailCause.SIGNAL_LOST));
1814796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan    }
1815796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan
1816fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    private ApnSetting makeApnSetting(Cursor cursor) {
1817fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        String[] types = parseTypes(
1818fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.TYPE)));
1819176f28521fd45bb739709d309e7970b1558c9f61Cassie        int networkTypeBitmask = cursor.getInt(
1820176f28521fd45bb739709d309e7970b1558c9f61Cassie                cursor.getColumnIndexOrThrow(Telephony.Carriers.NETWORK_TYPE_BITMASK));
1821176f28521fd45bb739709d309e7970b1558c9f61Cassie
1822fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        ApnSetting apn = new ApnSetting(
1823fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID)),
1824fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NUMERIC)),
1825fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NAME)),
1826fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN)),
1827fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1828fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1829fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY))),
1830fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PORT)),
1831fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1832fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1833fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC))),
1834fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1835fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1836fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY))),
1837fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPORT)),
1838fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)),
1839fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)),
18401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.AUTH_TYPE)),
1841fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                types,
1842fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROTOCOL)),
1843fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(
1844fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        Telephony.Carriers.ROAMING_PROTOCOL)),
1845fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(
1846fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        Telephony.Carriers.CARRIER_ENABLED)) == 1,
1847176f28521fd45bb739709d309e7970b1558c9f61Cassie                networkTypeBitmask,
18489d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROFILE_ID)),
18499d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(
18509d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                        Telephony.Carriers.MODEM_COGNITIVE)) == 1,
18519d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MAX_CONNS)),
18529d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(
18539d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                        Telephony.Carriers.WAIT_TIME)),
1854e9701717e43cc5aacbcf624f77a53be92350662cw                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MAX_CONNS_TIME)),
18553262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MTU)),
18563262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_TYPE)),
18573262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_MATCH_DATA)));
1858fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        return apn;
1859fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    }
1860fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
1861cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ArrayList<ApnSetting> createApnList(Cursor cursor) {
18623262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        ArrayList<ApnSetting> mnoApns = new ArrayList<ApnSetting>();
18633262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        ArrayList<ApnSetting> mvnoApns = new ArrayList<ApnSetting>();
1864fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        IccRecords r = mIccRecords.get();
1865fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
1866cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor.moveToFirst()) {
1867cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            do {
18683262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                ApnSetting apn = makeApnSetting(cursor);
18693262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                if (apn == null) {
18703262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                    continue;
18713262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                }
18723262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
18733262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                if (apn.hasMvnoParams()) {
187463913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan                    if (r != null && ApnSetting.mvnoMatches(r, apn.mvnoType, apn.mvnoMatchData)) {
18753262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                        mvnoApns.add(apn);
1876fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    }
1877fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                } else {
18783262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                    mnoApns.add(apn);
1879fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                }
1880cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } while (cursor.moveToNext());
1881cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
18823262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
18831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ArrayList<ApnSetting> result;
18841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mvnoApns.isEmpty()) {
18851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            result = mnoApns;
18861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mMvnoMatched = false;
18871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
18881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            result = mvnoApns;
18891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mMvnoMatched = true;
18901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
1891cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createApnList: X result=" + result);
1892c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
1893c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1894c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1895454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private boolean dataConnectionNotInUse(DcAsyncChannel dcac) {
1896ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("dataConnectionNotInUse: check if dcac is inuse dcac=" + dcac);
1897cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1898ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getDcAc() == dcac) {
1899cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("dataConnectionNotInUse: in use by apnContext=" + apnContext);
1900cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
1901cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1902cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1903cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: Fix retry handling so free DataConnections have empty apnlists.
1904cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Probably move retry handling into DataConnections and reduce complexity
1905cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // of DCT.
1906cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("dataConnectionNotInUse: tearDownAll");
1907ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        dcac.tearDownAll("No connection", null);
1908cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("dataConnectionNotInUse: not in use return true");
1909cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
1910cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1911cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1912454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel findFreeDataConnection() {
1913454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
1914cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac.isInactiveSync() && dataConnectionNotInUse(dcac)) {
1915cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
1916cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("findFreeDataConnection: found free DataConnection=" +
1917ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        " dcac=" + dcac);
1918cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1919ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                return dcac;
1920cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1921cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1922cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("findFreeDataConnection: NO free DataConnection");
1923cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
1924cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1925cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
192699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu    /**
192799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * Setup a data connection based on given APN type.
192899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *
192999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @param apnContext APN context
193099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @param radioTech RAT of the data connection
193199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @param unmeteredUseOnly True if this data connection should be only used for unmetered
193299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *                         purposes only.
193399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @return True if successful, otherwise false.
193499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     */
1935120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu    private boolean setupData(ApnContext apnContext, int radioTech, boolean unmeteredUseOnly) {
1936cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setupData: apnContext=" + apnContext);
19372dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog("setupData");
1938ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnSetting apnSetting;
19391484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        DcAsyncChannel dcac = null;
1940cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
19410e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        apnSetting = apnContext.getNextApnSetting();
19420e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
1943ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnSetting == null) {
1944cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("setupData: return for no apn found!");
1945cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
1946cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1947cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1948231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        int profileId = apnSetting.profileId;
1949231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        if (profileId == 0) {
1950231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen            profileId = getApnProfileID(apnContext.getApnType());
1951231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        }
1952231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen
19531484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // On CDMA, if we're explicitly asking for DUN, we need have
19541484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // a dun-profiled connection so we can't share an existing one
19551484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // On GSM/LTE we can share existing apn connections provided they support
19561484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // this type.
19571484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        if (apnContext.getApnType() != PhoneConstants.APN_TYPE_DUN ||
19581484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                teardownForDun() == false) {
19591484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt            dcac = checkForCompatibleConnectedApnContext(apnContext);
19601484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt            if (dcac != null) {
19611484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // Get the dcacApnSetting for the connection we want to share.
19621484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                ApnSetting dcacApnSetting = dcac.getApnSettingSync();
19631484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                if (dcacApnSetting != null) {
19641484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    // Setting is good, so use it.
19651484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    apnSetting = dcacApnSetting;
19661484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                }
1967ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1968ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
1969ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (dcac == null) {
19703fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (isOnlySingleDcAllowed(radioTech)) {
19713fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (isHigherPriorityApnContextActive(apnContext)) {
19723fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (DBG) {
19733fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        log("setupData: Higher priority ApnContext active.  Ignoring call");
19743fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    }
19753fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    return false;
19763fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                }
19773fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
19783fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // Only lower priority calls left.  Disconnect them all in this single PDP case
19793fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // so that we can bring up the requested higher priority call (once we receive
19800e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                // response for deactivate request for the calls we are about to disconnect
19813fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (cleanUpAllConnections(true, Phone.REASON_SINGLE_PDN_ARBITRATION)) {
19823fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // If any call actually requested to be disconnected, means we can't
19833fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // bring up this connection yet as we need to wait for those data calls
19843fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // to be disconnected.
19853fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (DBG) log("setupData: Some calls are disconnecting first.  Wait and retry");
19863fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    return false;
19873fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                }
19883fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
19893fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // No other calls are active, so proceed
19903fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (DBG) log("setupData: Single pdp. Continue setting up data call.");
19913fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
19923fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
1993ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            dcac = findFreeDataConnection();
1994cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1995ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac == null) {
1996ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                dcac = createDataConnection();
1997cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1998cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1999ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac == null) {
2000ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) log("setupData: No free DataConnection and couldn't create one, WEIRD");
2001cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
2002cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2003cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
20041a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        final int generation = apnContext.incAndGetConnectionGeneration();
20051a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        if (DBG) {
20061a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt            log("setupData: dcac=" + dcac + " apnSetting=" + apnSetting + " gen#=" + generation);
20071a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        }
2008cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2009cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setDataConnectionAc(dcac);
2010ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setApnSetting(apnSetting);
2011cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setState(DctConstants.State.CONNECTING);
2012cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
2013cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2014cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Message msg = obtainMessage();
2015cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        msg.what = DctConstants.EVENT_DATA_SETUP_COMPLETE;
20161a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        msg.obj = new Pair<ApnContext, Integer>(apnContext, generation);
2017120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        dcac.bringUp(apnContext, profileId, radioTech, unmeteredUseOnly, msg, generation);
2018cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2019cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setupData: initing!");
2020cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
2021cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2022cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
20231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void setInitialAttachApn() {
20241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting iaApnSetting = null;
20251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting defaultApnSetting = null;
20261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting firstApnSetting = null;
20271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
20281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("setInitialApn: E mPreferredApn=" + mPreferredApn);
20291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
203040b0e247a4a79e83f10b6410025ef1d7cc537692Robert Greenwalt        if (mPreferredApn != null && mPreferredApn.canHandleType(PhoneConstants.APN_TYPE_IA)) {
203140b0e247a4a79e83f10b6410025ef1d7cc537692Robert Greenwalt              iaApnSetting = mPreferredApn;
203240b0e247a4a79e83f10b6410025ef1d7cc537692Robert Greenwalt        } else if (mAllApnSettings != null && !mAllApnSettings.isEmpty()) {
20331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            firstApnSetting = mAllApnSettings.get(0);
20341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("setInitialApn: firstApnSetting=" + firstApnSetting);
20351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
20361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Search for Initial APN setting and the first apn that can handle default
20371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (ApnSetting apn : mAllApnSettings) {
203840b0e247a4a79e83f10b6410025ef1d7cc537692Robert Greenwalt                if (apn.canHandleType(PhoneConstants.APN_TYPE_IA)) {
20391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // The Initial Attach APN is highest priority so use it if there is one
20401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("setInitialApn: iaApnSetting=" + apn);
20411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    iaApnSetting = apn;
20421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    break;
20431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else if ((defaultApnSetting == null)
20441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        && (apn.canHandleType(PhoneConstants.APN_TYPE_DEFAULT))) {
20451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // Use the first default apn if no better choice
20461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("setInitialApn: defaultApnSetting=" + apn);
20471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    defaultApnSetting = apn;
20481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
20491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
20501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
20511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
20521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // The priority of apn candidates from highest to lowest is:
20530e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        //   1) APN_TYPE_IA (Initial Attach)
20541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        //   2) mPreferredApn, i.e. the current preferred apn
20551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        //   3) The first apn that than handle APN_TYPE_DEFAULT
20561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        //   4) The first APN we can find.
20571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
20581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting initialAttachApnSetting = null;
20591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (iaApnSetting != null) {
20601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using iaApnSetting");
20611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = iaApnSetting;
20621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (mPreferredApn != null) {
20631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using mPreferredApn");
20641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = mPreferredApn;
20651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (defaultApnSetting != null) {
20661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using defaultApnSetting");
20671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = defaultApnSetting;
20681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (firstApnSetting != null) {
20691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using firstApnSetting");
20701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = firstApnSetting;
20711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
20721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
20731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (initialAttachApnSetting == null) {
20741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: X There in no available apn");
20751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
20761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: X selected Apn=" + initialAttachApnSetting);
20771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
207871f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu            mDataServiceManager.setInitialAttachApn(createDataProfile(initialAttachApnSetting),
2079cc40713c49908aeaac0070bf4ea796247f9066b5Jack Yu                    mPhone.getServiceState().getDataRoamingFromRegistration(), null);
20801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
20811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
20821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2083c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
2084cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Handles changes to the APN database.
2085c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
2086cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onApnChanged() {
2087cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        DctConstants.State overallState = getOverallState();
2088cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isDisconnected = (overallState == DctConstants.State.IDLE ||
2089cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                overallState == DctConstants.State.FAILED);
2090cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
20911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mPhone instanceof GsmCdmaPhone) {
2092cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // The "current" may no longer be valid.  MMS depends on this to send properly. TBD
20931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            ((GsmCdmaPhone)mPhone).updateCurrentCarrierInProvider();
2094cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2095cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2096cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: It'd be nice to only do this if the changed entrie(s)
2097cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // match the current operator.
2098cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onApnChanged: createAllApnList and cleanUpAllConnections");
2099cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        createAllApnList();
21005d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi        setInitialAttachApn();
2101ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu        cleanUpConnectionsOnUpdatedApns(!isDisconnected, Phone.REASON_APN_CHANGED);
2102bda761320929f714951c328bfec6a51a1978db97Wink Saville
21038f6f52e4f7598e44cea1f9e5f4781291f9060d1dWink Saville        // FIXME: See bug 17426028 maybe no conditional is needed.
210438ca51d0f643405df51e78fce6c546424e9f410dShishir Agrawal        if (mPhone.getSubId() == SubscriptionManager.getDefaultDataSubscriptionId()) {
2105ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_APN_CHANGED);
2106c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2107c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2108c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2109c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
2110cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param cid Connection id provided from RIL.
2111cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return DataConnectionAc associated with specified cid.
2112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
2113454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel findDataConnectionAcByCid(int cid) {
2114454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
2115cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac.getCidSync() == cid) {
2116cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return dcac;
2117cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2118c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2119cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
2120c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2121c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
21223fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    /**
21233fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * "Active" here means ApnContext isEnabled() and not in FAILED state
21243fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @param apnContext to compare with
21253fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return true if higher priority active apn found
21263fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     */
21273fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean isHigherPriorityApnContextActive(ApnContext apnContext) {
21283fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        for (ApnContext otherContext : mPrioritySortedApnContexts) {
21293fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (apnContext.getApnType().equalsIgnoreCase(otherContext.getApnType())) return false;
21303fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (otherContext.isEnabled() && otherContext.getState() != DctConstants.State.FAILED) {
21313fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                return true;
21323fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
21333fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
21343fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return false;
21353fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    }
21363fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
21373fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    /**
21383fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * Reports if we support multiple connections or not.
21393fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * This is a combination of factors, based on carrier and RAT.
21403fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @param rilRadioTech the RIL Radio Tech currently in use
21413fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return true if only single DataConnection is allowed
21423fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     */
21433fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean isOnlySingleDcAllowed(int rilRadioTech) {
2144bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        // Default single dc rats with no knowledge of carrier
2145bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        int[] singleDcRats = null;
2146bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        // get the carrier specific value, if it exists, from CarrierConfigManager.
2147bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        // generally configManager and bundle should not be null, but if they are it should be okay
2148bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        // to leave singleDcRats null as well
2149bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        CarrierConfigManager configManager = (CarrierConfigManager)
2150bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu                mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
2151bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        if (configManager != null) {
2152bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu            PersistableBundle bundle = configManager.getConfig();
2153bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu            if (bundle != null) {
2154bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu                singleDcRats = bundle.getIntArray(
2155bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu                        CarrierConfigManager.KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY);
2156bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu            }
2157bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        }
21583fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        boolean onlySingleDcAllowed = false;
21593fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (Build.IS_DEBUGGABLE &&
21603fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                SystemProperties.getBoolean("persist.telephony.test.singleDc", false)) {
21613fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            onlySingleDcAllowed = true;
21623fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
21633fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (singleDcRats != null) {
21643fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            for (int i=0; i < singleDcRats.length && onlySingleDcAllowed == false; i++) {
21653fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (rilRadioTech == singleDcRats[i]) onlySingleDcAllowed = true;
21663fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
21673fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
21683fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
21693fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (DBG) log("isOnlySingleDcAllowed(" + rilRadioTech + "): " + onlySingleDcAllowed);
21703fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return onlySingleDcAllowed;
21713fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    }
21723fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
21731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    void sendRestartRadio() {
21741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG)log("sendRestartRadio:");
21751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_RESTART_RADIO);
21761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
21771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
21781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
21791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void restartRadio() {
2180cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("restartRadio: ************TURN OFF RADIO**************");
2181cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, Phone.REASON_RADIO_TURNED_OFF);
2182cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().powerOffRadioSafely(this);
2183cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        /* Note: no need to call setRadioPower(true).  Assuming the desired
2184cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * radio power state is still ON (as tracked by ServiceStateTracker),
2185cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * ServiceStateTracker will call setRadioPower when it receives the
2186cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * RADIO_STATE_CHANGED notification for the power off.  And if the
2187cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * desired power state has changed in the interim, we don't want to
2188cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * override it with an unconditional power on.
2189cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         */
2190cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2191cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int reset = Integer.parseInt(SystemProperties.get("net.ppp.reset-by-timeout", "0"));
21920e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        SystemProperties.set("net.ppp.reset-by-timeout", String.valueOf(reset + 1));
2193cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2194cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2195cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
2196cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Return true if data connection need to be setup after disconnected due to
2197cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * reason.
2198cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
21990e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu     * @param apnContext APN context
2200cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return true if try setup data connection is need for this reason
2201cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
22023fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean retryAfterDisconnected(ApnContext apnContext) {
2203cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean retry = true;
22043fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        String reason = apnContext.getReason();
2205cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
22063fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) ||
22073fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())
22083fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                 && isHigherPriorityApnContextActive(apnContext))) {
2209cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            retry = false;
2210cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2211cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return retry;
2212cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2213cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
22140e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    private void startAlarmForReconnect(long delay, ApnContext apnContext) {
2215cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String apnType = apnContext.getApnType();
221674672e8ee972f12406b72551261b4cc7e0651933Wink Saville
221774672e8ee972f12406b72551261b4cc7e0651933Wink Saville        Intent intent = new Intent(INTENT_RECONNECT_ALARM + "." + apnType);
221874672e8ee972f12406b72551261b4cc7e0651933Wink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, apnContext.getReason());
2219cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, apnType);
222067d43cfed4b996c20780bfec8fde1ae8c1391779Junda Liu        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
2221cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2222a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // Get current sub id.
22234f580e63be8e5787ce636c3b47335529ceb973b9Susheel nyamala        int subId = mPhone.getSubId();
2224a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
2225a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
222674672e8ee972f12406b72551261b4cc7e0651933Wink Saville        if (DBG) {
222774672e8ee972f12406b72551261b4cc7e0651933Wink Saville            log("startAlarmForReconnect: delay=" + delay + " action=" + intent.getAction()
222874672e8ee972f12406b72551261b4cc7e0651933Wink Saville                    + " apn=" + apnContext);
222974672e8ee972f12406b72551261b4cc7e0651933Wink Saville        }
223074672e8ee972f12406b72551261b4cc7e0651933Wink Saville
22310e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        PendingIntent alarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0,
2232cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                        intent, PendingIntent.FLAG_UPDATE_CURRENT);
2233ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setReconnectIntent(alarmIntent);
22347d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu
22357d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu        // Use the exact timer instead of the inexact one to provide better user experience.
22367d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu        // In some extreme cases, we saw the retry was delayed for few minutes.
22370852a954be5937a1b0bca94df0c2007d7ee3c0c7Jack Yu        // Note that if the stated trigger time is in the past, the alarm will be triggered
22380852a954be5937a1b0bca94df0c2007d7ee3c0c7Jack Yu        // immediately.
22397d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu        mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
2240cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                SystemClock.elapsedRealtime() + delay, alarmIntent);
2241cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2242cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2243ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void notifyNoData(DcFailCause lastFailCauseCode,
2244cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                              ApnContext apnContext) {
2245cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log( "notifyNoData: type=" + apnContext.getApnType());
2246ccfe5ebaf81c1378e8dbe44e45df26b0dc462a21Jack Yu        if (isPermanentFailure(lastFailCauseCode)
2247cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            && (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT))) {
2248cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
2249cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2250cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2251cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
22521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public boolean getAutoAttachOnCreation() {
22531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mAutoAttachOnCreation.get();
22541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
22551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
22561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRecordsLoadedOrSubIdChanged() {
22571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("onRecordsLoadedOrSubIdChanged: createAllApnList");
225812fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        mAutoAttachOnCreationConfig = mPhone.getContext().getResources()
225912fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao                .getBoolean(com.android.internal.R.bool.config_auto_attach_data_on_creation);
2260bda761320929f714951c328bfec6a51a1978db97Wink Saville
2261cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        createAllApnList();
22625d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi        setInitialAttachApn();
226322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPhone.mCi.getRadioState().isOn()) {
22641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("onRecordsLoadedOrSubIdChanged: notifying data availability");
2265cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_SIM_LOADED);
2266cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2267bda761320929f714951c328bfec6a51a1978db97Wink Saville        setupDataOnConnectableApns(Phone.REASON_SIM_LOADED);
2268cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2269cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
22704c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu    /**
22714c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu     * Action set from carrier signalling broadcast receivers to enable/disable metered apns.
22724c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu     */
22736a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu    private void onSetCarrierDataEnabled(AsyncResult ar) {
22746a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu        if (ar.exception != null) {
22756a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu            Rlog.e(LOG_TAG, "CarrierDataEnable exception: " + ar.exception);
22766a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu            return;
22776a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu        }
2278a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        synchronized (mDataEnabledSettings) {
22796a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu            boolean enabled = (boolean) ar.result;
2280a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            if (enabled != mDataEnabledSettings.isCarrierDataEnabled()) {
2281a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                if (DBG) {
2282a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                    log("carrier Action: set metered apns enabled: " + enabled);
2283a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                }
2284a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
2285a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                // Disable/enable all metered apns
2286a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                mDataEnabledSettings.setCarrierDataEnabled(enabled);
2287a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
2288a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                if (!enabled) {
2289a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                    // Send otasp_sim_unprovisioned so that SuW is able to proceed and notify users
22906432c2f4a4f438b72fa0d4b51d5098b179935868Nathan Harold                    mPhone.notifyOtaspChanged(TelephonyManager.OTASP_SIM_UNPROVISIONED);
2291a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                    // Tear down all metered apns
2292a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                    cleanUpAllConnections(true, Phone.REASON_CARRIER_ACTION_DISABLE_METERED_APN);
2293a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                } else {
2294120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    // Re-evaluate Otasp state
22954839eb565b4294443a34a93ee2ca93ac70b72b87fionaxu                    int otaspState = mPhone.getServiceStateTracker().getOtasp();
22964839eb565b4294443a34a93ee2ca93ac70b72b87fionaxu                    mPhone.notifyOtaspChanged(otaspState);
22974839eb565b4294443a34a93ee2ca93ac70b72b87fionaxu
2298120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    reevaluateDataConnections();
2299a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                    setupDataOnConnectableApns(Phone.REASON_DATA_ENABLED);
2300a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                }
230168f4f4a0bc8d4060b5775e7a24a97ea5b485989efionaxu            }
2302a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        }
2303a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    }
2304a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
23050469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal    private void onSimNotReady() {
23060469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        if (DBG) log("onSimNotReady");
23070469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal
23080469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        cleanUpAllConnections(true, Phone.REASON_SIM_NOT_READY);
23090469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        mAllApnSettings = null;
23100469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        mAutoAttachOnCreationConfig = false;
23117e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C        // Clear auto attach as modem is expected to do a new attach once SIM is ready
23127e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C        mAutoAttachOnCreation.set(false);
23130469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal    }
23140469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal
23151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetDependencyMet(String apnType, boolean met) {
2316cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // don't allow users to tweak hipri to work around default dependency not met
2317cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_HIPRI.equals(apnType)) return;
2318cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2319cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
2320cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
2321cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onSetDependencyMet: ApnContext not found in onSetDependencyMet(" +
2322cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnType + ", " + met + ")");
2323cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
2324cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2325cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        applyNewState(apnContext, apnContext.isEnabled(), met);
2326cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_DEFAULT.equals(apnType)) {
2327cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // tie actions on default to similar actions on HIPRI regarding dependencyMet
2328cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext = mApnContexts.get(PhoneConstants.APN_TYPE_HIPRI);
2329cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext != null) applyNewState(apnContext, apnContext.isEnabled(), met);
2330cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2331cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2332c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2333a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    public void setPolicyDataEnabled(boolean enabled) {
2334a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        if (DBG) log("setPolicyDataEnabled: " + enabled);
2335a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        Message msg = obtainMessage(DctConstants.CMD_SET_POLICY_DATA_ENABLE);
2336a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        msg.arg1 = (enabled ? DctConstants.ENABLED : DctConstants.DISABLED);
2337a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        sendMessage(msg);
2338a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    }
2339a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
23401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetPolicyDataEnabled(boolean enabled) {
2341a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        synchronized (mDataEnabledSettings) {
234299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            final boolean prevEnabled = isDataEnabled();
2343a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            if (mDataEnabledSettings.isPolicyDataEnabled() != enabled) {
2344a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                mDataEnabledSettings.setPolicyDataEnabled(enabled);
2345a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                // TODO: We should register for DataEnabledSetting's data enabled/disabled event and
2346a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                // handle the rest from there.
234799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                if (prevEnabled != isDataEnabled()) {
23481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (!prevEnabled) {
2349120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                        reevaluateDataConnections();
23501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onTrySetupData(Phone.REASON_DATA_ENABLED);
23511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
23521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);
23531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
23541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
23551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
23561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
23571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
23581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2359cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void applyNewState(ApnContext apnContext, boolean enabled, boolean met) {
2360cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean cleanup = false;
2361cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean trySetup = false;
23622dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        String str ="applyNewState(" + apnContext.getApnType() + ", " + enabled +
23632dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                "(" + apnContext.isEnabled() + "), " + met + "(" +
23642dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                apnContext.getDependencyMet() +"))";
23652dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        if (DBG) log(str);
23662dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog(str);
23672dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt
2368cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext.isReady()) {
2369305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt            cleanup = true;
23702428693913ae731d4ace3414429f5e91af24ea36Wink Saville            if (enabled && met) {
23712428693913ae731d4ace3414429f5e91af24ea36Wink Saville                DctConstants.State state = apnContext.getState();
23722428693913ae731d4ace3414429f5e91af24ea36Wink Saville                switch(state) {
23732428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case CONNECTING:
23742428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case CONNECTED:
23752428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case DISCONNECTING:
23762428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // We're "READY" and active so just return
23772428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        if (DBG) log("applyNewState: 'ready' so return");
23782dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        apnContext.requestLog("applyNewState state=" + state + ", so return");
23792428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        return;
23802428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case IDLE:
23812428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // fall through: this is unexpected but if it happens cleanup and try setup
23822428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case FAILED:
23839d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu                    case SCANNING:
23842428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case RETRYING: {
23852428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // We're "READY" but not active so disconnect (cleanup = true) and
23862428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // connect (trySetup = true) to be sure we retry the connection.
23872428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        trySetup = true;
23882428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        apnContext.setReason(Phone.REASON_DATA_ENABLED);
23892428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        break;
23902428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    }
23912428693913ae731d4ace3414429f5e91af24ea36Wink Saville                }
2392305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt            } else if (met) {
2393cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setReason(Phone.REASON_DATA_DISABLED);
2394305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // If ConnectivityService has disabled this network, stop trying to bring
2395305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // it up, but do not tear it down - ConnectivityService will do that
2396305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // directly by talking with the DataConnection.
23971484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                //
23981484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // This doesn't apply to DUN, however.  Those connections have special
23991484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // requirements from carriers and we need stop using them when the dun
24001484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // request goes away.  This applies to both CDMA and GSM because they both
24011484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // can declare the DUN APN sharable by default traffic, thus still satisfying
24021484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // those requests and not torn down organically.
24039db4884401d436d0796138f9190079df310cee95Sukanya Rajkhowa                if ((apnContext.getApnType() == PhoneConstants.APN_TYPE_DUN && teardownForDun())
24049db4884401d436d0796138f9190079df310cee95Sukanya Rajkhowa                        || apnContext.getState() != DctConstants.State.CONNECTED) {
24059db4884401d436d0796138f9190079df310cee95Sukanya Rajkhowa                    str = "Clean up the connection. Apn type = " + apnContext.getApnType()
24069db4884401d436d0796138f9190079df310cee95Sukanya Rajkhowa                            + ", state = " + apnContext.getState();
24079db4884401d436d0796138f9190079df310cee95Sukanya Rajkhowa                    if (DBG) log(str);
24089db4884401d436d0796138f9190079df310cee95Sukanya Rajkhowa                    apnContext.requestLog(str);
24091484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    cleanup = true;
24101484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                } else {
24111484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    cleanup = false;
24121484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                }
2413cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
2414cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_UNMET);
2415cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2416cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2417cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (enabled && met) {
2418cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apnContext.isEnabled()) {
2419cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_MET);
2420cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2421cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setReason(Phone.REASON_DATA_ENABLED);
2422c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
2423cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apnContext.getState() == DctConstants.State.FAILED) {
2424cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setState(DctConstants.State.IDLE);
2425cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2426cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                trySetup = true;
2427cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2428cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2429cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setEnabled(enabled);
2430cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setDependencyMet(met);
2431cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cleanup) cleanUpConnection(true, apnContext);
24320d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt        if (trySetup) {
24330d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt            apnContext.resetErrorCodeRetries();
24340d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt            trySetupData(apnContext);
24350d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt        }
2436cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2437c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2438454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel checkForCompatibleConnectedApnContext(ApnContext apnContext) {
2439cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String apnType = apnContext.getApnType();
2440cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnSetting dunSetting = null;
2441cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2442cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_DUN.equals(apnType)) {
2443cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            dunSetting = fetchDunApn();
2444cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2445ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) {
2446ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            log("checkForCompatibleConnectedApnContext: apnContext=" + apnContext );
2447ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
2448cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2449454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel potentialDcac = null;
2450ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnContext potentialApnCtx = null;
2451ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        for (ApnContext curApnCtx : mApnContexts.values()) {
2452454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel curDcac = curApnCtx.getDcAc();
2453ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (curDcac != null) {
2454ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                ApnSetting apnSetting = curApnCtx.getApnSetting();
2455a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("apnSetting: " + apnSetting);
2456cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (dunSetting != null) {
2457cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (dunSetting.equals(apnSetting)) {
2458ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        switch (curApnCtx.getState()) {
2459cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            case CONNECTED:
2460cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                if (DBG) {
2461ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                    log("checkForCompatibleConnectedApnContext:"
2462ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                            + " found dun conn=" + curDcac
2463ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                            + " curApnCtx=" + curApnCtx);
2464cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                }
2465ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                return curDcac;
2466ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            case RETRYING:
2467cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            case CONNECTING:
2468ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                potentialDcac = curDcac;
2469ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                potentialApnCtx = curApnCtx;
2470cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            default:
2471cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // Not connected, potential unchanged
2472cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                break;
2473cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
2474cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2475cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else if (apnSetting != null && apnSetting.canHandleType(apnType)) {
2476ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    switch (curApnCtx.getState()) {
2477cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        case CONNECTED:
2478cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            if (DBG) {
2479ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                log("checkForCompatibleConnectedApnContext:"
2480ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        + " found canHandle conn=" + curDcac
2481ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        + " curApnCtx=" + curApnCtx);
2482cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            }
2483ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            return curDcac;
2484ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        case RETRYING:
2485cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        case CONNECTING:
2486ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            potentialDcac = curDcac;
2487ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            potentialApnCtx = curApnCtx;
2488cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        default:
2489cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            // Not connected, potential unchanged
2490cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            break;
2491cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2492cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2493ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            } else {
2494ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) {
2495ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    log("checkForCompatibleConnectedApnContext: not conn curApnCtx=" + curApnCtx);
2496ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                }
2497cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2498cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2499ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (potentialDcac != null) {
2500cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
2501ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                log("checkForCompatibleConnectedApnContext: found potential conn=" + potentialDcac
2502ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        + " curApnCtx=" + potentialApnCtx);
2503cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2504ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            return potentialDcac;
2505cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2506c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2507ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("checkForCompatibleConnectedApnContext: NO conn apnContext=" + apnContext);
2508cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
2509cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2510c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
251127b650c406018355a88a41528db7859e232728a0Jack Yu    public void setEnabled(int id, boolean enable) {
25121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_ENABLE_NEW_APN);
25131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = id;
25141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg2 = (enable ? DctConstants.ENABLED : DctConstants.DISABLED);
25151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
25161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
25171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
25181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onEnableApn(int apnId, int enabled) {
2519af5593594070f825032be46dced573cd195956e1Robert Greenwalt        ApnContext apnContext = mApnContextsById.get(apnId);
2520cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
2521cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onEnableApn(" + apnId + ", " + enabled + "): NO ApnContext");
2522cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
2523cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2524cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO change our retry manager to use the appropriate numbers for the new APN
2525cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onEnableApn: apnContext=" + apnContext + " call applyNewState");
2526cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        applyNewState(apnContext, enabled == DctConstants.ENABLED, apnContext.getDependencyMet());
2527af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla
2528af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla        if ((enabled == DctConstants.DISABLED) &&
2529af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology()) &&
2530af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            !isHigherPriorityApnContextActive(apnContext)) {
2531af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla
2532af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            if(DBG) log("onEnableApn: isOnlySingleDcAllowed true & higher priority APN disabled");
2533af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            // If the highest priority APN is disabled and only single
2534af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            // data call is allowed, try to setup data call on other connectable APN.
2535af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            setupDataOnConnectableApns(Phone.REASON_SINGLE_PDN_ARBITRATION);
2536af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla        }
2537cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2538c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2539cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // TODO: We shouldnt need this.
25401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean onTrySetupData(String reason) {
2541cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onTrySetupData: reason=" + reason);
2542ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(reason);
2543cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
2544cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2545c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
25461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean onTrySetupData(ApnContext apnContext) {
2547cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onTrySetupData: apnContext=" + apnContext);
2548cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return trySetupData(apnContext);
2549cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2550c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
25511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
2552a64092befe003884c4c8951438ab311ce8f92824Malcolm Chen     * Whether data is enabled by user. Unlike isDataEnabled, this only
2553a64092befe003884c4c8951438ab311ce8f92824Malcolm Chen     * checks user setting stored in {@link android.provider.Settings.Global#MOBILE_DATA}
2554a64092befe003884c4c8951438ab311ce8f92824Malcolm Chen     * if not provisioning, or isProvisioningDataEnabled if provisioning.
25551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
2556a64092befe003884c4c8951438ab311ce8f92824Malcolm Chen    public boolean isUserDataEnabled() {
2557985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen        if (mDataEnabledSettings.isProvisioning()) {
2558985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen            return mDataEnabledSettings.isProvisioningDataEnabled();
2559f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        } else {
2560985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen            return mDataEnabledSettings.isUserDataEnabled();
25611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
25621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
25631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
25641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
256521e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * Modify {@link android.provider.Settings.Global#DATA_ROAMING} value for user modification only
25661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
256721e6af8d6197a071d025733fffeffc157d0085bcfionaxu    public void setDataRoamingEnabledByUser(boolean enabled) {
25681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        final int phoneSubId = mPhone.getSubId();
25695b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (getDataRoamingEnabled() != enabled) {
25701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            int roaming = enabled ? 1 : 0;
25711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
25721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // For single SIM phones, this is a per phone property.
25731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (TelephonyManager.getDefault().getSimCount() == 1) {
25741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Settings.Global.putInt(mResolver, Settings.Global.DATA_ROAMING, roaming);
257521e6af8d6197a071d025733fffeffc157d0085bcfionaxu                setDataRoamingFromUserAction(true);
25761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
25771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Settings.Global.putInt(mResolver, Settings.Global.DATA_ROAMING +
25781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                         phoneSubId, roaming);
25791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
25801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
25811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSubscriptionManager.setDataRoaming(roaming, phoneSubId);
25821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // will trigger handleDataOnRoamingChange() through observer
25831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
258421e6af8d6197a071d025733fffeffc157d0085bcfionaxu                log("setDataRoamingEnabledByUser: set phoneSubId=" + phoneSubId
25855b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu                        + " isRoaming=" + enabled);
25861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
25871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
25881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
258921e6af8d6197a071d025733fffeffc157d0085bcfionaxu                log("setDataRoamingEnabledByUser: unchanged phoneSubId=" + phoneSubId
25901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        + " isRoaming=" + enabled);
25911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu             }
25921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
25931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
25941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
25951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
25961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Return current {@link android.provider.Settings.Global#DATA_ROAMING} value.
25971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
25985b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    public boolean getDataRoamingEnabled() {
259921e6af8d6197a071d025733fffeffc157d0085bcfionaxu        boolean isDataRoamingEnabled;
26001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        final int phoneSubId = mPhone.getSubId();
26011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2602985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen        // For single SIM phones, this is a per phone property.
2603985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen        if (TelephonyManager.getDefault().getSimCount() == 1) {
2604985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen            isDataRoamingEnabled = Settings.Global.getInt(mResolver,
2605985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen                    Settings.Global.DATA_ROAMING,
2606985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen                    getDefaultDataRoamingEnabled() ? 1 : 0) != 0;
2607985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen        } else {
2608985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen            isDataRoamingEnabled = Settings.Global.getInt(mResolver,
2609985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen                    Settings.Global.DATA_ROAMING + phoneSubId,
2610985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen                    getDefaultDataRoamingEnabled() ? 1 : 0) != 0;
26111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
2612985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen
26131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) {
26145b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            log("getDataRoamingEnabled: phoneSubId=" + phoneSubId
26155b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu                    + " isDataRoamingEnabled=" + isDataRoamingEnabled);
26161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
26171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return isDataRoamingEnabled;
26181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
26191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
262021e6af8d6197a071d025733fffeffc157d0085bcfionaxu    /**
262121e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * get default values for {@link Settings.Global#DATA_ROAMING}
262221e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * return {@code true} if either
262321e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} or
262421e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * system property ro.com.android.dataroaming is set to true. otherwise return {@code false}
262521e6af8d6197a071d025733fffeffc157d0085bcfionaxu     */
262621e6af8d6197a071d025733fffeffc157d0085bcfionaxu    private boolean getDefaultDataRoamingEnabled() {
262721e6af8d6197a071d025733fffeffc157d0085bcfionaxu        final CarrierConfigManager configMgr = (CarrierConfigManager)
262821e6af8d6197a071d025733fffeffc157d0085bcfionaxu                mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
262921e6af8d6197a071d025733fffeffc157d0085bcfionaxu        boolean isDataRoamingEnabled = "true".equalsIgnoreCase(SystemProperties.get(
263021e6af8d6197a071d025733fffeffc157d0085bcfionaxu                "ro.com.android.dataroaming", "false"));
263121e6af8d6197a071d025733fffeffc157d0085bcfionaxu        isDataRoamingEnabled |= configMgr.getConfigForSubId(mPhone.getSubId()).getBoolean(
263221e6af8d6197a071d025733fffeffc157d0085bcfionaxu                CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
263321e6af8d6197a071d025733fffeffc157d0085bcfionaxu        return isDataRoamingEnabled;
263421e6af8d6197a071d025733fffeffc157d0085bcfionaxu    }
263521e6af8d6197a071d025733fffeffc157d0085bcfionaxu
263621e6af8d6197a071d025733fffeffc157d0085bcfionaxu    /**
263721e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * Set default value for {@link android.provider.Settings.Global#DATA_ROAMING}
263821e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * if the setting is not from user actions. default value is based on carrier config and system
263921e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * properties.
264021e6af8d6197a071d025733fffeffc157d0085bcfionaxu     */
264121e6af8d6197a071d025733fffeffc157d0085bcfionaxu    private void setDefaultDataRoamingEnabled() {
264221e6af8d6197a071d025733fffeffc157d0085bcfionaxu        // For single SIM phones, this is a per phone property.
264321e6af8d6197a071d025733fffeffc157d0085bcfionaxu        String setting = Settings.Global.DATA_ROAMING;
264421e6af8d6197a071d025733fffeffc157d0085bcfionaxu        boolean useCarrierSpecificDefault = false;
264521e6af8d6197a071d025733fffeffc157d0085bcfionaxu        if (TelephonyManager.getDefault().getSimCount() != 1) {
264621e6af8d6197a071d025733fffeffc157d0085bcfionaxu            setting = setting + mPhone.getSubId();
264721e6af8d6197a071d025733fffeffc157d0085bcfionaxu            try {
264821e6af8d6197a071d025733fffeffc157d0085bcfionaxu                Settings.Global.getInt(mResolver, setting);
264921e6af8d6197a071d025733fffeffc157d0085bcfionaxu            } catch (SettingNotFoundException ex) {
265021e6af8d6197a071d025733fffeffc157d0085bcfionaxu                // For msim, update to carrier default if uninitialized.
265121e6af8d6197a071d025733fffeffc157d0085bcfionaxu                useCarrierSpecificDefault = true;
265221e6af8d6197a071d025733fffeffc157d0085bcfionaxu            }
265321e6af8d6197a071d025733fffeffc157d0085bcfionaxu        } else if (!isDataRoamingFromUserAction()) {
265421e6af8d6197a071d025733fffeffc157d0085bcfionaxu            // for single sim device, update to carrier default if user action is not set
265521e6af8d6197a071d025733fffeffc157d0085bcfionaxu            useCarrierSpecificDefault = true;
265621e6af8d6197a071d025733fffeffc157d0085bcfionaxu        }
265721e6af8d6197a071d025733fffeffc157d0085bcfionaxu        if (useCarrierSpecificDefault) {
265821e6af8d6197a071d025733fffeffc157d0085bcfionaxu            boolean defaultVal = getDefaultDataRoamingEnabled();
265921e6af8d6197a071d025733fffeffc157d0085bcfionaxu            log("setDefaultDataRoamingEnabled: " + setting + "default value: " + defaultVal);
266021e6af8d6197a071d025733fffeffc157d0085bcfionaxu            Settings.Global.putInt(mResolver, setting, defaultVal ? 1 : 0);
266121e6af8d6197a071d025733fffeffc157d0085bcfionaxu            mSubscriptionManager.setDataRoaming(defaultVal ? 1 : 0, mPhone.getSubId());
266221e6af8d6197a071d025733fffeffc157d0085bcfionaxu        }
266321e6af8d6197a071d025733fffeffc157d0085bcfionaxu    }
266421e6af8d6197a071d025733fffeffc157d0085bcfionaxu
266521e6af8d6197a071d025733fffeffc157d0085bcfionaxu    private boolean isDataRoamingFromUserAction() {
266621e6af8d6197a071d025733fffeffc157d0085bcfionaxu        final SharedPreferences sp = PreferenceManager
266721e6af8d6197a071d025733fffeffc157d0085bcfionaxu                .getDefaultSharedPreferences(mPhone.getContext());
266821e6af8d6197a071d025733fffeffc157d0085bcfionaxu        // since we don't want to unset user preference from system update, pass true as the default
266921e6af8d6197a071d025733fffeffc157d0085bcfionaxu        // value if shared pref does not exist and set shared pref to false explicitly from factory
267021e6af8d6197a071d025733fffeffc157d0085bcfionaxu        // reset.
267121e6af8d6197a071d025733fffeffc157d0085bcfionaxu        if (!sp.contains(Phone.DATA_ROAMING_IS_USER_SETTING_KEY)
267221e6af8d6197a071d025733fffeffc157d0085bcfionaxu                && Settings.Global.getInt(mResolver, Settings.Global.DEVICE_PROVISIONED, 0) == 0) {
267321e6af8d6197a071d025733fffeffc157d0085bcfionaxu            sp.edit().putBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, false).commit();
267421e6af8d6197a071d025733fffeffc157d0085bcfionaxu        }
267521e6af8d6197a071d025733fffeffc157d0085bcfionaxu        return sp.getBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, true);
267621e6af8d6197a071d025733fffeffc157d0085bcfionaxu    }
267721e6af8d6197a071d025733fffeffc157d0085bcfionaxu
267821e6af8d6197a071d025733fffeffc157d0085bcfionaxu    private void setDataRoamingFromUserAction(boolean isUserAction) {
267921e6af8d6197a071d025733fffeffc157d0085bcfionaxu        final SharedPreferences.Editor sp = PreferenceManager
268021e6af8d6197a071d025733fffeffc157d0085bcfionaxu                .getDefaultSharedPreferences(mPhone.getContext()).edit();
268121e6af8d6197a071d025733fffeffc157d0085bcfionaxu        sp.putBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, isUserAction).commit();
268221e6af8d6197a071d025733fffeffc157d0085bcfionaxu    }
268321e6af8d6197a071d025733fffeffc157d0085bcfionaxu
26845b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    // When the data roaming status changes from roaming to non-roaming.
26855b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    private void onDataRoamingOff() {
26865b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (DBG) log("onDataRoamingOff");
2687c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
26885b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (!getDataRoamingEnabled()) {
26895b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // TODO: Remove this once all old vendor RILs are gone. We don't need to set initial apn
26905b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // attach and send the data profile again as the modem should have both roaming and
26915b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // non-roaming protocol in place. Modem should choose the right protocol based on the
26925b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // roaming condition.
26935b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            setInitialAttachApn();
26945b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            setDataProfilesAsNeeded();
26958e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu
26965b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // If the user did not enable data roaming, now when we transit from roaming to
26975b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // non-roaming, we should try to reestablish the data connection.
2698c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2699cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_OFF);
2700bda761320929f714951c328bfec6a51a1978db97Wink Saville            setupDataOnConnectableApns(Phone.REASON_ROAMING_OFF);
2701cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2702cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_ROAMING_OFF);
2703cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2704cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2705cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
27065b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    // This method is called
27075b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    // 1. When the data roaming status changes from non-roaming to roaming.
27085b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    // 2. When allowed data roaming settings is changed by the user.
2709d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen    private void onDataRoamingOnOrSettingsChanged(int messageType) {
27105b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (DBG) log("onDataRoamingOnOrSettingsChanged");
2711d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen        // Used to differentiate data roaming turned on vs settings changed.
2712d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen        boolean settingChanged = (messageType == DctConstants.EVENT_ROAMING_SETTING_CHANGE);
2713f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu
2714f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu        // Check if the device is actually data roaming
2715f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu        if (!mPhone.getServiceState().getDataRoaming()) {
2716f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu            if (DBG) log("device is not roaming. ignored the request.");
2717f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu            return;
2718f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu        }
2719cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2720d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen        checkDataRoamingStatus(settingChanged);
2721d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen
27225b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (getDataRoamingEnabled()) {
27235b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            if (DBG) log("onDataRoamingOnOrSettingsChanged: setup data on roaming");
27245b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu
2725ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_ROAMING_ON);
2726cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_ROAMING_ON);
2727cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
27285b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // If the user does not turn on data roaming, when we transit from non-roaming to
27295b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // roaming, we need to tear down the data connection otherwise the user might be
27305b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // charged for data roaming usage.
27315b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            if (DBG) log("onDataRoamingOnOrSettingsChanged: Tear down data connection on roaming.");
2732cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpAllConnections(true, Phone.REASON_ROAMING_ON);
2733cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
2734cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2735cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2736cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2737d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen    // We want to track possible roaming data leakage. Which is, if roaming setting
2738d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen    // is disabled, yet we still setup a roaming data connection or have a connected ApnContext
2739d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen    // switched to roaming. When this happens, we log it in a local log.
2740d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen    private void checkDataRoamingStatus(boolean settingChanged) {
2741d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen        if (!settingChanged && !getDataRoamingEnabled()
2742d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                && mPhone.getServiceState().getDataRoaming()) {
2743d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen            for (ApnContext apnContext : mApnContexts.values()) {
2744d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                if (apnContext.getState() == DctConstants.State.CONNECTED) {
2745d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                    mDataRoamingLeakageLog.log("PossibleRoamingLeakage "
2746d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                            + " connection params: " + (apnContext.getDcAc() != null
2747d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                            ? apnContext.getDcAc().mLastConnectionParams : ""));
2748d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                }
2749d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen            }
2750d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen        }
2751d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen    }
2752d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen
27531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRadioAvailable() {
2754cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onRadioAvailable");
2755cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
2756cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
2757cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
2758cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // setState(DctConstants.State.CONNECTED);
2759cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(null);
2760cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2761cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("onRadioAvailable: We're on the simulator; assuming data is connected");
2762cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2763cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2764cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
2765cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (r != null && r.getRecordsLoaded()) {
2766cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(null);
2767cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2768cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2769cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getOverallState() != DctConstants.State.IDLE) {
2770cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpConnection(true, null);
2771cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2772cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2773cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
27741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRadioOffOrNotAvailable() {
2775cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Make sure our reconnect delay starts at the initial value
2776cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // next time the radio comes on
2777cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2778cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mReregisterOnReconnectFailure = false;
2779cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
27807e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C        // Clear auto attach as modem is expected to do a new attach
27817e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C        mAutoAttachOnCreation.set(false);
27827e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C
2783cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
2784cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
2785cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
2786cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("We're on the simulator; assuming radio off is meaningless");
2787cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2788cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRadioOffOrNotAvailable: is off and clean up all connections");
2789cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpAllConnections(false, Phone.REASON_RADIO_TURNED_OFF);
2790cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2791cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyOffApnsOfAvailability(null);
2792cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2793cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
27941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void completeConnection(ApnContext apnContext) {
2795c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2796c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (DBG) log("completeConnection: successful, notify the world apnContext=" + apnContext);
2797c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2798c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (mIsProvisioning && !TextUtils.isEmpty(mProvisioningUrl)) {
2799c9b81a0c05128694c617fcdd67e73821895822feWink Saville            if (DBG) {
2800c9b81a0c05128694c617fcdd67e73821895822feWink Saville                log("completeConnection: MOBILE_PROVISIONING_ACTION url="
2801c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        + mProvisioningUrl);
2802c9b81a0c05128694c617fcdd67e73821895822feWink Saville            }
2803c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt            Intent newIntent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN,
2804c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt                    Intent.CATEGORY_APP_BROWSER);
2805c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt            newIntent.setData(Uri.parse(mProvisioningUrl));
2806c9b81a0c05128694c617fcdd67e73821895822feWink Saville            newIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
2807c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    Intent.FLAG_ACTIVITY_NEW_TASK);
2808c9b81a0c05128694c617fcdd67e73821895822feWink Saville            try {
2809c9b81a0c05128694c617fcdd67e73821895822feWink Saville                mPhone.getContext().startActivity(newIntent);
2810c9b81a0c05128694c617fcdd67e73821895822feWink Saville            } catch (ActivityNotFoundException e) {
2811c9b81a0c05128694c617fcdd67e73821895822feWink Saville                loge("completeConnection: startActivityAsUser failed" + e);
2812c9b81a0c05128694c617fcdd67e73821895822feWink Saville            }
2813c9b81a0c05128694c617fcdd67e73821895822feWink Saville        }
2814c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mIsProvisioning = false;
2815c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mProvisioningUrl = null;
28162b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        if (mProvisioningSpinner != null) {
28172b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            sendMessage(obtainMessage(DctConstants.CMD_CLEAR_PROVISIONING_SPINNER,
28182b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner));
28192b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        }
2820c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2821c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
2822c9b81a0c05128694c617fcdd67e73821895822feWink Saville        startNetStatPoll();
2823c9b81a0c05128694c617fcdd67e73821895822feWink Saville        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
2824c9b81a0c05128694c617fcdd67e73821895822feWink Saville    }
2825c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2826ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
2827ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * A SETUP (aka bringUp) has completed, possibly with an error. If
2828ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * there is an error this method will call {@link #onDataSetupCompleteError}.
2829ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
28301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataSetupComplete(AsyncResult ar) {
2831608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt
2832ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        DcFailCause cause = DcFailCause.UNKNOWN;
2833cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean handleError = false;
2834ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDataSetupComplete");
2835cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2836ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
2837cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2838cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (ar.exception == null) {
2839454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = apnContext.getDcAc();
2840cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2841cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (RADIO_TESTS) {
2842cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Note: To change radio.test.onDSC.null.dcac from command line you need to
2843cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // adb root and adb remount and from the command line you can only change the
2844cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // value to 1 once. To change it a second time you can reboot or execute
2845cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // adb shell stop and then adb shell start. The command line to set the value is:
2846ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink 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');"
2847cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ContentResolver cr = mPhone.getContext().getContentResolver();
2848cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                String radioTestProperty = "radio.test.onDSC.null.dcac";
2849cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (Settings.System.getInt(cr, radioTestProperty, 0) == 1) {
2850cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: " + radioTestProperty +
2851cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            " is true, set dcac to null and reset property to false");
2852cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    dcac = null;
2853cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    Settings.System.putInt(cr, radioTestProperty, 0);
2854cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: " + radioTestProperty + "=" +
2855cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            Settings.System.getInt(mPhone.getContext().getContentResolver(),
2856cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                    radioTestProperty, -1));
2857cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2858c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2859cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac == null) {
2860cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("onDataSetupComplete: no connection to DC, handle as error");
2861ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                cause = DcFailCause.CONNECTION_TO_DATACONNECTIONAC_BROKEN;
2862cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                handleError = true;
2863cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
2864cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ApnSetting apn = apnContext.getApnSetting();
2865cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
2866cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: success apn=" + (apn == null ? "unknown" : apn.apn));
2867cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2868cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn != null && apn.proxy != null && apn.proxy.length() != 0) {
2869cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    try {
2870cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        String port = apn.port;
2871cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (TextUtils.isEmpty(port)) port = "8080";
28729c180aedfc9f0d20525c0128487d3500e6c0a715Jason Monk                        ProxyInfo proxy = new ProxyInfo(apn.proxy,
2873cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                Integer.parseInt(port), null);
2874cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        dcac.setLinkPropertiesHttpProxySync(proxy);
2875cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    } catch (NumberFormatException e) {
2876cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        loge("onDataSetupComplete: NumberFormatException making ProxyProperties (" +
2877cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                apn.port + "): " + e);
2878cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2879cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2880cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2881cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // everything is setup
2882d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                if (TextUtils.equals(apnContext.getApnType(), PhoneConstants.APN_TYPE_DEFAULT)) {
288327b650c406018355a88a41528db7859e232728a0Jack Yu                    try {
288427b650c406018355a88a41528db7859e232728a0Jack Yu                        SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "true");
288527b650c406018355a88a41528db7859e232728a0Jack Yu                    } catch (RuntimeException ex) {
288627b650c406018355a88a41528db7859e232728a0Jack Yu                        log("Failed to set PUPPET_MASTER_RADIO_STRESS_TEST to true");
288727b650c406018355a88a41528db7859e232728a0Jack Yu                    }
288822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mCanSetPreferApn && mPreferredApn == null) {
28890e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                        if (DBG) log("onDataSetupComplete: PREFERRED APN is null");
2890cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mPreferredApn = apn;
2891cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (mPreferredApn != null) {
2892cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            setPreferredApn(mPreferredApn.id);
2893cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
2894cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2895cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
289627b650c406018355a88a41528db7859e232728a0Jack Yu                    try {
289727b650c406018355a88a41528db7859e232728a0Jack Yu                        SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
289827b650c406018355a88a41528db7859e232728a0Jack Yu                    } catch (RuntimeException ex) {
289927b650c406018355a88a41528db7859e232728a0Jack Yu                        log("Failed to set PUPPET_MASTER_RADIO_STRESS_TEST to false");
290027b650c406018355a88a41528db7859e232728a0Jack Yu                    }
2901cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2902c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2903c9b81a0c05128694c617fcdd67e73821895822feWink Saville                // A connection is setup
2904c9b81a0c05128694c617fcdd67e73821895822feWink Saville                apnContext.setState(DctConstants.State.CONNECTED);
29050e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
2906d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                checkDataRoamingStatus(false);
2907d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen
2908c9b81a0c05128694c617fcdd67e73821895822feWink Saville                boolean isProvApn = apnContext.isProvisioningApn();
2909b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                final ConnectivityManager cm = ConnectivityManager.from(mPhone.getContext());
2910b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                if (mProvisionBroadcastReceiver != null) {
2911b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mPhone.getContext().unregisterReceiver(mProvisionBroadcastReceiver);
2912b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mProvisionBroadcastReceiver = null;
2913b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                }
2914c9b81a0c05128694c617fcdd67e73821895822feWink Saville                if ((!isProvApn) || mIsProvisioning) {
2915b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // Hide any provisioning notification.
2916b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    cm.setProvisioningNotificationVisible(false, ConnectivityManager.TYPE_MOBILE,
2917b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                            mProvisionActionName);
2918c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // Complete the connection normally notifying the world we're connected.
2919c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // We do this if this isn't a special provisioning apn or if we've been
2920c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // told its time to provision.
2921c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    completeConnection(apnContext);
2922c9b81a0c05128694c617fcdd67e73821895822feWink Saville                } else {
2923c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // This is a provisioning APN that we're reporting as connected. Later
2924c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // when the user desires to upgrade this to a "default" connection,
2925c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // mIsProvisioning == true, we'll go through the code path above.
2926c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // mIsProvisioning becomes true when CMD_ENABLE_MOBILE_PROVISIONING
2927c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // is sent to the DCT.
2928c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    if (DBG) {
2929c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        log("onDataSetupComplete: successful, BUT send connected to prov apn as"
2930c9b81a0c05128694c617fcdd67e73821895822feWink Saville                                + " mIsProvisioning:" + mIsProvisioning + " == false"
2931c9b81a0c05128694c617fcdd67e73821895822feWink Saville                                + " && (isProvisioningApn:" + isProvApn + " == true");
2932c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    }
2933c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2934b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // While radio is up, grab provisioning URL.  The URL contains ICCID which
2935b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // disappears when radio is off.
2936b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mProvisionBroadcastReceiver = new ProvisionNotificationBroadcastReceiver(
29372b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                            cm.getMobileProvisioningUrl(),
29382b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                            TelephonyManager.getDefault().getNetworkOperatorName());
2939b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mPhone.getContext().registerReceiver(mProvisionBroadcastReceiver,
2940b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                            new IntentFilter(mProvisionActionName));
2941b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // Put up user notification that sign-in is required.
2942b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    cm.setProvisioningNotificationVisible(true, ConnectivityManager.TYPE_MOBILE,
2943b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                            mProvisionActionName);
2944b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // Turn off radio to save battery and avoid wasting carrier resources.
2945b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // The network isn't usable and network validation will just fail anyhow.
2946b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    setRadio(false);
2947c9b81a0c05128694c617fcdd67e73821895822feWink Saville                }
2948c9b81a0c05128694c617fcdd67e73821895822feWink Saville                if (DBG) {
2949c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    log("onDataSetupComplete: SETUP complete type=" + apnContext.getApnType()
2950c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        + ", reason:" + apnContext.getReason());
2951c9b81a0c05128694c617fcdd67e73821895822feWink Saville                }
29524c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                if (Build.IS_DEBUGGABLE) {
29534c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                    // adb shell setprop persist.radio.test.pco [pco_val]
29544c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                    String radioTestProperty = "persist.radio.test.pco";
2955cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    int pcoVal = SystemProperties.getInt(radioTestProperty, -1);
2956cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    if (pcoVal != -1) {
2957cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        log("PCO testing: read pco value from persist.radio.test.pco " + pcoVal);
2958cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        final byte[] value = new byte[1];
2959cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        value[0] = (byte) pcoVal;
2960cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        final Intent intent =
2961cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                                new Intent(TelephonyIntents.ACTION_CARRIER_SIGNAL_PCO_VALUE);
2962cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        intent.putExtra(TelephonyIntents.EXTRA_APN_TYPE_KEY, "default");
2963cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        intent.putExtra(TelephonyIntents.EXTRA_APN_PROTO_KEY, "IPV4V6");
2964cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        intent.putExtra(TelephonyIntents.EXTRA_PCO_ID_KEY, 0xFF00);
2965cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        intent.putExtra(TelephonyIntents.EXTRA_PCO_VALUE_KEY, value);
2966cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
2967cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    }
29684c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                }
2969c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2970cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2971ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            cause = (DcFailCause) (ar.result);
2972cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
2973cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ApnSetting apn = apnContext.getApnSetting();
2974cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log(String.format("onDataSetupComplete: error apn=%s cause=%s",
2975cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        (apn == null ? "unknown" : apn.apn), cause));
2976c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2977cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cause.isEventLoggable()) {
2978cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Log this failure to the Event Logs.
2979cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                int cid = getCellLocationId();
2980cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                EventLog.writeEvent(EventLogTags.PDP_SETUP_FAIL,
2981cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        cause.ordinal(), cid, TelephonyManager.getDefault().getNetworkType());
2982c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
29830742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela            ApnSetting apn = apnContext.getApnSetting();
29840742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela            mPhone.notifyPreciseDataConnectionFailed(apnContext.getReason(),
29850742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela                    apnContext.getApnType(), apn != null ? apn.apn : "unknown", cause.toString());
2986cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
29874c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            // Compose broadcast intent send to the specific carrier signaling receivers
29884c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            Intent intent = new Intent(TelephonyIntents
29894c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                    .ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED);
29904c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            intent.putExtra(TelephonyIntents.EXTRA_ERROR_CODE_KEY, cause.getErrorCode());
29914c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            intent.putExtra(TelephonyIntents.EXTRA_APN_TYPE_KEY, apnContext.getApnType());
29924c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
2993a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
299431f84bf1a4f1c945f7ca4646095ef4717a261c98Jordan Liu            if (cause.isRestartRadioFail(mPhone.getContext(), mPhone.getSubId()) ||
299531f84bf1a4f1c945f7ca4646095ef4717a261c98Jordan Liu                    apnContext.restartOnError(cause.getErrorCode())) {
29960e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                if (DBG) log("Modem restarted.");
29970e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                sendRestartRadio();
29980e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            }
2999cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
30000e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // If the data call failure cause is a permanent failure, we mark the APN as permanent
30010e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // failed.
3002ccfe5ebaf81c1378e8dbe44e45df26b0dc462a21Jack Yu            if (isPermanentFailure(cause)) {
30030e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                log("cause = " + cause + ", mark apn as permanent failed. apn = " + apn);
30040e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                apnContext.markApnPermanentFailed(apn);
3005c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
30060e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
3007cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            handleError = true;
3008cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3009cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3010cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (handleError) {
3011ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            onDataSetupCompleteError(ar);
3012ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
3013a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3014a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        /* If flag is set to false after SETUP_DATA_CALL is invoked, we need
3015a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         * to clean data connections.
3016a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         */
3017a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        if (!mDataEnabledSettings.isInternalDataEnabled()) {
30184fdc57b9bf223c908474c4545cc6f63456117a3bSanket Padawe            cleanUpAllConnections(Phone.REASON_DATA_DISABLED);
3019a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
3020a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3021ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
3022cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3023ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
3024ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt     * check for obsolete messages.  Return ApnContext if valid, null if not
3025ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt     */
3026ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt    private ApnContext getValidApnContext(AsyncResult ar, String logString) {
3027ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (ar != null && ar.userObj instanceof Pair) {
3028ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            Pair<ApnContext, Integer>pair = (Pair<ApnContext, Integer>)ar.userObj;
3029ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            ApnContext apnContext = pair.first;
3030ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            if (apnContext != null) {
30311a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                final int generation = apnContext.getConnectionGeneration();
30321a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                if (DBG) {
30331a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                    log("getValidApnContext (" + logString + ") on " + apnContext + " got " +
30341a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                            generation + " vs " + pair.second);
30351a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                }
30361a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                if (generation == pair.second) {
3037ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                    return apnContext;
3038ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                } else {
3039ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                    log("ignoring obsolete " + logString);
3040ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                    return null;
3041ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                }
3042ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            }
3043ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        }
3044ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        throw new RuntimeException(logString + ": No apnContext");
3045ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt    }
3046ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt
3047ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt    /**
3048ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Error has occurred during the SETUP {aka bringUP} request and the DCT
3049ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * should either try the next waiting APN or start over from the
3050ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * beginning if the list is empty. Between each SETUP request there will
3051ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville     * be a delay defined by {@link #getApnDelay()}.
3052ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
30531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataSetupCompleteError(AsyncResult ar) {
30540e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
3055ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDataSetupCompleteError");
3056ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3057ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
3058ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
30590e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        long delay = apnContext.getDelayForNextApn(mFailFast);
3060ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
30610e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        // Check if we need to retry or not.
30620852a954be5937a1b0bca94df0c2007d7ee3c0c7Jack Yu        if (delay >= 0) {
30630e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (DBG) log("onDataSetupCompleteError: Try next APN. delay = " + delay);
3064ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext.setState(DctConstants.State.SCANNING);
3065ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // Wait a bit before trying the next APN, so that
3066ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // we're not tying up the RIL command channel
30670e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            startAlarmForReconnect(delay, apnContext);
30680e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        } else {
30690e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // If we are not going to retry any APN, set this APN context to failed state.
30700e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // This would be the final state of a data connection.
30710e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            apnContext.setState(DctConstants.State.FAILED);
30720e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType());
30730e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            apnContext.setDataConnectionAc(null);
30740e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            log("onDataSetupCompleteError: Stop retrying APNs.");
3075c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3076c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3077c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3078c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
3079a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu     * Called when EVENT_REDIRECTION_DETECTED is received.
3080a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu     */
30814c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu    private void onDataConnectionRedirected(String redirectUrl) {
3082a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        if (!TextUtils.isEmpty(redirectUrl)) {
30834c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            Intent intent = new Intent(TelephonyIntents.ACTION_CARRIER_SIGNAL_REDIRECTED);
30844c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            intent.putExtra(TelephonyIntents.EXTRA_REDIRECTION_URL_KEY, redirectUrl);
30856a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu            mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
30866a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu            log("Notify carrier signal receivers with redirectUrl: " + redirectUrl);
3087a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        }
3088a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    }
3089a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
3090a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    /**
3091cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Called when EVENT_DISCONNECT_DONE is received.
3092c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
30931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDisconnectDone(AsyncResult ar) {
3094ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDisconnectDone");
3095ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
3096c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3097cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE apnContext=" + apnContext);
3098cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setState(DctConstants.State.IDLE);
3099cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3100cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
3101cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3102cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // if all data connection are gone, check whether Airplane mode request was
3103cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // pending.
3104cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isDisconnected()) {
3105cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPhone.getServiceStateTracker().processPendingRadioPowerOffAfterDataOff()) {
3106a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                if (DBG) log("onDisconnectDone: radio will be turned off, no retries");
3107cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Radio will be turned off. No need to retry data setup
3108cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setApnSetting(null);
3109cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setDataConnectionAc(null);
3110a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3111a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // Need to notify disconnect as well, in the case of switching Airplane mode.
3112a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // Otherwise, it would cause 30s delayed to turn on Airplane mode.
31130e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                if (mDisconnectPendingCount > 0) {
3114a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mDisconnectPendingCount--;
31150e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                }
3116a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3117a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mDisconnectPendingCount == 0) {
3118a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    notifyDataDisconnectComplete();
3119a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    notifyAllDataDisconnected();
3120a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
3121cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return;
3122cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3123c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3124cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // If APN is still enabled, try to bring it back up automatically
31253fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (mAttached.get() && apnContext.isReady() && retryAfterDisconnected(apnContext)) {
312627b650c406018355a88a41528db7859e232728a0Jack Yu            try {
312727b650c406018355a88a41528db7859e232728a0Jack Yu                SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
312827b650c406018355a88a41528db7859e232728a0Jack Yu            } catch (RuntimeException ex) {
312927b650c406018355a88a41528db7859e232728a0Jack Yu                log("Failed to set PUPPET_MASTER_RADIO_STRESS_TEST to false");
313027b650c406018355a88a41528db7859e232728a0Jack Yu            }
3131cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Wait a bit before trying the next APN, so that
3132cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // we're not tying up the RIL command channel.
3133cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // This also helps in any external dependency to turn off the context.
31340e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (DBG) log("onDisconnectDone: attached, ready and retry after disconnect");
3135da21f0de2087657b20b18817b33d59778720bffbJack Yu            long delay = apnContext.getRetryAfterDisconnectDelay();
31360e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (delay > 0) {
31370e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                // Data connection is in IDLE state, so when we reconnect later, we'll rebuild
31380e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                // the waiting APN list, which will also reset/reconfigure the retry manager.
31390e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                startAlarmForReconnect(delay, apnContext);
31400e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            }
3141c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
3142449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            boolean restartRadioAfterProvisioning = mPhone.getContext().getResources().getBoolean(
3143449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                    com.android.internal.R.bool.config_restartRadioAfterProvisioning);
3144449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville
3145449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            if (apnContext.isProvisioningApn() && restartRadioAfterProvisioning) {
3146449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                log("onDisconnectDone: restartRadio after provisioning");
3147449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                restartRadio();
3148449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            }
3149cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setApnSetting(null);
3150cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setDataConnectionAc(null);
31513fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())) {
3152449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                if(DBG) log("onDisconnectDone: isOnlySigneDcAllowed true so setup single apn");
31533fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                setupDataOnConnectableApns(Phone.REASON_SINGLE_PDN_ARBITRATION);
3154449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            } else {
3155449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                if(DBG) log("onDisconnectDone: not retrying");
31563fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
3157c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3158a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3159a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mDisconnectPendingCount > 0)
3160a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mDisconnectPendingCount--;
3161a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3162a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mDisconnectPendingCount == 0) {
3163c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt            apnContext.setConcurrentVoiceAndDataAllowed(
3164c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed());
3165a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyDataDisconnectComplete();
3166a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
3167a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
3168a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3169c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3170c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3171ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
3172ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Called when EVENT_DISCONNECT_DC_RETRYING is received.
3173ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
31741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDisconnectDcRetrying(AsyncResult ar) {
3175ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // We could just do this in DC!!!
3176ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDisconnectDcRetrying");
3177ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
3178ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3179ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setState(DctConstants.State.RETRYING);
3180ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if(DBG) log("onDisconnectDcRetrying: apnContext=" + apnContext);
3181ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3182ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
3183ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
3184ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
31851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onVoiceCallStarted() {
3186cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onVoiceCallStarted");
3187ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        mInVoiceCall = true;
3188cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnected() && ! mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
3189cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onVoiceCallStarted stop polling");
3190cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            stopNetStatPoll();
3191cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            stopDataStallAlarm();
3192cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
3193c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3194c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3195c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
31961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onVoiceCallEnded() {
3197cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onVoiceCallEnded");
3198ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        mInVoiceCall = false;
3199cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnected()) {
3200cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
3201cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                startNetStatPoll();
3202cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
3203cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
3204cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
3205cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // clean slate after call end.
3206cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                resetPollStats();
3207c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3208c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3209bda761320929f714951c328bfec6a51a1978db97Wink Saville        // reset reconnect timer
3210bda761320929f714951c328bfec6a51a1978db97Wink Saville        setupDataOnConnectableApns(Phone.REASON_VOICE_CALL_ENDED);
3211c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3212c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onCleanUpConnection(boolean tearDown, int apnId, String reason) {
3214cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onCleanUpConnection");
3215af5593594070f825032be46dced573cd195956e1Robert Greenwalt        ApnContext apnContext = mApnContextsById.get(apnId);
3216cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
3217cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setReason(reason);
3218cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpConnection(tearDown, apnContext);
3219c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3220c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3221c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean isConnected() {
3223cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
3224ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getState() == DctConstants.State.CONNECTED) {
3225cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // At least one context is connected, return true
3226cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return true;
3227c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3228c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3229cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // There are not any contexts connected, return false
3230cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return false;
3231c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3232c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3233cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isDisconnected() {
3234cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
3235cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!apnContext.isDisconnected()) {
3236cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // At least one context was not disconnected return false
3237cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
3238cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3239c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3240cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // All contexts were disconnected so return true
3241cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
3242c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3243c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyDataConnection(String reason) {
3245cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("notifyDataConnection: reason=" + reason);
3246cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
3247187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (mAttached.get() && apnContext.isReady()) {
3248187a39f896f88eb6c5e4306d9595546654825976Wink Saville                if (DBG) log("notifyDataConnection: type:" + apnContext.getApnType());
3249cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
3250cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.getApnType());
3251cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3252c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3253cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyOffApnsOfAvailability(reason);
3254c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3255c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void setDataProfilesAsNeeded() {
32571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("setDataProfilesAsNeeded");
32581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mAllApnSettings != null && !mAllApnSettings.isEmpty()) {
32591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            ArrayList<DataProfile> dps = new ArrayList<DataProfile>();
32601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (ApnSetting apn : mAllApnSettings) {
32611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (apn.modemCognitive) {
3262886183cde1263ea524cdf08524442724e246ed42Jack Yu                    DataProfile dp = createDataProfile(apn);
32638e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                    if (!dps.contains(dp)) {
32641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        dps.add(dp);
32651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
32661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
32671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
32688e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu            if (dps.size() > 0) {
326971f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                mDataServiceManager.setDataProfile(dps,
3270cc40713c49908aeaac0070bf4ea796247f9066b5Jack Yu                        mPhone.getServiceState().getDataRoamingFromRegistration(), null);
32711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
32721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
32731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
32741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3275c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
3276cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Based on the sim operator numeric, create a list for all possible
3277cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Data Connections and setup the preferredApn.
3278c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
3279cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void createAllApnList() {
32801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mMvnoMatched = false;
32818e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu        mAllApnSettings = new ArrayList<>();
3282cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
3283cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String operator = (r != null) ? r.getOperatorNumeric() : "";
3284cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (operator != null) {
32853c89e23cf33c3c7f795554b29cd926219f28fe34Sungmin Choi            String selection = Telephony.Carriers.NUMERIC + " = '" + operator + "'";
3286cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // query only enabled apn.
3287cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // carrier_enabled : 1 means enabled apn, 0 disabled apn.
32889d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan            // selection += " and carrier_enabled = 1";
3289cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: selection=" + selection);
3290cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
32913c89e23cf33c3c7f795554b29cd926219f28fe34Sungmin Choi            // ORDER BY Telephony.Carriers._ID ("_id")
3292cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            Cursor cursor = mPhone.getContext().getContentResolver().query(
3293030fdfb7ccdf5dce9a6b48ca07918082627200f4yuemingw                    Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "filtered"),
3294030fdfb7ccdf5dce9a6b48ca07918082627200f4yuemingw                    null, selection, null, Telephony.Carriers._ID);
3295cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3296cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cursor != null) {
3297cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (cursor.getCount() > 0) {
3298ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    mAllApnSettings = createApnList(cursor);
3299cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3300cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cursor.close();
3301cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3302c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3303c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
330476f43316a5a6082d601bffd4b6898d0bd81e11fcram        addEmergencyApnSetting();
330576f43316a5a6082d601bffd4b6898d0bd81e11fcram
330629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        dedupeApnSettings();
330729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
3308ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings.isEmpty()) {
3309cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: No APN found for carrier: " + operator);
3310cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPreferredApn = null;
3311ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // TODO: What is the right behavior?
3312cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            //notifyNoData(DataConnection.FailCause.MISSING_UNKNOWN_APN);
3313c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
3314cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPreferredApn = getPreferredApn();
3315cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator)) {
3316cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn = null;
3317cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                setPreferredApn(-1);
3318cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3319cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: mPreferredApn=" + mPreferredApn);
3320c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3321ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("createAllApnList: X mAllApnSettings=" + mAllApnSettings);
33229d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan
33239d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        setDataProfilesAsNeeded();
3324c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3325c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
332629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    private void dedupeApnSettings() {
332729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        ArrayList<ApnSetting> resultApns = new ArrayList<ApnSetting>();
332829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
332929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        // coalesce APNs if they are similar enough to prevent
333029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        // us from bringing up two data calls with the same interface
333129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        int i = 0;
333229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        while (i < mAllApnSettings.size() - 1) {
333329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            ApnSetting first = mAllApnSettings.get(i);
333429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            ApnSetting second = null;
333529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            int j = i + 1;
333629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            while (j < mAllApnSettings.size()) {
333729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                second = mAllApnSettings.get(j);
33389fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                if (first.similar(second)) {
333929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    ApnSetting newApn = mergeApns(first, second);
334029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    mAllApnSettings.set(i, newApn);
334129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    first = newApn;
334229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    mAllApnSettings.remove(j);
334329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                } else {
334429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    j++;
334529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                }
334629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            }
334729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            i++;
334829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        }
334929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    }
335029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
335129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    private ApnSetting mergeApns(ApnSetting dest, ApnSetting src) {
3352bca51fc3a191d3ca30df627b75374db0941571c5Sungmin Choi        int id = dest.id;
335329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        ArrayList<String> resultTypes = new ArrayList<String>();
335429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        resultTypes.addAll(Arrays.asList(dest.types));
335529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        for (String srcType : src.types) {
335629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            if (resultTypes.contains(srcType) == false) resultTypes.add(srcType);
3357bca51fc3a191d3ca30df627b75374db0941571c5Sungmin Choi            if (srcType.equals(PhoneConstants.APN_TYPE_DEFAULT)) id = src.id;
335829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        }
335929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        String mmsc = (TextUtils.isEmpty(dest.mmsc) ? src.mmsc : dest.mmsc);
336029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        String mmsProxy = (TextUtils.isEmpty(dest.mmsProxy) ? src.mmsProxy : dest.mmsProxy);
336129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        String mmsPort = (TextUtils.isEmpty(dest.mmsPort) ? src.mmsPort : dest.mmsPort);
336261cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String proxy = (TextUtils.isEmpty(dest.proxy) ? src.proxy : dest.proxy);
336361cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String port = (TextUtils.isEmpty(dest.port) ? src.port : dest.port);
336461cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String protocol = src.protocol.equals("IPV4V6") ? src.protocol : dest.protocol;
336561cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String roamingProtocol = src.roamingProtocol.equals("IPV4V6") ? src.roamingProtocol :
336661cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                dest.roamingProtocol;
3367176f28521fd45bb739709d309e7970b1558c9f61Cassie        int networkTypeBitmask = (dest.networkTypeBitmask == 0 || src.networkTypeBitmask == 0)
3368176f28521fd45bb739709d309e7970b1558c9f61Cassie                ? 0 : (dest.networkTypeBitmask | src.networkTypeBitmask);
3369176f28521fd45bb739709d309e7970b1558c9f61Cassie        if (networkTypeBitmask == 0) {
3370176f28521fd45bb739709d309e7970b1558c9f61Cassie            int bearerBitmask = (dest.bearerBitmask == 0 || src.bearerBitmask == 0)
3371176f28521fd45bb739709d309e7970b1558c9f61Cassie                    ? 0 : (dest.bearerBitmask | src.bearerBitmask);
3372176f28521fd45bb739709d309e7970b1558c9f61Cassie            networkTypeBitmask = ServiceState.convertBearerBitmaskToNetworkTypeBitmask(
3373176f28521fd45bb739709d309e7970b1558c9f61Cassie                    bearerBitmask);
3374176f28521fd45bb739709d309e7970b1558c9f61Cassie        }
337529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
3376bca51fc3a191d3ca30df627b75374db0941571c5Sungmin Choi        return new ApnSetting(id, dest.numeric, dest.carrier, dest.apn,
337761cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                proxy, port, mmsc, mmsProxy, mmsPort, dest.user, dest.password,
337861cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                dest.authType, resultTypes.toArray(new String[0]), protocol,
3379176f28521fd45bb739709d309e7970b1558c9f61Cassie                roamingProtocol, dest.carrierEnabled, networkTypeBitmask, dest.profileId,
338029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                (dest.modemCognitive || src.modemCognitive), dest.maxConns, dest.waitTime,
338129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                dest.maxConnsTime, dest.mtu, dest.mvnoType, dest.mvnoMatchData);
338229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    }
338329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
3384ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /** Return the DC AsyncChannel for the new data connection */
3385454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel createDataConnection() {
3386cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createDataConnection E");
3387cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3388cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int id = mUniqueIdGenerator.getAndIncrement();
338971f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        DataConnection conn = DataConnection.makeDataConnection(mPhone, id, this,
339071f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                mDataServiceManager, mDcTesterFailBringUpAll, mDcc);
3391cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mDataConnections.put(id, conn);
3392454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac = new DcAsyncChannel(conn, LOG_TAG);
3393cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int status = dcac.fullyConnectSync(mPhone.getContext(), this, conn.getHandler());
3394cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (status == AsyncChannel.STATUS_SUCCESSFUL) {
3395ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            mDataConnectionAcHashMap.put(dcac.getDataConnectionIdSync(), dcac);
3396c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
3397ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            loge("createDataConnection: Could not connect to dcac=" + dcac + " status=" + status);
3398c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3399cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3400cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createDataConnection() X id=" + id + " dc=" + conn);
3401ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        return dcac;
3402c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3403c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3404cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void destroyDataConnections() {
3405cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(mDataConnections != null) {
3406cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("destroyDataConnections: clear mDataConnectionList");
3407cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mDataConnections.clear();
3408cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
3409cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("destroyDataConnections: mDataConnecitonList is empty, ignore");
3410c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3411c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3412c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3413c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
3414cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Build a list of APNs to be used to create PDP's.
3415c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
3416cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param requestedApnType
3417cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return waitingApns list to be used to create PDP
3418cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *          error when waitingApns.isEmpty()
3419c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
3420203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    private ArrayList<ApnSetting> buildWaitingApns(String requestedApnType, int radioTech) {
3421cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("buildWaitingApns: E requestedApnType=" + requestedApnType);
3422cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ArrayList<ApnSetting> apnList = new ArrayList<ApnSetting>();
3423cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3424cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (requestedApnType.equals(PhoneConstants.APN_TYPE_DUN)) {
3425cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ApnSetting dun = fetchDunApn();
3426cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dun != null) {
3427cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnList.add(dun);
3428cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: X added APN_TYPE_DUN apnList=" + apnList);
3429cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return apnList;
3430c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3431c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3432c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3433cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
3434cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String operator = (r != null) ? r.getOperatorNumeric() : "";
3435c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3436cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // This is a workaround for a bug (7305641) where we don't failover to other
3437cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // suitable APNs if our preferred APN fails.  On prepaid ATT sims we need to
3438cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // failover to a provisioning APN, but once we've used their default data
3439cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // connection we are locked to it for life.  This change allows ATT devices
3440cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // to say they don't want to use preferred at all.
3441cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean usePreferred = true;
3442cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        try {
3443cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            usePreferred = ! mPhone.getContext().getResources().getBoolean(com.android.
3444cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    internal.R.bool.config_dontPreferApn);
3445cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } catch (Resources.NotFoundException e) {
3446cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("buildWaitingApns: usePreferred NotFoundException set to true");
3447cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            usePreferred = true;
3448cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3449bf660a4647db8151609cdfa0ecc4c96e1518947fSungmin Choi        if (usePreferred) {
3450bf660a4647db8151609cdfa0ecc4c96e1518947fSungmin Choi            mPreferredApn = getPreferredApn();
3451bf660a4647db8151609cdfa0ecc4c96e1518947fSungmin Choi        }
3452cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
3453cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("buildWaitingApns: usePreferred=" + usePreferred
345422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    + " canSetPreferApn=" + mCanSetPreferApn
3455cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " mPreferredApn=" + mPreferredApn
3456cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " operator=" + operator + " radioTech=" + radioTech
3457cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " IccRecords r=" + r);
3458cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3459c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
346022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (usePreferred && mCanSetPreferApn && mPreferredApn != null &&
3461cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn.canHandleType(requestedApnType)) {
3462cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
3463cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("buildWaitingApns: Preferred APN:" + operator + ":"
3464cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        + mPreferredApn.numeric + ":" + mPreferredApn);
3465cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3466cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPreferredApn.numeric.equals(operator)) {
3467176f28521fd45bb739709d309e7970b1558c9f61Cassie                if (ServiceState.bitmaskHasTech(mPreferredApn.networkTypeBitmask,
3468176f28521fd45bb739709d309e7970b1558c9f61Cassie                        ServiceState.rilRadioTechnologyToNetworkType(radioTech))) {
3469cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnList.add(mPreferredApn);
3470cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
3471cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return apnList;
3472cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
3473cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("buildWaitingApns: no preferred APN");
3474cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    setPreferredApn(-1);
3475cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mPreferredApn = null;
3476c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
3477cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
3478cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: no preferred APN");
3479cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                setPreferredApn(-1);
3480cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn = null;
3481c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3482c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3483ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings != null) {
3484ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (DBG) log("buildWaitingApns: mAllApnSettings=" + mAllApnSettings);
3485ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for (ApnSetting apn : mAllApnSettings) {
3486cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn.canHandleType(requestedApnType)) {
3487176f28521fd45bb739709d309e7970b1558c9f61Cassie                    if (ServiceState.bitmaskHasTech(apn.networkTypeBitmask,
3488176f28521fd45bb739709d309e7970b1558c9f61Cassie                            ServiceState.rilRadioTechnologyToNetworkType(radioTech))) {
34899232dafa7ea833fc0b3a6024d6c7e23fc8e961eaRobert Greenwalt                        if (DBG) log("buildWaitingApns: adding apn=" + apn);
3490cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnList.add(apn);
3491c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else {
3492cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (DBG) {
3493176f28521fd45bb739709d309e7970b1558c9f61Cassie                            log("buildWaitingApns: bearerBitmask:" + apn.bearerBitmask
3494176f28521fd45bb739709d309e7970b1558c9f61Cassie                                    + " or " + "networkTypeBitmask:" + apn.networkTypeBitmask
3495176f28521fd45bb739709d309e7970b1558c9f61Cassie                                    + "do not include radioTech:" + radioTech);
3496cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
3497c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
34989232dafa7ea833fc0b3a6024d6c7e23fc8e961eaRobert Greenwalt                } else if (DBG) {
349927b650c406018355a88a41528db7859e232728a0Jack Yu                    log("buildWaitingApns: couldn't handle requested ApnType="
3500cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            + requestedApnType);
3501c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
3502c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3503cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
35044bd0ae43eb0cb9969dee4f30cddc18a71da68190Jack Yu            loge("mAllApnSettings is null!");
3505c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
35060e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        if (DBG) log("buildWaitingApns: " + apnList.size() + " APNs in the list: " + apnList);
3507cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return apnList;
3508c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3509c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3510cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private String apnListToString (ArrayList<ApnSetting> apns) {
3511cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        StringBuilder result = new StringBuilder();
3512cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (int i = 0, size = apns.size(); i < size; i++) {
3513cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result.append('[')
3514cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                  .append(apns.get(i).toString())
3515cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                  .append(']');
3516c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3517cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result.toString();
3518c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3519c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3520cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void setPreferredApn(int pos) {
352122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (!mCanSetPreferApn) {
3522cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("setPreferredApn: X !canSEtPreferApn");
3523cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
3524cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3525cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
35266bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        String subId = Long.toString(mPhone.getSubId());
35276bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        Uri uri = Uri.withAppendedPath(PREFERAPN_NO_UPDATE_URI_USING_SUBID, subId);
3528cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("setPreferredApn: delete");
3529cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ContentResolver resolver = mPhone.getContext().getContentResolver();
35306bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        resolver.delete(uri, null, null);
3531cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3532cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (pos >= 0) {
3533cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("setPreferredApn: insert");
3534cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ContentValues values = new ContentValues();
3535cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            values.put(APN_ID, pos);
35366bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville            resolver.insert(uri, values);
3537cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3538cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
3539cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3540cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ApnSetting getPreferredApn() {
35414bd0ae43eb0cb9969dee4f30cddc18a71da68190Jack Yu        if (mAllApnSettings == null || mAllApnSettings.isEmpty()) {
35424bd0ae43eb0cb9969dee4f30cddc18a71da68190Jack Yu            log("getPreferredApn: mAllApnSettings is " + ((mAllApnSettings == null)?"null":"empty"));
3543cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return null;
3544cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3545cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
35466bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        String subId = Long.toString(mPhone.getSubId());
35476bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        Uri uri = Uri.withAppendedPath(PREFERAPN_NO_UPDATE_URI_USING_SUBID, subId);
3548cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Cursor cursor = mPhone.getContext().getContentResolver().query(
35496bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville                uri, new String[] { "_id", "name", "apn" },
3550cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
3551cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3552cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor != null) {
355322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCanSetPreferApn = true;
3554cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
355522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCanSetPreferApn = false;
3556cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3557cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("getPreferredApn: mRequestedApnType=" + mRequestedApnType + " cursor=" + cursor
3558cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                + " cursor.count=" + ((cursor != null) ? cursor.getCount() : 0));
3559cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
356022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mCanSetPreferApn && cursor.getCount() > 0) {
3561cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            int pos;
3562cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cursor.moveToFirst();
3563cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            pos = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID));
3564ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for(ApnSetting p : mAllApnSettings) {
3565cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("getPreferredApn: apnSetting=" + p);
3566cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (p.id == pos && p.canHandleType(mRequestedApnType)) {
3567cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("getPreferredApn: X found apnSetting" + p);
3568cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    cursor.close();
3569cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return p;
3570cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3571cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
3572cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3573cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3574cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor != null) {
3575cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cursor.close();
3576cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3577cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3578cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("getPreferredApn: X not found");
3579cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
3580cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
3581cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3582cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
3583cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void handleMessage (Message msg) {
35841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) log("handleMessage msg=" + msg);
3585cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3586cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        switch (msg.what) {
3587cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_RECORDS_LOADED:
35881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // If onRecordsLoadedOrSubIdChanged() is not called here, it should be called on
35891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // onSubscriptionsChanged() when a valid subId is available.
35901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                int subId = mPhone.getSubId();
35911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (SubscriptionManager.isValidSubscriptionId(subId)) {
35921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onRecordsLoadedOrSubIdChanged();
35931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
35941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("Ignoring EVENT_RECORDS_LOADED as subId is not valid: " + subId);
35951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
3596cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3597cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3598cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_CONNECTION_DETACHED:
3599cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onDataConnectionDetached();
3600cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3601cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3602cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_CONNECTION_ATTACHED:
3603bda761320929f714951c328bfec6a51a1978db97Wink Saville                onDataConnectionAttached();
3604cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3605cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3606cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DO_RECOVERY:
3607cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                doRecovery();
3608cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3609cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3610cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_APN_CHANGED:
3611cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onApnChanged();
3612cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3613cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3614cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_PS_RESTRICT_ENABLED:
3615cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                /**
3616cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * We don't need to explicitly to tear down the PDP context
3617cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * when PS restricted is enabled. The base band will deactive
3618cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * PDP context and notify us with PDP_CONTEXT_CHANGED.
3619cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * But we should stop the network polling and prevent reset PDP.
3620cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 */
3621cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
3622cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                stopNetStatPoll();
3623cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                stopDataStallAlarm();
3624cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsPsRestricted = true;
3625cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
3626cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3627cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_PS_RESTRICT_DISABLED:
3628cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                /**
3629cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * When PS restrict is removed, we need setup PDP connection if
3630cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * PDP connection is down.
3631cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 */
3632cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_PS_RESTRICT_DISABLED " + mIsPsRestricted);
3633cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsPsRestricted  = false;
3634cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (isConnected()) {
3635cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    startNetStatPoll();
3636cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
3637cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
3638cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // TODO: Should all PDN states be checked to fail?
3639ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    if (mState == DctConstants.State.FAILED) {
3640cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        cleanUpAllConnections(false, Phone.REASON_PS_RESTRICT_ENABLED);
3641cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mReregisterOnReconnectFailure = false;
3642cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
3643af5593594070f825032be46dced573cd195956e1Robert Greenwalt                    ApnContext apnContext = mApnContextsById.get(DctConstants.APN_DEFAULT_ID);
36443fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (apnContext != null) {
36453fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        apnContext.setReason(Phone.REASON_PS_RESTRICT_ENABLED);
36463fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        trySetupData(apnContext);
36473fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    } else {
36483fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        loge("**** Default ApnContext not found ****");
36493fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        if (Build.IS_DEBUGGABLE) {
36503fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                            throw new RuntimeException("Default ApnContext not found");
36513fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        }
36523fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    }
3653cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3654cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
3655ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3656cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_TRY_SETUP_DATA:
3657cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (msg.obj instanceof ApnContext) {
3658cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    onTrySetupData((ApnContext)msg.obj);
3659cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else if (msg.obj instanceof String) {
3660cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    onTrySetupData((String)msg.obj);
3661cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
3662cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    loge("EVENT_TRY_SETUP request w/o apnContext or String");
3663cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3664cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
3665cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3666cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_CLEAN_UP_CONNECTION:
3667cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                boolean tearDown = (msg.arg1 == 0) ? false : true;
3668cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_CLEAN_UP_CONNECTION tearDown=" + tearDown);
3669cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (msg.obj instanceof ApnContext) {
3670cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    cleanUpConnection(tearDown, (ApnContext)msg.obj);
3671cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
36721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onCleanUpConnection(tearDown, msg.arg2, (String) msg.obj);
3673cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3674cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
36751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE: {
36761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
3677a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                onSetInternalDataEnabled(enabled, (Message) msg.obj);
3678a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
36791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
3680a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS:
36811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if ((msg.obj != null) && (msg.obj instanceof String == false)) {
36821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    msg.obj = null;
3683a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
36841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onCleanUpAllConnections((String) msg.obj);
3685a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
3686ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3687220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville            case DctConstants.EVENT_DATA_RAT_CHANGED:
3688b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                if (mPhone.getServiceState().getRilDataRadioTechnology()
3689b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                        == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
3690b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                    // unknown rat is an exception for data rat change. It's only received when out
3691b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                    // of service and is not applicable for apn bearer bitmask. We should bypass the
3692b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                    // check of waiting apn list and keep the data connection on, and no need to
3693b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                    // setup a new one.
3694b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                    break;
3695b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                }
3696ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                cleanUpConnectionsOnUpdatedApns(false, Phone.REASON_NW_TYPE_CHANGED);
3697220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville                //May new Network allow setupData, so try it here
3698c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                setupDataOnConnectableApns(Phone.REASON_NW_TYPE_CHANGED,
3699c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                        RetryFailures.ONLY_ON_CHANGE);
3700220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville                break;
3701220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville
37022b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            case DctConstants.CMD_CLEAR_PROVISIONING_SPINNER:
37032b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                // Check message sender intended to clear the current spinner.
37042b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                if (mProvisioningSpinner == msg.obj) {
37052b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner.dismiss();
37062b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner = null;
37072b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                }
37082b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                break;
37091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
37101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("DISCONNECTED_CONNECTED: msg=" + msg);
37111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DcAsyncChannel dcac = (DcAsyncChannel) msg.obj;
37121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mDataConnectionAcHashMap.remove(dcac.getDataConnectionIdSync());
37131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                dcac.disconnected();
37141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
37161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ENABLE_NEW_APN:
37171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onEnableApn(msg.arg1, msg.arg2);
37181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_STALL_ALARM:
37211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDataStallAlarm(msg.arg1);
37221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ROAMING_OFF:
37255b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu                onDataRoamingOff();
37261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ROAMING_ON:
3729d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen            case DctConstants.EVENT_ROAMING_SETTING_CHANGE:
3730d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                onDataRoamingOnOrSettingsChanged(msg.what);
37311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3733f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            case DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE:
3734f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                onDeviceProvisionedChange();
3735f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                break;
3736f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
3737a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            case DctConstants.EVENT_REDIRECTION_DETECTED:
37384c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                String url = (String) msg.obj;
373968f4f4a0bc8d4060b5775e7a24a97ea5b485989efionaxu                log("dataConnectionTracker.handleMessage: EVENT_REDIRECTION_DETECTED=" + url);
37404c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                onDataConnectionRedirected(url);
3741a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
37421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RADIO_AVAILABLE:
37431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onRadioAvailable();
37441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
37471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onRadioOffOrNotAvailable();
37481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_SETUP_COMPLETE:
37511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDataSetupComplete((AsyncResult) msg.obj);
37521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_SETUP_COMPLETE_ERROR:
37551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDataSetupCompleteError((AsyncResult) msg.obj);
37561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
3757a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
37581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DISCONNECT_DONE:
37591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("DataConnectionTracker.handleMessage: EVENT_DISCONNECT_DONE msg=" + msg);
37601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDisconnectDone((AsyncResult) msg.obj);
37611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DISCONNECT_DC_RETRYING:
37641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("DataConnectionTracker.handleMessage: EVENT_DISCONNECT_DC_RETRYING msg=" + msg);
37651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDisconnectDcRetrying((AsyncResult) msg.obj);
37661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_VOICE_CALL_STARTED:
37691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onVoiceCallStarted();
37701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_VOICE_CALL_ENDED:
37731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onVoiceCallEnded();
37741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_USER_DATA_ENABLE: {
37761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
37771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_SET_USER_DATA_ENABLE enabled=" + enabled);
37781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onSetUserDataEnabled(enabled);
37791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
37811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // TODO - remove
37821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_DEPENDENCY_MET: {
37831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                boolean met = (msg.arg1 == DctConstants.ENABLED) ? true : false;
37841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_SET_DEPENDENCY_MET met=" + met);
37851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Bundle bundle = msg.getData();
37861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (bundle != null) {
37871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    String apnType = (String)bundle.get(DctConstants.APN_TYPE_KEY);
37881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (apnType != null) {
37891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onSetDependencyMet(apnType, met);
37901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
37911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
37921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
37941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_POLICY_DATA_ENABLE: {
37951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
37961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onSetPolicyDataEnabled(enabled);
37971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
37991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: {
38001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                sEnableFailFastRefCounter += (msg.arg1 == DctConstants.ENABLED) ? 1 : -1;
38011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
38021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: "
38031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + " sEnableFailFastRefCounter=" + sEnableFailFastRefCounter);
38041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (sEnableFailFastRefCounter < 0) {
38061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    final String s = "CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: "
38071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + "sEnableFailFastRefCounter:" + sEnableFailFastRefCounter + " < 0";
38081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge(s);
38091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    sEnableFailFastRefCounter = 0;
38101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = sEnableFailFastRefCounter > 0;
38121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
38131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: enabled=" + enabled
38141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + " sEnableFailFastRefCounter=" + sEnableFailFastRefCounter);
38151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (mFailFast != enabled) {
38171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mFailFast = enabled;
38180e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
38191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mDataStallDetectionEnabled = !enabled;
38201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mDataStallDetectionEnabled
38211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            && (getOverallState() == DctConstants.State.CONNECTED)
38221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            && (!mInVoiceCall ||
38231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    mPhone.getServiceStateTracker()
38241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                        .isConcurrentVoiceAndDataAllowed())) {
38251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: start data stall");
38261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        stopDataStallAlarm();
38271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
38281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
38291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: stop data stall");
38301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        stopDataStallAlarm();
38311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
38321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38332b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen
38341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
38361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_ENABLE_MOBILE_PROVISIONING: {
38371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Bundle bundle = msg.getData();
38381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (bundle != null) {
38391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    try {
38401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mProvisioningUrl = (String)bundle.get(DctConstants.PROVISIONING_URL_KEY);
38411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } catch(ClassCastException e) {
38421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioning url not a string" + e);
38431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mProvisioningUrl = null;
38441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
38451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (TextUtils.isEmpty(mProvisioningUrl)) {
38471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioning url is empty, ignoring");
38481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mIsProvisioning = false;
38491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mProvisioningUrl = null;
38501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
38511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioningUrl=" + mProvisioningUrl);
38521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mIsProvisioning = true;
38531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    startProvisioningApnAlarm();
38541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
38571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_PROVISIONING_APN_ALARM: {
38581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("EVENT_PROVISIONING_APN_ALARM");
3859af5593594070f825032be46dced573cd195956e1Robert Greenwalt                ApnContext apnCtx = mApnContextsById.get(DctConstants.APN_DEFAULT_ID);
38601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (apnCtx.isProvisioningApn() && apnCtx.isConnectedOrConnecting()) {
38611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mProvisioningApnAlarmTag == msg.arg1) {
38621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) log("EVENT_PROVISIONING_APN_ALARM: Disconnecting");
38631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mIsProvisioning = false;
38641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mProvisioningUrl = null;
38651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        stopProvisioningApnAlarm();
38661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        sendCleanUpConnection(true, apnCtx);
38671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
38681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) {
38691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            log("EVENT_PROVISIONING_APN_ALARM: ignore stale tag,"
38701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    + " mProvisioningApnAlarmTag:" + mProvisioningApnAlarmTag
38711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    + " != arg1:" + msg.arg1);
38721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        }
38731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
38741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
38751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (DBG) log("EVENT_PROVISIONING_APN_ALARM: Not connected ignore");
38761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
38791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_IS_PROVISIONING_APN: {
38801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_IS_PROVISIONING_APN");
38811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                boolean isProvApn;
38821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                try {
38831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    String apnType = null;
38841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    Bundle bundle = msg.getData();
38851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (bundle != null) {
38861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        apnType = (String)bundle.get(DctConstants.APN_TYPE_KEY);
38871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
38881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (TextUtils.isEmpty(apnType)) {
38891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        loge("CMD_IS_PROVISIONING_APN: apnType is empty");
38901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        isProvApn = false;
38911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
38921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        isProvApn = isProvisioningApn(apnType);
38931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
38941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } catch (ClassCastException e) {
38951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge("CMD_IS_PROVISIONING_APN: NO provisioning url ignoring");
38961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    isProvApn = false;
38971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_IS_PROVISIONING_APN: ret=" + isProvApn);
38991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mReplyAc.replyToMessage(msg, DctConstants.CMD_IS_PROVISIONING_APN,
39001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        isProvApn ? DctConstants.ENABLED : DctConstants.DISABLED);
39011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ICC_CHANGED: {
39041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onUpdateIcc();
39051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RESTART_RADIO: {
39081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartRadio();
39091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_NET_STAT_POLL: {
39121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (msg.arg1 == DctConstants.ENABLED) {
39131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    handleStartNetStatPoll((DctConstants.Activity)msg.obj);
39141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else if (msg.arg1 == DctConstants.DISABLED) {
39151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    handleStopNetStatPoll((DctConstants.Activity)msg.obj);
39161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
39171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39192e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            case DctConstants.EVENT_PCO_DATA_RECEIVED: {
39202e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt                handlePcoData((AsyncResult)msg.obj);
39212e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt                break;
39222e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            }
3923a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            case DctConstants.EVENT_SET_CARRIER_DATA_ENABLED:
39246a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu                onSetCarrierDataEnabled((AsyncResult) msg.obj);
3925a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                break;
3926e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu            case DctConstants.EVENT_DATA_RECONNECT:
3927e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                onDataReconnect(msg.getData());
3928e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                break;
392971f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu            case DctConstants.EVENT_DATA_SERVICE_BINDING_CHANGED:
393071f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                onDataServiceBindingChanged((Boolean) ((AsyncResult) msg.obj).result);
3931cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            default:
39321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Rlog.e("DcTracker", "Unhandled event=" + msg);
3933cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
39341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3935cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3936cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
3937cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
39381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int getApnProfileID(String apnType) {
3939cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IMS)) {
3940cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_IMS;
3941cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_FOTA)) {
3942cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_FOTA;
3943cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_CBS)) {
3944cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_CBS;
39451b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IA)) {
39461b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            return RILConstants.DATA_PROFILE_DEFAULT; // DEFAULT for now
394745df26444864daad60afdd4d121ab4043da3834bSungmin Choi        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_DUN)) {
394845df26444864daad60afdd4d121ab4043da3834bSungmin Choi            return RILConstants.DATA_PROFILE_TETHERED;
3949cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
3950cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_DEFAULT;
3951cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3952cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
3953cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3954cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private int getCellLocationId() {
3955cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int cid = -1;
3956cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        CellLocation loc = mPhone.getCellLocation();
3957cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3958cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (loc != null) {
3959cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (loc instanceof GsmCellLocation) {
3960cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cid = ((GsmCellLocation)loc).getCid();
3961cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else if (loc instanceof CdmaCellLocation) {
3962cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cid = ((CdmaCellLocation)loc).getBaseStationId();
3963cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
3964cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3965cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return cid;
3966cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
3967cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3968a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private IccRecords getUiccRecords(int appFamily) {
3969a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return mUiccController.getIccRecords(mPhone.getPhoneId(), appFamily);
3970a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
3971a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3972a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
39731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onUpdateIcc() {
3974cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mUiccController == null ) {
3975cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            return;
3976cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3977cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3978a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        IccRecords newIccRecords = getUiccRecords(UiccController.APP_FAM_3GPP);
3979cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3980cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
3981cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (r != newIccRecords) {
3982cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (r != null) {
3983cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("Removing stale icc objects.");
3984cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                r.unregisterForRecordsLoaded(this);
3985cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIccRecords.set(null);
39869aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan            }
3987cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (newIccRecords != null) {
39881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (SubscriptionManager.isValidSubscriptionId(mPhone.getSubId())) {
3989aa863054476b152fe9323defd197fa946a47033fSungmin Choi                    log("New records found.");
3990aa863054476b152fe9323defd197fa946a47033fSungmin Choi                    mIccRecords.set(newIccRecords);
3991aa863054476b152fe9323defd197fa946a47033fSungmin Choi                    newIccRecords.registerForRecordsLoaded(
3992aa863054476b152fe9323defd197fa946a47033fSungmin Choi                            this, DctConstants.EVENT_RECORDS_LOADED, null);
3993aa863054476b152fe9323defd197fa946a47033fSungmin Choi                }
39940469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal            } else {
39950469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal                onSimNotReady();
39969aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan            }
39979aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan        }
3998cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
3999cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4000a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void update() {
4001a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("update sub = " + mPhone.getSubId());
4002bda761320929f714951c328bfec6a51a1978db97Wink Saville        log("update(): Active DDS, register for all events now!");
4003bda761320929f714951c328bfec6a51a1978db97Wink Saville        onUpdateIcc();
4004a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
40050979b71e48405cab10bdf1d1b4170cfce72838a7Jack Yu        mAutoAttachOnCreation.set(false);
4006bda761320929f714951c328bfec6a51a1978db97Wink Saville
40071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ((GsmCdmaPhone)mPhone).updateCurrentCarrierInProvider();
4008a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4009a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4010a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void cleanUpAllConnections(String cause) {
4011a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cleanUpAllConnections(cause, null);
4012a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4013a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4014a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void updateRecords() {
4015bda761320929f714951c328bfec6a51a1978db97Wink Saville        onUpdateIcc();
4016a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4017a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4018a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void cleanUpAllConnections(String cause, Message disconnectAllCompleteMsg) {
4019a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("cleanUpAllConnections");
4020a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (disconnectAllCompleteMsg != null) {
4021a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mDisconnectAllCompleteMsgList.add(disconnectAllCompleteMsg);
4022a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4023a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4024a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Message msg = obtainMessage(DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS);
4025a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        msg.obj = cause;
4026a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sendMessage(msg);
4027a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4028a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
40291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyDataDisconnectComplete() {
4030a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("notifyDataDisconnectComplete");
4031a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        for (Message m: mDisconnectAllCompleteMsgList) {
4032a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            m.sendToTarget();
4033a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4034a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mDisconnectAllCompleteMsgList.clear();
4035a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4036a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4037a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
40381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyAllDataDisconnected() {
4039a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sEnableFailFastRefCounter = 0;
4040a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mFailFast = false;
4041a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.notifyRegistrants();
4042a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4043a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4044a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void registerForAllDataDisconnected(Handler h, int what, Object obj) {
4045a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.addUnique(h, what, obj);
4046a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4047a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (isDisconnected()) {
4048a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("notify All Data Disconnected");
4049a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
4050a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4051a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4052a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4053a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void unregisterForAllDataDisconnected(Handler h) {
4054a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.remove(h);
4055a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4056a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4057a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    public void registerForDataEnabledChanged(Handler h, int what, Object obj) {
4058a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        mDataEnabledSettings.registerForDataEnabledChanged(h, what, obj);
4059a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    }
4060a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
4061a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    public void unregisterForDataEnabledChanged(Handler h) {
4062a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        mDataEnabledSettings.unregisterForDataEnabledChanged(h);
4063a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    }
4064a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
40651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetInternalDataEnabled(boolean enabled, Message onCompleteMsg) {
4066a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        synchronized (mDataEnabledSettings) {
4067a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            if (DBG) log("onSetInternalDataEnabled: enabled=" + enabled);
4068a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            boolean sendOnComplete = true;
4069a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4070a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            mDataEnabledSettings.setInternalDataEnabled(enabled);
4071a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (enabled) {
4072a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("onSetInternalDataEnabled: changed to enabled, try to setup data call");
4073a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                onTrySetupData(Phone.REASON_DATA_ENABLED);
4074a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
4075a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                sendOnComplete = false;
4076a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("onSetInternalDataEnabled: changed to disabled, cleanUpAllConnections");
40774fdc57b9bf223c908474c4545cc6f63456117a3bSanket Padawe                cleanUpAllConnections(Phone.REASON_DATA_DISABLED, onCompleteMsg);
4078a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
4079a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4080a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            if (sendOnComplete) {
4081a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                if (onCompleteMsg != null) {
4082a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                    onCompleteMsg.sendToTarget();
4083a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                }
4084a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
4085a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4086a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4087a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4088a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean setInternalDataEnabled(boolean enable) {
4089a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return setInternalDataEnabled(enable, null);
4090a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4091a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4092a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean setInternalDataEnabled(boolean enable, Message onCompleteMsg) {
40936bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        if (DBG) log("setInternalDataEnabled(" + enable + ")");
4094a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4095a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Message msg = obtainMessage(DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE, onCompleteMsg);
4096a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        msg.arg1 = (enable ? DctConstants.ENABLED : DctConstants.DISABLED);
4097a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sendMessage(msg);
4098a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return true;
4099a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4100a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
41011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void log(String s) {
4102a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Rlog.d(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s);
4103cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
4104cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
41051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void loge(String s) {
4106a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Rlog.e(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s);
4107cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
4108cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4109c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
41101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println("DcTracker:");
41111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" RADIO_TESTS=" + RADIO_TESTS);
411299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        pw.println(" mDataEnabledSettings=" + mDataEnabledSettings);
411399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        pw.println(" isDataAllowed=" + isDataAllowed(null));
41141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
41151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mRequestedApnType=" + mRequestedApnType);
41161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mPhone=" + mPhone.getPhoneName());
41171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mActivity=" + mActivity);
41181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mState=" + mState);
41191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mTxPkts=" + mTxPkts);
41201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mRxPkts=" + mRxPkts);
41211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mNetStatPollPeriod=" + mNetStatPollPeriod);
41221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mNetStatPollEnabled=" + mNetStatPollEnabled);
41231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mDataStallTxRxSum=" + mDataStallTxRxSum);
41241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mDataStallAlarmTag=" + mDataStallAlarmTag);
4125a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        pw.println(" mDataStallDetectionEnabled=" + mDataStallDetectionEnabled);
41261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mSentSinceLastRecv=" + mSentSinceLastRecv);
41271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mNoRecvPollCount=" + mNoRecvPollCount);
41281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mResolver=" + mResolver);
41291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mReconnectIntent=" + mReconnectIntent);
41301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mAutoAttachOnCreation=" + mAutoAttachOnCreation.get());
41311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsScreenOn=" + mIsScreenOn);
41321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mUniqueIdGenerator=" + mUniqueIdGenerator);
4133d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen        pw.println(" mDataRoamingLeakageLog= ");
4134d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen        mDataRoamingLeakageLog.dump(fd, pw, args);
41351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
41361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
41371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        DcController dcc = mDcc;
41381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (dcc != null) {
41391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            dcc.dump(fd, pw, args);
41401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
41411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mDcc=null");
41421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
41431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
41441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        HashMap<Integer, DataConnection> dcs = mDataConnections;
41451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (dcs != null) {
41461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Set<Entry<Integer, DataConnection> > mDcSet = mDataConnections.entrySet();
41471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mDataConnections: count=" + mDcSet.size());
41481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (Entry<Integer, DataConnection> entry : mDcSet) {
41491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                pw.printf(" *** mDataConnection[%d] \n", entry.getKey());
41501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                entry.getValue().dump(fd, pw, args);
41511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
41521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
41531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println("mDataConnections=null");
41541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
41551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
41561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
41571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        HashMap<String, Integer> apnToDcId = mApnToDataConnectionId;
41581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (apnToDcId != null) {
41591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Set<Entry<String, Integer>> apnToDcIdSet = apnToDcId.entrySet();
41601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mApnToDataConnectonId size=" + apnToDcIdSet.size());
41611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (Entry<String, Integer> entry : apnToDcIdSet) {
41621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                pw.printf(" mApnToDataConnectonId[%s]=%d\n", entry.getKey(), entry.getValue());
41631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
41641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
41651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println("mApnToDataConnectionId=null");
41661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
41671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
41681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
41691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ConcurrentHashMap<String, ApnContext> apnCtxs = mApnContexts;
41701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (apnCtxs != null) {
41711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Set<Entry<String, ApnContext>> apnCtxsSet = apnCtxs.entrySet();
41721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mApnContexts size=" + apnCtxsSet.size());
41731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (Entry<String, ApnContext> entry : apnCtxsSet) {
41741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                entry.getValue().dump(fd, pw, args);
41751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
41761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" ***************************************");
41771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
41781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mApnContexts=null");
41791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
41801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
41811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ArrayList<ApnSetting> apnSettings = mAllApnSettings;
41821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (apnSettings != null) {
41831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mAllApnSettings size=" + apnSettings.size());
41841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (int i=0; i < apnSettings.size(); i++) {
41851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                pw.printf(" mAllApnSettings[%d]: %s\n", i, apnSettings.get(i));
41861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
41871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.flush();
41881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
41891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mAllApnSettings=null");
41901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
41911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mPreferredApn=" + mPreferredApn);
41921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsPsRestricted=" + mIsPsRestricted);
41931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsDisposed=" + mIsDisposed);
41941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIntentReceiver=" + mIntentReceiver);
4195cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mReregisterOnReconnectFailure=" + mReregisterOnReconnectFailure);
419622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" canSetPreferApn=" + mCanSetPreferApn);
4197cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mApnObserver=" + mApnObserver);
4198cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" getOverallState=" + getOverallState());
4199ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        pw.println(" mDataConnectionAsyncChannels=%s\n" + mDataConnectionAcHashMap);
4200187a39f896f88eb6c5e4306d9595546654825976Wink Saville        pw.println(" mAttached=" + mAttached.get());
4201985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen        mDataEnabledSettings.dump(fd, pw, args);
42021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
4203c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
4204a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4205bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram    public String[] getPcscfAddress(String apnType) {
4206a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("getPcscfAddress()");
4207bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        ApnContext apnContext = null;
4208bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram
4209bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        if(apnType == null){
4210bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            log("apnType is null, return null");
4211bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            return null;
4212bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        }
4213a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4214bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_EMERGENCY)) {
4215af5593594070f825032be46dced573cd195956e1Robert Greenwalt            apnContext = mApnContextsById.get(DctConstants.APN_EMERGENCY_ID);
4216bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IMS)) {
4217af5593594070f825032be46dced573cd195956e1Robert Greenwalt            apnContext = mApnContextsById.get(DctConstants.APN_IMS_ID);
4218bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        } else {
4219bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            log("apnType is invalid, return null");
4220bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            return null;
4221bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        }
4222a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4223a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (apnContext == null) {
4224a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("apnContext is null, return null");
4225a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return null;
4226a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4227a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4228a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        DcAsyncChannel dcac = apnContext.getDcAc();
4229a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        String[] result = null;
4230a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4231a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (dcac != null) {
4232a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            result = dcac.getPcscfAddr();
4233a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4234c0a3ed8c70021d47cd55bbc1406a9cf63bd6afe2Jack Yu            if (result != null) {
4235c0a3ed8c70021d47cd55bbc1406a9cf63bd6afe2Jack Yu                for (int i = 0; i < result.length; i++) {
4236c0a3ed8c70021d47cd55bbc1406a9cf63bd6afe2Jack Yu                    log("Pcscf[" + i + "]: " + result[i]);
4237c0a3ed8c70021d47cd55bbc1406a9cf63bd6afe2Jack Yu                }
4238a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
4239a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return result;
4240a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4241a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return null;
4242a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4243a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
424476f43316a5a6082d601bffd4b6898d0bd81e11fcram    /**
424576f43316a5a6082d601bffd4b6898d0bd81e11fcram     * Read APN configuration from Telephony.db for Emergency APN
424676f43316a5a6082d601bffd4b6898d0bd81e11fcram     * All opertors recognize the connection request for EPDN based on APN type
424776f43316a5a6082d601bffd4b6898d0bd81e11fcram     * PLMN name,APN name are not mandatory parameters
424876f43316a5a6082d601bffd4b6898d0bd81e11fcram     */
424976f43316a5a6082d601bffd4b6898d0bd81e11fcram    private void initEmergencyApnSetting() {
425076f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Operator Numeric is not available when sim records are not loaded.
425176f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Query Telephony.db with APN type as EPDN request does not
425276f43316a5a6082d601bffd4b6898d0bd81e11fcram        // require APN name, plmn and all operators support same APN config.
425376f43316a5a6082d601bffd4b6898d0bd81e11fcram        // DB will contain only one entry for Emergency APN
425476f43316a5a6082d601bffd4b6898d0bd81e11fcram        String selection = "type=\"emergency\"";
425576f43316a5a6082d601bffd4b6898d0bd81e11fcram        Cursor cursor = mPhone.getContext().getContentResolver().query(
4256030fdfb7ccdf5dce9a6b48ca07918082627200f4yuemingw                Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "filtered"),
4257030fdfb7ccdf5dce9a6b48ca07918082627200f4yuemingw                null, selection, null, null);
425876f43316a5a6082d601bffd4b6898d0bd81e11fcram
425976f43316a5a6082d601bffd4b6898d0bd81e11fcram        if (cursor != null) {
426076f43316a5a6082d601bffd4b6898d0bd81e11fcram            if (cursor.getCount() > 0) {
426176f43316a5a6082d601bffd4b6898d0bd81e11fcram                if (cursor.moveToFirst()) {
426276f43316a5a6082d601bffd4b6898d0bd81e11fcram                    mEmergencyApn = makeApnSetting(cursor);
426376f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
426476f43316a5a6082d601bffd4b6898d0bd81e11fcram            }
426576f43316a5a6082d601bffd4b6898d0bd81e11fcram            cursor.close();
426676f43316a5a6082d601bffd4b6898d0bd81e11fcram        }
426776f43316a5a6082d601bffd4b6898d0bd81e11fcram    }
426876f43316a5a6082d601bffd4b6898d0bd81e11fcram
426976f43316a5a6082d601bffd4b6898d0bd81e11fcram    /**
427076f43316a5a6082d601bffd4b6898d0bd81e11fcram     * Add the Emergency APN settings to APN settings list
427176f43316a5a6082d601bffd4b6898d0bd81e11fcram     */
427276f43316a5a6082d601bffd4b6898d0bd81e11fcram    private void addEmergencyApnSetting() {
427376f43316a5a6082d601bffd4b6898d0bd81e11fcram        if(mEmergencyApn != null) {
427476f43316a5a6082d601bffd4b6898d0bd81e11fcram            if(mAllApnSettings == null) {
427576f43316a5a6082d601bffd4b6898d0bd81e11fcram                mAllApnSettings = new ArrayList<ApnSetting>();
427676f43316a5a6082d601bffd4b6898d0bd81e11fcram            } else {
427776f43316a5a6082d601bffd4b6898d0bd81e11fcram                boolean hasEmergencyApn = false;
427876f43316a5a6082d601bffd4b6898d0bd81e11fcram                for (ApnSetting apn : mAllApnSettings) {
427976f43316a5a6082d601bffd4b6898d0bd81e11fcram                    if (ArrayUtils.contains(apn.types, PhoneConstants.APN_TYPE_EMERGENCY)) {
428076f43316a5a6082d601bffd4b6898d0bd81e11fcram                        hasEmergencyApn = true;
428176f43316a5a6082d601bffd4b6898d0bd81e11fcram                        break;
428276f43316a5a6082d601bffd4b6898d0bd81e11fcram                    }
428376f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
428476f43316a5a6082d601bffd4b6898d0bd81e11fcram
428576f43316a5a6082d601bffd4b6898d0bd81e11fcram                if(hasEmergencyApn == false) {
428676f43316a5a6082d601bffd4b6898d0bd81e11fcram                    mAllApnSettings.add(mEmergencyApn);
428776f43316a5a6082d601bffd4b6898d0bd81e11fcram                } else {
428876f43316a5a6082d601bffd4b6898d0bd81e11fcram                    log("addEmergencyApnSetting - E-APN setting is already present");
428976f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
429076f43316a5a6082d601bffd4b6898d0bd81e11fcram            }
429176f43316a5a6082d601bffd4b6898d0bd81e11fcram        }
429276f43316a5a6082d601bffd4b6898d0bd81e11fcram    }
42939a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
42949fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu    private boolean containsAllApns(ArrayList<ApnSetting> oldApnList,
42959fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                                    ArrayList<ApnSetting> newApnList) {
42969fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu        for (ApnSetting newApnSetting : newApnList) {
42979fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            boolean canHandle = false;
42989fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            for (ApnSetting oldApnSetting : oldApnList) {
42999fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                // Make sure at least one of the APN from old list can cover the new APN
43009fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                if (oldApnSetting.equals(newApnSetting,
43019fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                        mPhone.getServiceState().getDataRoamingFromRegistration())) {
43029fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                    canHandle = true;
43039fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                    break;
43049fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                }
43059fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            }
43069fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            if (!canHandle) return false;
43079fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu        }
43089fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu        return true;
43099fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu    }
43109fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu
4311ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu    private void cleanUpConnectionsOnUpdatedApns(boolean tearDown, String reason) {
43129a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (DBG) log("cleanUpConnectionsOnUpdatedApns: tearDown=" + tearDown);
4313ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu        if (mAllApnSettings != null && mAllApnSettings.isEmpty()) {
43149a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            cleanUpAllConnections(tearDown, Phone.REASON_APN_CHANGED);
43159a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        } else {
4316e996a89f15d07d8c9fae23e9b03d47fff17087d8fionaxu            int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
4317e996a89f15d07d8c9fae23e9b03d47fff17087d8fionaxu            if (radioTech == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
4318e996a89f15d07d8c9fae23e9b03d47fff17087d8fionaxu                // unknown rat is an exception for data rat change. Its only received when out of
4319e996a89f15d07d8c9fae23e9b03d47fff17087d8fionaxu                // service and is not applicable for apn bearer bitmask. We should bypass the check
4320e996a89f15d07d8c9fae23e9b03d47fff17087d8fionaxu                // of waiting apn list and keep the data connection on.
4321e996a89f15d07d8c9fae23e9b03d47fff17087d8fionaxu                return;
4322e996a89f15d07d8c9fae23e9b03d47fff17087d8fionaxu            }
43239a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            for (ApnContext apnContext : mApnContexts.values()) {
43249a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                ArrayList<ApnSetting> currentWaitingApns = apnContext.getWaitingApns();
4325ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                ArrayList<ApnSetting> waitingApns = buildWaitingApns(
4326b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                        apnContext.getApnType(),
4327b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                        mPhone.getServiceState().getRilDataRadioTechnology());
4328ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                if (VDBG) log("new waitingApns:" + waitingApns);
4329ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                if ((currentWaitingApns != null)
4330ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                        && ((waitingApns.size() != currentWaitingApns.size())
43319fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                        // Check if the existing waiting APN list can cover the newly built APN
43329fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                        // list. If yes, then we don't need to tear down the existing data call.
43339fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                        // TODO: We probably need to rebuild APN list when roaming status changes.
43349fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                        || !containsAllApns(currentWaitingApns, waitingApns))) {
4335ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                    if (VDBG) log("new waiting apn is different for " + apnContext);
4336ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                    apnContext.setWaitingApns(waitingApns);
4337ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                    if (!apnContext.isDisconnected()) {
4338ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                        if (VDBG) log("cleanUpConnectionsOnUpdatedApns for " + apnContext);
4339ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                        apnContext.setReason(reason);
4340ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                        cleanUpConnection(true, apnContext);
43419a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    }
43429a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                }
43439a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            }
43449a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        }
43459a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
43469a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (!isConnected()) {
43479a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            stopNetStatPoll();
43489a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            stopDataStallAlarm();
43499a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        }
43509a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
43519a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
43529a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
43539a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (DBG) log("mDisconnectPendingCount = " + mDisconnectPendingCount);
43549a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (tearDown && mDisconnectPendingCount == 0) {
43559a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            notifyDataDisconnectComplete();
43569a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            notifyAllDataDisconnected();
43579a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        }
43589a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang    }
43591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
43601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
43611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Polling stuff
43621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
43631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void resetPollStats() {
43641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mTxPkts = -1;
43651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mRxPkts = -1;
43661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mNetStatPollPeriod = POLL_NETSTAT_MILLIS;
43671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
43681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
43691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void startNetStatPoll() {
43701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (getOverallState() == DctConstants.State.CONNECTED
43711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                && mNetStatPollEnabled == false) {
43721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
43731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("startNetStatPoll");
43741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
43751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            resetPollStats();
43761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mNetStatPollEnabled = true;
43771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPollNetStat.run();
43781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
43791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mPhone != null) {
43801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPhone.notifyDataActivity();
43811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
43821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
43831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
43841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void stopNetStatPoll() {
43851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mNetStatPollEnabled = false;
43861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        removeCallbacks(mPollNetStat);
43871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
43881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("stopNetStatPoll");
43891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
43901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
43911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // To sync data activity icon in the case of switching data connection to send MMS.
43921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mPhone != null) {
43931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPhone.notifyDataActivity();
43941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
43951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
43961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
43971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void sendStartNetStatPoll(DctConstants.Activity activity) {
43981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.CMD_NET_STAT_POLL);
43991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = DctConstants.ENABLED;
44001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.obj = activity;
44011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
44021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void handleStartNetStatPoll(DctConstants.Activity activity) {
44051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startNetStatPoll();
44061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
44071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        setActivity(activity);
44081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void sendStopNetStatPoll(DctConstants.Activity activity) {
44111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.CMD_NET_STAT_POLL);
44121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = DctConstants.DISABLED;
44131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.obj = activity;
44141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
44151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void handleStopNetStatPoll(DctConstants.Activity activity) {
44181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        stopNetStatPoll();
44191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        stopDataStallAlarm();
44201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        setActivity(activity);
44211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void updateDataActivity() {
44241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        long sent, received;
44251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        DctConstants.Activity newActivity;
44271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        TxRxSum preTxRxSum = new TxRxSum(mTxPkts, mRxPkts);
44291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        TxRxSum curTxRxSum = new TxRxSum();
44301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        curTxRxSum.updateTxRxSum();
44311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mTxPkts = curTxRxSum.txPkts;
44321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mRxPkts = curTxRxSum.rxPkts;
44331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) {
44351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("updateDataActivity: curTxRxSum=" + curTxRxSum + " preTxRxSum=" + preTxRxSum);
44361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mNetStatPollEnabled && (preTxRxSum.txPkts > 0 || preTxRxSum.rxPkts > 0)) {
44391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            sent = mTxPkts - preTxRxSum.txPkts;
44401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            received = mRxPkts - preTxRxSum.rxPkts;
44411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG)
44431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("updateDataActivity: sent=" + sent + " received=" + received);
44441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (sent > 0 && received > 0) {
44451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = DctConstants.Activity.DATAINANDOUT;
44461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (sent > 0 && received == 0) {
44471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = DctConstants.Activity.DATAOUT;
44481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (sent == 0 && received > 0) {
44491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = DctConstants.Activity.DATAIN;
44501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
44511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = (mActivity == DctConstants.Activity.DORMANT) ?
44521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mActivity : DctConstants.Activity.NONE;
44531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
44541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mActivity != newActivity && mIsScreenOn) {
44561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (VDBG)
44571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("updateDataActivity: newActivity=" + newActivity);
44581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mActivity = newActivity;
44591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mPhone.notifyDataActivity();
44601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
44611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44642e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt    private void handlePcoData(AsyncResult ar) {
44652e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        if (ar.exception != null) {
44662e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            Rlog.e(LOG_TAG, "PCO_DATA exception: " + ar.exception);
44672e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            return;
44682e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        }
44692e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        PcoData pcoData = (PcoData)(ar.result);
4470cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        ArrayList<DataConnection> dcList = new ArrayList<>();
4471cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        DataConnection temp = mDcc.getActiveDcByCid(pcoData.cid);
4472cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        if (temp != null) {
4473cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            dcList.add(temp);
4474cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        }
4475cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        if (dcList.size() == 0) {
4476cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            Rlog.e(LOG_TAG, "PCO_DATA for unknown cid: " + pcoData.cid + ", inferring");
4477cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            for (DataConnection dc : mDataConnections.values()) {
4478cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                final int cid = dc.getCid();
4479cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                if (cid == pcoData.cid) {
4480cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    if (VDBG) Rlog.d(LOG_TAG, "  found " + dc);
4481cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    dcList.clear();
4482cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    dcList.add(dc);
4483cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    break;
4484cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                }
4485cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                // check if this dc is still connecting
4486cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                if (cid == -1) {
4487cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    for (ApnContext apnContext : dc.mApnContexts.keySet()) {
4488cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        if (apnContext.getState() == DctConstants.State.CONNECTING) {
4489cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                            if (VDBG) Rlog.d(LOG_TAG, "  found potential " + dc);
4490cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                            dcList.add(dc);
4491cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                            break;
4492cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        }
4493cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    }
4494cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                }
4495cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            }
4496cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        }
4497cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        if (dcList.size() == 0) {
4498cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            Rlog.e(LOG_TAG, "PCO_DATA - couldn't infer cid");
44992e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            return;
45002e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        }
4501cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        for (DataConnection dc : dcList) {
4502cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            if (dc.mApnContexts.size() == 0) {
4503cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                break;
4504cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            }
4505cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            // send one out for each apn type in play
4506cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            for (ApnContext apnContext : dc.mApnContexts.keySet()) {
4507cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                String apnType = apnContext.getApnType();
4508cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt
4509cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                final Intent intent = new Intent(TelephonyIntents.ACTION_CARRIER_SIGNAL_PCO_VALUE);
4510cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                intent.putExtra(TelephonyIntents.EXTRA_APN_TYPE_KEY, apnType);
4511cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                intent.putExtra(TelephonyIntents.EXTRA_APN_PROTO_KEY, pcoData.bearerProto);
4512cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                intent.putExtra(TelephonyIntents.EXTRA_PCO_ID_KEY, pcoData.pcoId);
4513cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                intent.putExtra(TelephonyIntents.EXTRA_PCO_VALUE_KEY, pcoData.contents);
4514cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
4515cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            }
45162e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        }
45172e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt    }
45182e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt
45191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
45201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Data-Stall
45211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
45221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Recovery action taken in case of data stall
45231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static class RecoveryAction {
45241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int GET_DATA_CALL_LIST      = 0;
45251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int CLEANUP                 = 1;
45261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int REREGISTER              = 2;
45271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int RADIO_RESTART           = 3;
45281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        private static boolean isAggressiveRecovery(int value) {
45301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return ((value == RecoveryAction.CLEANUP) ||
45311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    (value == RecoveryAction.REREGISTER) ||
4532fc7e59579742d8888abd288ac5c36f2da17c29dbNathan Harold                    (value == RecoveryAction.RADIO_RESTART));
45331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
45341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int getRecoveryAction() {
45371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int action = Settings.System.getInt(mResolver,
45381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                "radio.data.stall.recovery.action", RecoveryAction.GET_DATA_CALL_LIST);
45391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("getRecoveryAction: " + action);
45401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return action;
45411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void putRecoveryAction(int action) {
45441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Settings.System.putInt(mResolver, "radio.data.stall.recovery.action", action);
45451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("putRecoveryAction: " + action);
45461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void doRecovery() {
45491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (getOverallState() == DctConstants.State.CONNECTED) {
45501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Go through a series of recovery steps, each action transitions to the next action
45510a39f581e11eb7b040a5412229164ef72044279fRobert Greenwalt            final int recoveryAction = getRecoveryAction();
4552f2d0fa64860a12423fb8709766d6af90fba5e6cfJack Yu            TelephonyMetrics.getInstance().writeDataStallEvent(mPhone.getPhoneId(), recoveryAction);
45531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            switch (recoveryAction) {
455471f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                case RecoveryAction.GET_DATA_CALL_LIST:
455571f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_GET_DATA_CALL_LIST,
455671f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                            mSentSinceLastRecv);
455771f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    if (DBG) log("doRecovery() get data call list");
455871f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    mDataServiceManager.getDataCallList(obtainMessage());
455971f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    putRecoveryAction(RecoveryAction.CLEANUP);
456071f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    break;
456171f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                case RecoveryAction.CLEANUP:
456271f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_CLEANUP,
456371f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                            mSentSinceLastRecv);
456471f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    if (DBG) log("doRecovery() cleanup all connections");
456571f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    cleanUpAllConnections(Phone.REASON_PDP_RESET);
456671f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    putRecoveryAction(RecoveryAction.REREGISTER);
456771f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    break;
456871f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                case RecoveryAction.REREGISTER:
456971f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_REREGISTER,
457071f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                            mSentSinceLastRecv);
457171f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    if (DBG) log("doRecovery() re-register");
457271f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    mPhone.getServiceStateTracker().reRegisterNetwork(null);
457371f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    putRecoveryAction(RecoveryAction.RADIO_RESTART);
457471f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    break;
457571f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                case RecoveryAction.RADIO_RESTART:
457671f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART,
457771f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                            mSentSinceLastRecv);
457871f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    if (DBG) log("restarting radio");
457971f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    restartRadio();
458071f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
458171f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    break;
458271f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                default:
458371f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                    throw new RuntimeException("doRecovery: Invalid recoveryAction="
458471f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu                            + recoveryAction);
45851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
45861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSentSinceLastRecv = 0;
45871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
45881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void updateDataStallInfo() {
45911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        long sent, received;
45921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        TxRxSum preTxRxSum = new TxRxSum(mDataStallTxRxSum);
45941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDataStallTxRxSum.updateTxRxSum();
45951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) {
45971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("updateDataStallInfo: mDataStallTxRxSum=" + mDataStallTxRxSum +
45981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " preTxRxSum=" + preTxRxSum);
45991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sent = mDataStallTxRxSum.txPkts - preTxRxSum.txPkts;
46021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        received = mDataStallTxRxSum.rxPkts - preTxRxSum.rxPkts;
46031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (RADIO_TESTS) {
46051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (SystemProperties.getBoolean("radio.test.data.stall", false)) {
46061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("updateDataStallInfo: radio.test.data.stall true received = 0;");
46071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                received = 0;
46081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if ( sent > 0 && received > 0 ) {
46111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) log("updateDataStallInfo: IN/OUT");
46121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSentSinceLastRecv = 0;
46131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
46141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (sent > 0 && received == 0) {
46156a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta            if (isPhoneStateIdle()) {
46161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mSentSinceLastRecv += sent;
46171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
46181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mSentSinceLastRecv = 0;
46191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
46211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("updateDataStallInfo: OUT sent=" + sent +
46221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        " mSentSinceLastRecv=" + mSentSinceLastRecv);
46231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (sent == 0 && received > 0) {
46251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) log("updateDataStallInfo: IN");
46261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSentSinceLastRecv = 0;
46271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
46281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
46291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) log("updateDataStallInfo: NONE");
46301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
46321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46336a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta    private boolean isPhoneStateIdle() {
46346a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta        for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
46356a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta            Phone phone = PhoneFactory.getPhone(i);
46366a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta            if (phone != null && phone.getState() != PhoneConstants.State.IDLE) {
46376a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta                log("isPhoneStateIdle false: Voice call active on phone " + i);
46386a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta                return false;
46396a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta            }
46406a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta        }
46416a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta        return true;
46426a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta    }
46436a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta
46441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataStallAlarm(int tag) {
46451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mDataStallAlarmTag != tag) {
46461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
46471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("onDataStallAlarm: ignore, tag=" + tag + " expecting " + mDataStallAlarmTag);
46481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return;
46501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        updateDataStallInfo();
46521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int hangWatchdogTrigger = Settings.Global.getInt(mResolver,
46541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Settings.Global.PDP_WATCHDOG_TRIGGER_PACKET_COUNT,
46551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                NUMBER_SENT_PACKETS_OF_HANG);
46561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        boolean suspectedStall = DATA_STALL_NOT_SUSPECTED;
46581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mSentSinceLastRecv >= hangWatchdogTrigger) {
46591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
46601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("onDataStallAlarm: tag=" + tag + " do recovery action=" + getRecoveryAction());
46611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            suspectedStall = DATA_STALL_SUSPECTED;
46631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            sendMessage(obtainMessage(DctConstants.EVENT_DO_RECOVERY));
46641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
46651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) {
46661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("onDataStallAlarm: tag=" + tag + " Sent " + String.valueOf(mSentSinceLastRecv) +
46671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " pkts since last received, < watchdogTrigger=" + hangWatchdogTrigger);
46681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startDataStallAlarm(suspectedStall);
46711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
46721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void startDataStallAlarm(boolean suspectedStall) {
46741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int nextAction = getRecoveryAction();
46751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int delayInMs;
46761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mDataStallDetectionEnabled && getOverallState() == DctConstants.State.CONNECTED) {
46781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // If screen is on or data stall is currently suspected, set the alarm
46790e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // with an aggressive timeout.
46801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mIsScreenOn || suspectedStall || RecoveryAction.isAggressiveRecovery(nextAction)) {
46811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                delayInMs = Settings.Global.getInt(mResolver,
46821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS,
46831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
46841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
46851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                delayInMs = Settings.Global.getInt(mResolver,
46861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS,
46871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
46881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mDataStallAlarmTag += 1;
46911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) {
46921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("startDataStallAlarm: tag=" + mDataStallAlarmTag +
46931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        " delay=" + (delayInMs / 1000) + "s");
46941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Intent intent = new Intent(INTENT_DATA_STALL_ALARM);
46961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            intent.putExtra(DATA_STALL_ALARM_TAG_EXTRA, mDataStallAlarmTag);
46971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mDataStallAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
46981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    PendingIntent.FLAG_UPDATE_CURRENT);
4699128f3f36854fe183a6dd4d9917906b4723dd234fAjay Dudani            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME,
47001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    SystemClock.elapsedRealtime() + delayInMs, mDataStallAlarmIntent);
47011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
47021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) {
47031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("startDataStallAlarm: NOT started, no connection tag=" + mDataStallAlarmTag);
47041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void stopDataStallAlarm() {
47091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) {
47101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("stopDataStallAlarm: current tag=" + mDataStallAlarmTag +
47111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " mDataStallAlarmIntent=" + mDataStallAlarmIntent);
47121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDataStallAlarmTag += 1;
47141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mDataStallAlarmIntent != null) {
47151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mAlarmManager.cancel(mDataStallAlarmIntent);
47161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mDataStallAlarmIntent = null;
47171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void restartDataStallAlarm() {
47211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (isConnected() == false) return;
47221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // To be called on screen status change.
47231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // Do not cancel the alarm if it is set with aggressive timeout.
47241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int nextAction = getRecoveryAction();
47251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (RecoveryAction.isAggressiveRecovery(nextAction)) {
47271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("restartDataStallAlarm: action is pending. not resetting the alarm.");
47281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return;
47291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("restartDataStallAlarm: stop then start.");
47311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        stopDataStallAlarm();
47321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
47331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
47361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Provisioning APN
47371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
47381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onActionIntentProvisioningApnAlarm(Intent intent) {
47391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("onActionIntentProvisioningApnAlarm: action=" + intent.getAction());
47401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_PROVISIONING_APN_ALARM,
47411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                intent.getAction());
47421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = intent.getIntExtra(PROVISIONING_APN_ALARM_TAG_EXTRA, 0);
47431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
47441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void startProvisioningApnAlarm() {
47471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int delayInMs = Settings.Global.getInt(mResolver,
47481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                Settings.Global.PROVISIONING_APN_ALARM_DELAY_IN_MS,
47491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                PROVISIONING_APN_ALARM_DELAY_IN_MS_DEFAULT);
47501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (Build.IS_DEBUGGABLE) {
47511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Allow debug code to use a system property to provide another value
47521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            String delayInMsStrg = Integer.toString(delayInMs);
47531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            delayInMsStrg = System.getProperty(DEBUG_PROV_APN_ALARM, delayInMsStrg);
47541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            try {
47551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                delayInMs = Integer.parseInt(delayInMsStrg);
47561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } catch (NumberFormatException e) {
47571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                loge("startProvisioningApnAlarm: e=" + e);
47581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisioningApnAlarmTag += 1;
47611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
47621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("startProvisioningApnAlarm: tag=" + mProvisioningApnAlarmTag +
47631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " delay=" + (delayInMs / 1000) + "s");
47641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Intent intent = new Intent(INTENT_PROVISIONING_APN_ALARM);
47661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        intent.putExtra(PROVISIONING_APN_ALARM_TAG_EXTRA, mProvisioningApnAlarmTag);
47671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisioningApnAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
47681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                PendingIntent.FLAG_UPDATE_CURRENT);
47691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
47701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                SystemClock.elapsedRealtime() + delayInMs, mProvisioningApnAlarmIntent);
47711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void stopProvisioningApnAlarm() {
47741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
47751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("stopProvisioningApnAlarm: current tag=" + mProvisioningApnAlarmTag +
47761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " mProvsioningApnAlarmIntent=" + mProvisioningApnAlarmIntent);
47771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisioningApnAlarmTag += 1;
47791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mProvisioningApnAlarmIntent != null) {
47801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mAlarmManager.cancel(mProvisioningApnAlarmIntent);
47811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mProvisioningApnAlarmIntent = null;
47821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4785886183cde1263ea524cdf08524442724e246ed42Jack Yu    private static DataProfile createDataProfile(ApnSetting apn) {
4786886183cde1263ea524cdf08524442724e246ed42Jack Yu        return createDataProfile(apn, apn.profileId);
4787886183cde1263ea524cdf08524442724e246ed42Jack Yu    }
4788886183cde1263ea524cdf08524442724e246ed42Jack Yu
4789886183cde1263ea524cdf08524442724e246ed42Jack Yu    @VisibleForTesting
4790886183cde1263ea524cdf08524442724e246ed42Jack Yu    public static DataProfile createDataProfile(ApnSetting apn, int profileId) {
4791886183cde1263ea524cdf08524442724e246ed42Jack Yu        int profileType;
4792176f28521fd45bb739709d309e7970b1558c9f61Cassie
4793176f28521fd45bb739709d309e7970b1558c9f61Cassie        int bearerBitmap = 0;
4794176f28521fd45bb739709d309e7970b1558c9f61Cassie        bearerBitmap = ServiceState.convertNetworkTypeBitmaskToBearerBitmask(
4795176f28521fd45bb739709d309e7970b1558c9f61Cassie                apn.networkTypeBitmask);
4796176f28521fd45bb739709d309e7970b1558c9f61Cassie
4797176f28521fd45bb739709d309e7970b1558c9f61Cassie        if (bearerBitmap == 0) {
4798886183cde1263ea524cdf08524442724e246ed42Jack Yu            profileType = DataProfile.TYPE_COMMON;
4799176f28521fd45bb739709d309e7970b1558c9f61Cassie        } else if (ServiceState.bearerBitmapHasCdma(bearerBitmap)) {
4800886183cde1263ea524cdf08524442724e246ed42Jack Yu            profileType = DataProfile.TYPE_3GPP2;
4801886183cde1263ea524cdf08524442724e246ed42Jack Yu        } else {
4802886183cde1263ea524cdf08524442724e246ed42Jack Yu            profileType = DataProfile.TYPE_3GPP;
4803886183cde1263ea524cdf08524442724e246ed42Jack Yu        }
4804886183cde1263ea524cdf08524442724e246ed42Jack Yu
4805886183cde1263ea524cdf08524442724e246ed42Jack Yu        return new DataProfile(profileId, apn.apn, apn.protocol,
4806886183cde1263ea524cdf08524442724e246ed42Jack Yu                apn.authType, apn.user, apn.password, profileType,
4807886183cde1263ea524cdf08524442724e246ed42Jack Yu                apn.maxConnsTime, apn.maxConns, apn.waitTime, apn.carrierEnabled, apn.typesBitmap,
4808176f28521fd45bb739709d309e7970b1558c9f61Cassie                apn.roamingProtocol, bearerBitmap, apn.mtu, apn.mvnoType, apn.mvnoMatchData,
4809886183cde1263ea524cdf08524442724e246ed42Jack Yu                apn.modemCognitive);
4810886183cde1263ea524cdf08524442724e246ed42Jack Yu    }
481171f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu
481271f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu    private void onDataServiceBindingChanged(boolean bound) {
481371f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        if (bound) {
481471f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu            mDcc.start();
481571f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        } else {
481671f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu            mDcc.dispose();
481771f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu        }
481871f909237a9921f52d91440fb8f9c6fc97465a52Jack Yu    }
4819c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville}
4820