DcTracker.java revision fcd5efef57e734966ed373ab7a4ce419d0034cec
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;
371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.net.NetworkInfo;
38af5593594070f825032be46dced573cd195956e1Robert Greenwaltimport android.net.NetworkRequest;
39cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.NetworkUtils;
409c180aedfc9f0d20525c0128487d3500e6c0a715Jason Monkimport android.net.ProxyInfo;
411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.net.TrafficStats;
42cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.Uri;
431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.net.wifi.WifiManager;
44c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.AsyncResult;
453fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwaltimport android.os.Build;
46b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensenimport android.os.Bundle;
47a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.Handler;
481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.os.HandlerThread;
49c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Message;
50bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liuimport android.os.PersistableBundle;
51a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.RegistrantList;
52b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensenimport android.os.ServiceManager;
53c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemClock;
54c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemProperties;
551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.preference.PreferenceManager;
56c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.provider.Settings;
571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.provider.Settings.SettingNotFoundException;
58cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.provider.Telephony;
59bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liuimport android.telephony.CarrierConfigManager;
60cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.CellLocation;
612e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwaltimport android.telephony.PcoData;
624c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport android.telephony.Rlog;
630e776303ca82b5bec5db19bb44e0f13b0c7c6400Etan Cohenimport android.telephony.ServiceState;
64a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.SubscriptionManager;
651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
664c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport android.telephony.TelephonyManager;
67cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.cdma.CdmaCellLocation;
68886183cde1263ea524cdf08524442724e246ed42Jack Yuimport android.telephony.data.DataProfile;
69cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.gsm.GsmCellLocation;
70c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.text.TextUtils;
71cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kallaimport android.util.EventLog;
722dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwaltimport android.util.LocalLog;
73ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwaltimport android.util.Pair;
74af5593594070f825032be46dced573cd195956e1Robert Greenwaltimport android.util.SparseArray;
752b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensenimport android.view.WindowManager;
76c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport com.android.internal.R;
78af5593594070f825032be46dced573cd195956e1Robert Greenwaltimport com.android.internal.annotations.VisibleForTesting;
796a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxuimport com.android.internal.telephony.CarrierActionAgent;
80cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.DctConstants;
81cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.EventLogTags;
824c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport com.android.internal.telephony.GsmCdmaPhone;
83b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensenimport com.android.internal.telephony.ITelephony;
844c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport com.android.internal.telephony.Phone;
854918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savilleimport com.android.internal.telephony.PhoneConstants;
866a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Guttaimport com.android.internal.telephony.PhoneFactory;
87cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.RILConstants;
88b8fa5c7082deeeb17434b42ed4838a5891a38769Jack Yuimport com.android.internal.telephony.SettingsObserver;
89a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxuimport com.android.internal.telephony.TelephonyIntents;
9099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yuimport com.android.internal.telephony.dataconnection.DataConnectionReasons.DataAllowedReasonType;
9199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yuimport com.android.internal.telephony.dataconnection.DataConnectionReasons.DataDisallowedReasonType;
92f2d0fa64860a12423fb8709766d6af90fba5e6cfJack Yuimport com.android.internal.telephony.metrics.TelephonyMetrics;
93d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccRecords;
94bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenkaimport com.android.internal.telephony.uicc.UiccController;
9576f43316a5a6082d601bffd4b6898d0bd81e11fcramimport com.android.internal.util.ArrayUtils;
964c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport com.android.internal.util.AsyncChannel;
97c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
98c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.io.FileDescriptor;
99c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.io.PrintWriter;
100c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.ArrayList;
10129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwaltimport java.util.Arrays;
1021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.Comparator;
1031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.HashMap;
1041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.Map.Entry;
1051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.PriorityQueue;
1061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.Set;
1071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.concurrent.ConcurrentHashMap;
1081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.concurrent.atomic.AtomicBoolean;
1091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.concurrent.atomic.AtomicInteger;
1101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.concurrent.atomic.AtomicReference;
111c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/**
112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * {@hide}
113c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
1140c3ec24396bb8c21b4d89f743b626c13dd35ba7bAmit Mahajanpublic class DcTracker extends Handler {
1151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String LOG_TAG = "DCT";
1161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean DBG = true;
1171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean VDBG = false; // STOPSHIP if true
1181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean VDBG_STALL = false; // STOPSHIP if true
1191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean RADIO_TESTS = false;
1201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1210e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    public AtomicBoolean isCleanupRequired = new AtomicBoolean(false);
1221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final AlarmManager mAlarmManager;
1241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Currently requested APN type (TODO: This should probably be a parameter not a member) */
1261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private String mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
1271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
128a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    // All data enabling/disabling related settings
129985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen    private final DataEnabledSettings mDataEnabledSettings;
130a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
1310a39f581e11eb7b040a5412229164ef72044279fRobert Greenwalt
1321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
1331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * After detecting a potential connection problem, this is the max number
1341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * of subsequent polls before attempting recovery.
1351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
1361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // 1 sec. default polling interval when screen is on.
1371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int POLL_NETSTAT_MILLIS = 1000;
1381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // 10 min. default polling interval when screen is off.
1391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int POLL_NETSTAT_SCREEN_OFF_MILLIS = 1000*60*10;
1401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Default sent packets without ack which triggers initial recovery steps
1411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int NUMBER_SENT_PACKETS_OF_HANG = 10;
1421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Default for the data stall alarm while non-aggressive stall detection
1441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60 * 6;
1451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Default for the data stall alarm for aggressive stall detection
1461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60;
1471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Tag for tracking stale alarms
1481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String DATA_STALL_ALARM_TAG_EXTRA = "data.stall.alram.tag";
1491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean DATA_STALL_SUSPECTED = true;
1511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean DATA_STALL_NOT_SUSPECTED = false;
1521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_RECONNECT_ALARM =
1541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "com.android.internal.telephony.data-reconnect";
1551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_RECONNECT_ALARM_EXTRA_TYPE = "reconnect_alarm_extra_type";
1561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_RECONNECT_ALARM_EXTRA_REASON =
1571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "reconnect_alarm_extra_reason";
1581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_DATA_STALL_ALARM =
1601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "com.android.internal.telephony.data-stall";
1611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DcTesterFailBringUpAll mDcTesterFailBringUpAll;
1631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DcController mDcc;
1641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** kept in sync with mApnContexts
1661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Higher numbers are higher priority and sorted so highest priority is first */
1671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final PriorityQueue<ApnContext>mPrioritySortedApnContexts =
1681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new PriorityQueue<ApnContext>(5,
1691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new Comparator<ApnContext>() {
1701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                public int compare(ApnContext c1, ApnContext c2) {
1711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    return c2.priority - c1.priority;
1721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
1731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } );
1741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** allApns holds all apns */
1761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ArrayList<ApnSetting> mAllApnSettings = null;
1771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** preferred apn */
1791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ApnSetting mPreferredApn = null;
1801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Is packet service restricted by network */
1821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsPsRestricted = false;
1831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** emergency apn Setting*/
1851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ApnSetting mEmergencyApn = null;
1861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Once disposed dont handle any messages */
1881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsDisposed = false;
1891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ContentResolver mResolver;
1911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Set to true with CMD_ENABLE_MOBILE_PROVISIONING */
1931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsProvisioning = false;
1941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* The Url passed as object parameter in CMD_ENABLE_MOBILE_PROVISIONING */
1961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private String mProvisioningUrl = null;
1971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Intent for the provisioning apn alarm */
1991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_PROVISIONING_APN_ALARM =
2001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "com.android.internal.telephony.provisioning_apn_alarm";
2011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Tag for tracking stale alarms */
2031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String PROVISIONING_APN_ALARM_TAG_EXTRA = "provisioning.apn.alarm.tag";
2041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Debug property for overriding the PROVISIONING_APN_ALARM_DELAY_IN_MS */
2061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String DEBUG_PROV_APN_ALARM = "persist.debug.prov_apn_alarm";
2071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Default for the provisioning apn alarm timeout */
2091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int PROVISIONING_APN_ALARM_DELAY_IN_MS_DEFAULT = 1000 * 60 * 15;
2101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* The provision apn alarm intent used to disable the provisioning apn */
2121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private PendingIntent mProvisioningApnAlarmIntent = null;
2131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Used to track stale provisioning apn alarms */
2151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mProvisioningApnAlarmTag = (int) SystemClock.elapsedRealtime();
2161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private AsyncChannel mReplyAc = new AsyncChannel();
2181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
219d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen    private final LocalLog mDataRoamingLeakageLog = new LocalLog(50);
220d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen
2211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver () {
2221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
2231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void onReceive(Context context, Intent intent) {
2241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            String action = intent.getAction();
225c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu
2261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (action.equals(Intent.ACTION_SCREEN_ON)) {
227baecdb610b30a5d4b35345f8fc63fcbc2133c149Jack Yu                // TODO: Evaluate hooking this up with DeviceStateMonitor
228c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("screen on");
2291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mIsScreenOn = true;
2301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                stopNetStatPoll();
2311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                startNetStatPoll();
2321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartDataStallAlarm();
2331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
234c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("screen off");
2351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mIsScreenOn = false;
2361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                stopNetStatPoll();
2371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                startNetStatPoll();
2381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartDataStallAlarm();
2391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.startsWith(INTENT_RECONNECT_ALARM)) {
2401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("Reconnect alarm. Previous state was " + mState);
2411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onActionIntentReconnectAlarm(intent);
2421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(INTENT_DATA_STALL_ALARM)) {
243c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("Data stall alarm");
2441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onActionIntentDataStallAlarm(intent);
2451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(INTENT_PROVISIONING_APN_ALARM)) {
246c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("Provisioning apn alarm");
2471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onActionIntentProvisioningApnAlarm(intent);
2481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
2491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final android.net.NetworkInfo networkInfo = (NetworkInfo)
2501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
2511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mIsWifiConnected = (networkInfo != null && networkInfo.isConnected());
2521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("NETWORK_STATE_CHANGED_ACTION: mIsWifiConnected=" + mIsWifiConnected);
2531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
254c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("Wifi state changed");
2551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
2561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
2571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (!enabled) {
2581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // when WiFi got disabled, the NETWORK_STATE_CHANGED_ACTION
2591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // quit and won't report disconnected until next enabling.
2601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mIsWifiConnected = false;
2611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
2621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
2631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("WIFI_STATE_CHANGED_ACTION: enabled=" + enabled
2641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + " mIsWifiConnected=" + mIsWifiConnected);
2651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
26621e6af8d6197a071d025733fffeffc157d0085bcfionaxu            } else if (action.equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
26721e6af8d6197a071d025733fffeffc157d0085bcfionaxu                if (mIccRecords.get() != null && mIccRecords.get().getRecordsLoaded()) {
26821e6af8d6197a071d025733fffeffc157d0085bcfionaxu                    setDefaultDataRoamingEnabled();
26921e6af8d6197a071d025733fffeffc157d0085bcfionaxu                }
270c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            } else {
271c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("onReceive: Unknown action=" + action);
2721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
2731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
2741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    };
2751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final Runnable mPollNetStat = new Runnable() {
2771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
2781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void run() {
2791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            updateDataActivity();
2801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mIsScreenOn) {
2821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mNetStatPollPeriod = Settings.Global.getInt(mResolver,
2831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.PDP_WATCHDOG_POLL_INTERVAL_MS, POLL_NETSTAT_MILLIS);
2841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
2851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mNetStatPollPeriod = Settings.Global.getInt(mResolver,
2861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS,
2871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        POLL_NETSTAT_SCREEN_OFF_MILLIS);
2881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
2891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mNetStatPollEnabled) {
2911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mDataConnectionTracker.postDelayed(this, mNetStatPollPeriod);
2921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
2931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
2941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    };
2951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private SubscriptionManager mSubscriptionManager;
2971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final OnSubscriptionsChangedListener mOnSubscriptionsChangedListener =
2981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new OnSubscriptionsChangedListener() {
2991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                public final AtomicInteger mPreviousSubId =
3001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        new AtomicInteger(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
3011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                /**
3031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                 * Callback invoked when there is any change to any SubscriptionInfo. Typically
3041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                 * this method invokes {@link SubscriptionManager#getActiveSubscriptionInfoList}
3051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                 */
3061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                @Override
3071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                public void onSubscriptionsChanged() {
3081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (DBG) log("SubscriptionListener.onSubscriptionInfoChanged");
3091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // Set the network type, in case the radio does not restore it.
3101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    int subId = mPhone.getSubId();
3111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (SubscriptionManager.isValidSubscriptionId(subId)) {
312f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                        registerSettingsObserver();
3131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
3141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mPreviousSubId.getAndSet(subId) != subId &&
3151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            SubscriptionManager.isValidSubscriptionId(subId)) {
3161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onRecordsLoadedOrSubIdChanged();
3171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
3181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
3191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            };
3201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
321f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    private final SettingsObserver mSettingsObserver;
322f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
323f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    private void registerSettingsObserver() {
324f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.unobserve();
325f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        String simSuffix = "";
326f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu        if (TelephonyManager.getDefault().getSimCount() > 1) {
327f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            simSuffix = Integer.toString(mPhone.getSubId());
328f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        }
329f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu
330f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.observe(
331f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                Settings.Global.getUriFor(Settings.Global.DATA_ROAMING + simSuffix),
332d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                DctConstants.EVENT_ROAMING_SETTING_CHANGE);
333f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.observe(
334f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
335f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE);
336f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.observe(
337f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED),
338f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE);
339f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    }
3401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
3421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Maintain the sum of transmit and receive packets.
3431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     *
3441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * The packet counts are initialized and reset to -1 and
3451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * remain -1 until they can be updated.
3461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
3471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public static class TxRxSum {
3481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public long txPkts;
3491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public long rxPkts;
3501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public TxRxSum() {
3521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            reset();
3531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public TxRxSum(long txPkts, long rxPkts) {
3561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.txPkts = txPkts;
3571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.rxPkts = rxPkts;
3581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public TxRxSum(TxRxSum sum) {
3611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            txPkts = sum.txPkts;
3621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            rxPkts = sum.rxPkts;
3631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void reset() {
3661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            txPkts = -1;
3671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            rxPkts = -1;
3681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
3711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public String toString() {
3721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return "{txSum=" + txPkts + " rxSum=" + rxPkts + "}";
3731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void updateTxRxSum() {
3761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.txPkts = TrafficStats.getMobileTcpTxPackets();
3771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.rxPkts = TrafficStats.getMobileTcpRxPackets();
3781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
3801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onActionIntentReconnectAlarm(Intent intent) {
382e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        Message msg = obtainMessage(DctConstants.EVENT_DATA_RECONNECT);
383e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        msg.setData(intent.getExtras());
384e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        sendMessage(msg);
385e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu    }
386e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu
387e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu    private void onDataReconnect(Bundle bundle) {
388e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        String reason = bundle.getString(INTENT_RECONNECT_ALARM_EXTRA_REASON);
389e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        String apnType = bundle.getString(INTENT_RECONNECT_ALARM_EXTRA_TYPE);
3901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int phoneSubId = mPhone.getSubId();
392e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        int currSubId = bundle.getInt(PhoneConstants.SUBSCRIPTION_KEY,
3931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
394e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        log("onDataReconnect: currSubId = " + currSubId + " phoneSubId=" + phoneSubId);
3951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // Stop reconnect if not current subId is not correct.
3971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // FIXME STOPSHIP - phoneSubId is coming up as -1 way after boot and failing this?
3981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (!SubscriptionManager.isValidSubscriptionId(currSubId) || (currSubId != phoneSubId)) {
3991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("receive ReconnectAlarm but subId incorrect, ignore");
4001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return;
4011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnContext apnContext = mApnContexts.get(apnType);
4041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
406e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu            log("onDataReconnect: mState=" + mState + " reason=" + reason + " apnType=" + apnType
407e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                    + " apnContext=" + apnContext + " mDataConnectionAsyncChannels="
408e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                    + mDataConnectionAcHashMap);
4091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if ((apnContext != null) && (apnContext.isEnabled())) {
4121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            apnContext.setReason(reason);
4131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            DctConstants.State apnContextState = apnContext.getState();
4141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
415e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                log("onDataReconnect: apnContext state=" + apnContextState);
4161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
4171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if ((apnContextState == DctConstants.State.FAILED)
4181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    || (apnContextState == DctConstants.State.IDLE)) {
4191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
420e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                    log("onDataReconnect: state is FAILED|IDLE, disassociate");
4211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
4221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DcAsyncChannel dcac = apnContext.getDcAc();
4231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (dcac != null) {
4241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (DBG) {
425e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                        log("onDataReconnect: tearDown apnContext=" + apnContext);
4261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
4271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    dcac.tearDown(apnContext, "", null);
4281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
4291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                apnContext.setDataConnectionAc(null);
4301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                apnContext.setState(DctConstants.State.IDLE);
4311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
432e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                if (DBG) log("onDataReconnect: keep associated");
4331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
4341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // TODO: IF already associated should we send the EVENT_TRY_SETUP_DATA???
4351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            sendMessage(obtainMessage(DctConstants.EVENT_TRY_SETUP_DATA, apnContext));
4361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            apnContext.setReconnectIntent(null);
4381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
4401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onActionIntentDataStallAlarm(Intent intent) {
4421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("onActionIntentDataStallAlarm: action=" + intent.getAction());
4431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_DATA_STALL_ALARM,
4441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                intent.getAction());
4451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = intent.getIntExtra(DATA_STALL_ALARM_TAG_EXTRA, 0);
4461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
4471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
4481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final ConnectivityManager mCm;
450c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
451b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla    /**
452a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * List of messages that are waiting to be posted, when data call disconnect
453a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * is complete
454a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
455a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ArrayList<Message> mDisconnectAllCompleteMsgList = new ArrayList<Message>();
456a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
457a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private RegistrantList mAllDataDisconnectedRegistrants = new RegistrantList();
458a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // member variables
4601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final Phone mPhone;
4611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final UiccController mUiccController;
4621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
4631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DctConstants.Activity mActivity = DctConstants.Activity.NONE;
4641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DctConstants.State mState = DctConstants.State.IDLE;
4651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final Handler mDataConnectionTracker;
4661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private long mTxPkts;
4681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private long mRxPkts;
4691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mNetStatPollPeriod;
4701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mNetStatPollEnabled = false;
4711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private TxRxSum mDataStallTxRxSum = new TxRxSum(0, 0);
4731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Used to track stale data stall alarms.
4741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mDataStallAlarmTag = (int) SystemClock.elapsedRealtime();
4751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // The current data stall alarm intent
4761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private PendingIntent mDataStallAlarmIntent = null;
4771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Number of packets sent since the last received packet
4781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private long mSentSinceLastRecv;
4791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Controls when a simple recovery attempt it to be tried
4801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mNoRecvPollCount = 0;
4810e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    // Reference counter for enabling fail fast
4821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static int sEnableFailFastRefCounter = 0;
4831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // True if data stall detection is enabled
4841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private volatile boolean mDataStallDetectionEnabled = true;
4851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private volatile boolean mFailFast = false;
4871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // True when in voice call
4891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mInVoiceCall = false;
4901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // wifi connection status will be updated by sticky intent
4921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsWifiConnected = false;
4931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Intent sent when the reconnect alarm fires. */
4951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private PendingIntent mReconnectIntent = null;
4961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // When false we will not auto attach and manually attaching is required.
4981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mAutoAttachOnCreationConfig = false;
4991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private AtomicBoolean mAutoAttachOnCreation = new AtomicBoolean(false);
5001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // State of screen
5021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // (TODO: Reconsider tying directly to screen, maybe this is
5031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    //        really a lower power mode")
5041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsScreenOn = true;
5051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Indicates if we found mvno-specific APNs in the full APN list.
5071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // used to determine if we can accept mno-specific APN for tethering.
5081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mMvnoMatched = false;
5091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Allows the generation of unique Id's for DataConnection objects */
5111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private AtomicInteger mUniqueIdGenerator = new AtomicInteger(0);
5121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** The data connections. */
5141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private HashMap<Integer, DataConnection> mDataConnections =
5151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new HashMap<Integer, DataConnection>();
5161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** The data connection async channels */
5181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private HashMap<Integer, DcAsyncChannel> mDataConnectionAcHashMap =
5191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new HashMap<Integer, DcAsyncChannel>();
5201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Convert an ApnType string to Id (TODO: Use "enumeration" instead of String for ApnType) */
5221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private HashMap<String, Integer> mApnToDataConnectionId = new HashMap<String, Integer>();
5231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Phone.APN_TYPE_* ===> ApnContext */
5251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final ConcurrentHashMap<String, ApnContext> mApnContexts =
5261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new ConcurrentHashMap<String, ApnContext>();
5271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
528af5593594070f825032be46dced573cd195956e1Robert Greenwalt    private final SparseArray<ApnContext> mApnContextsById = new SparseArray<ApnContext>();
529af5593594070f825032be46dced573cd195956e1Robert Greenwalt
5301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mDisconnectPendingCount = 0;
531a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
5324c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu    /** Indicate if metered APNs are disabled.
5334c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu     *  set to block all the metered APNs from continuously sending requests, which causes
5344c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu     *  undesired network load */
5354c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu    private boolean mMeteredApnDisabled = false;
53668f4f4a0bc8d4060b5775e7a24a97ea5b485989efionaxu
537a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
5384b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * int to remember whether has setDataProfiles and with roaming or not.
5394b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * 0: default, has never set data profile
5404b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * 1: has set data profile with home protocol
5414b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * 2: has set data profile with roaming protocol
5424b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * This is not needed once RIL command is updated to support both home and roaming protocol.
5434b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     */
5444b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu    private int mSetDataProfileStatus = 0;
5454b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu
5464b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu    /**
547cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Handles changes to the APN db.
548b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla     */
549cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private class ApnChangeObserver extends ContentObserver {
550cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public ApnChangeObserver () {
551cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            super(mDataConnectionTracker);
552cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
553c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
554cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
555cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public void onChange(boolean selfChange) {
556cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            sendMessage(obtainMessage(DctConstants.EVENT_APN_CHANGED));
557cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
558cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
559c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
560cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Instance Variables
561c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
562cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean mReregisterOnReconnectFailure = false;
563c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
564c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
565cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Constants
566c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
567ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    // Used by puppetmaster/*/radio_stress.py
568ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private static final String PUPPET_MASTER_RADIO_STRESS_TEST = "gsm.defaultpdpcontext.active";
569c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
570ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private static final int POLL_PDP_MILLIS = 5 * 1000;
571c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
5722b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen    private static final int PROVISIONING_SPINNER_TIMEOUT_MILLIS = 120 * 1000;
5732b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen
5746bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville    static final Uri PREFERAPN_NO_UPDATE_URI_USING_SUBID =
5756bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville                        Uri.parse("content://telephony/carriers/preferapn_no_update/subId/");
576cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final String APN_ID = "apn_id";
577cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
578ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private boolean mCanSetPreferApn = false;
579c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
580187a39f896f88eb6c5e4306d9595546654825976Wink Saville    private AtomicBoolean mAttached = new AtomicBoolean(false);
581187a39f896f88eb6c5e4306d9595546654825976Wink Saville
582cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** Watches for changes to the APN db. */
583cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ApnChangeObserver mApnObserver;
584cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
585b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private final String mProvisionActionName;
586b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private BroadcastReceiver mProvisionBroadcastReceiver;
5872b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen    private ProgressDialog mProvisioningSpinner;
588b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
589a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean mImsRegistrationState = false;
590a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
591cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Constructor
5921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public DcTracker(Phone phone) {
5931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        super();
5941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone = phone;
5951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("DCT.constructor");
5971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mResolver = mPhone.getContext().getContentResolver();
5991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mUiccController = UiccController.getInstance();
6001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mUiccController.registerForIccChanged(this, DctConstants.EVENT_ICC_CHANGED, null);
6011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mAlarmManager =
6021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
6031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mCm = (ConnectivityManager) mPhone.getContext().getSystemService(
6041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Context.CONNECTIVITY_SERVICE);
6051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        IntentFilter filter = new IntentFilter();
6081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(Intent.ACTION_SCREEN_ON);
6091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(Intent.ACTION_SCREEN_OFF);
6101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
6111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
6121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(INTENT_DATA_STALL_ALARM);
6131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(INTENT_PROVISIONING_APN_ALARM);
61421e6af8d6197a071d025733fffeffc157d0085bcfionaxu        filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
615985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen
616985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen        mDataEnabledSettings = new DataEnabledSettings(phone);
6171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
6191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
6211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mAutoAttachOnCreation.set(sp.getBoolean(Phone.DATA_DISABLED_ON_BOOT_KEY, false));
6221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mSubscriptionManager = SubscriptionManager.from(mPhone.getContext());
6241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
6251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        HandlerThread dcHandlerThread = new HandlerThread("DcHandlerThread");
6271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        dcHandlerThread.start();
6281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Handler dcHandler = new Handler(dcHandlerThread.getLooper());
6291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcc = DcController.makeDcc(mPhone, this, dcHandler);
6301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcTesterFailBringUpAll = new DcTesterFailBringUpAll(mPhone, dcHandler);
631cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
632cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mDataConnectionTracker = this;
633c374098c17a81f73f51e9d7df99eba574882949bYifan Bai        registerForAllEvents();
634a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        update();
635cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mApnObserver = new ApnChangeObserver();
6361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        phone.getContext().getContentResolver().registerContentObserver(
637cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                Telephony.Carriers.CONTENT_URI, true, mApnObserver);
638cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
639d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        initApnContexts();
640d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
641d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        for (ApnContext apnContext : mApnContexts.values()) {
642d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            // Register the reconnect and restart actions.
6431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            filter = new IntentFilter();
644d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            filter.addAction(INTENT_RECONNECT_ALARM + '.' + apnContext.getApnType());
645d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
646d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        }
647d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
64876f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Add Emergency APN to APN setting list by default to support EPDN in sim absent cases
64976f43316a5a6082d601bffd4b6898d0bd81e11fcram        initEmergencyApnSetting();
65076f43316a5a6082d601bffd4b6898d0bd81e11fcram        addEmergencyApnSetting();
651b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
6521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisionActionName = "com.android.internal.telephony.PROVISION" + phone.getPhoneId();
653f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
654f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver = new SettingsObserver(mPhone.getContext(), this);
655f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        registerSettingsObserver();
6561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
6571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
658af5593594070f825032be46dced573cd195956e1Robert Greenwalt    @VisibleForTesting
659af5593594070f825032be46dced573cd195956e1Robert Greenwalt    public DcTracker() {
660af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mAlarmManager = null;
661af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mCm = null;
662af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mPhone = null;
663af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mUiccController = null;
664af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mDataConnectionTracker = null;
665af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mProvisionActionName = null;
666f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver = new SettingsObserver(null, this);
667985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen        mDataEnabledSettings = null;
668af5593594070f825032be46dced573cd195956e1Robert Greenwalt    }
669af5593594070f825032be46dced573cd195956e1Robert Greenwalt
6701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void registerServiceStateTrackerEvents() {
6711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataConnectionAttached(this,
6721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null);
6731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataConnectionDetached(this,
6741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_DATA_CONNECTION_DETACHED, null);
6751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataRoamingOn(this,
6761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_ROAMING_ON, null);
6771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataRoamingOff(this,
6780d6ff7958dac61b9e2d689267c34ddfa0c666d9dfionaxu                DctConstants.EVENT_ROAMING_OFF, null, true);
6791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForPsRestrictedEnabled(this,
6801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_PS_RESTRICT_ENABLED, null);
6811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForPsRestrictedDisabled(this,
6821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_PS_RESTRICT_DISABLED, null);
6831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(this,
6841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_DATA_RAT_CHANGED, null);
685cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
686c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
6871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void unregisterServiceStateTrackerEvents() {
6881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataConnectionAttached(this);
6891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataConnectionDetached(this);
6901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataRoamingOn(this);
6911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataRoamingOff(this);
6921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForPsRestrictedEnabled(this);
6931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForPsRestrictedDisabled(this);
6941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged(this);
6951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
6961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void registerForAllEvents() {
698a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.mCi.registerForAvailable(this, DctConstants.EVENT_RADIO_AVAILABLE, null);
699a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.mCi.registerForOffOrNotAvailable(this,
7009c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
70137a3e51d244774ba156a88cf101432b62c8a42a3Jack Yu        mPhone.mCi.registerForDataCallListChanged(this,
7029c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                DctConstants.EVENT_DATA_STATE_CHANGED, null);
7030710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // Note, this is fragile - the Phone is now presenting a merged picture
7040710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // of PS (volte) & CS and by diving into its internals you're just seeing
7050710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // the CS data.  This works well for the purposes this is currently used for
7060710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // but that may not always be the case.  Should probably be redesigned to
7070710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // accurately reflect what we're really interested in (registerForCSVoiceCallEnded).
7081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getCallTracker().registerForVoiceCallEnded(this,
7091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_VOICE_CALL_ENDED, null);
7101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getCallTracker().registerForVoiceCallStarted(this,
7111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_VOICE_CALL_STARTED, null);
7121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        registerServiceStateTrackerEvents();
713a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     //   SubscriptionManager.registerForDdsSwitch(this,
714a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     //          DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS, null);
7152e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        mPhone.mCi.registerForPcoData(this, DctConstants.EVENT_PCO_DATA_RECEIVED, null);
7166a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu        mPhone.getCarrierActionAgent().registerForCarrierAction(
7176a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu                CarrierActionAgent.CARRIER_ACTION_SET_METERED_APNS_ENABLED, this,
7186a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu                DctConstants.EVENT_SET_CARRIER_DATA_ENABLED, null, false);
719a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
7201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
721cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void dispose() {
7221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("DCT.dispose");
7234dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt
724b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        if (mProvisionBroadcastReceiver != null) {
725b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            mPhone.getContext().unregisterReceiver(mProvisionBroadcastReceiver);
726b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            mProvisionBroadcastReceiver = null;
727b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
7282b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        if (mProvisioningSpinner != null) {
7292b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.dismiss();
7302b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner = null;
7312b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        }
732b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
733cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, null);
734cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
7351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
7361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            dcac.disconnect();
7371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
7381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDataConnectionAcHashMap.clear();
7391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mIsDisposed = true;
7401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getContext().unregisterReceiver(mIntentReceiver);
7411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mUiccController.unregisterForIccChanged(this);
742f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.unobserve();
743f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
7441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mSubscriptionManager
7451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                .removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
7461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcc.dispose();
7471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcTesterFailBringUpAll.dispose();
748cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
749a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getContext().getContentResolver().unregisterContentObserver(mApnObserver);
750a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mApnContexts.clear();
751af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mApnContextsById.clear();
752a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPrioritySortedApnContexts.clear();
753c374098c17a81f73f51e9d7df99eba574882949bYifan Bai        unregisterForAllEvents();
754a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
755a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        destroyDataConnections();
756a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
7571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void unregisterForAllEvents() {
759a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         //Unregister for all events
76022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.unregisterForAvailable(this);
76122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.unregisterForOffOrNotAvailable(this);
762cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
763a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (r != null) {
764a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            r.unregisterForRecordsLoaded(this);
765a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mIccRecords.set(null);
766a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
76737a3e51d244774ba156a88cf101432b62c8a42a3Jack Yu        mPhone.mCi.unregisterForDataCallListChanged(this);
768cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getCallTracker().unregisterForVoiceCallEnded(this);
769cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getCallTracker().unregisterForVoiceCallStarted(this);
7701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        unregisterServiceStateTrackerEvents();
771a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        //SubscriptionManager.unregisterForDdsSwitch(this);
7722e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        mPhone.mCi.unregisterForPcoData(this);
7736a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu        mPhone.getCarrierActionAgent().unregisterForCarrierAction(this,
7746a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu                CarrierActionAgent.CARRIER_ACTION_SET_METERED_APNS_ENABLED);
775cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
776cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
7771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
7781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Called when EVENT_RESET_DONE is received so goto
7791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * IDLE state and send notifications to those interested.
7801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     *
7811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * TODO - currently unused.  Needs to be hooked into DataConnection cleanup
7821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * TODO - needs to pass some notion of which connection is reset..
7831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
7841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onResetDone(AsyncResult ar) {
7851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("EVENT_RESET_DONE");
7861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        String reason = null;
7871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (ar.userObj instanceof String) {
7881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            reason = (String) ar.userObj;
7891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
7901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        gotoIdleAndNotifyDataConnection(reason);
7911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
7921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
7941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Modify {@link android.provider.Settings.Global#MOBILE_DATA} value.
7951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
7961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void setDataEnabled(boolean enable) {
7971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.CMD_SET_USER_DATA_ENABLE);
7981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = enable ? 1 : 0;
7991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("setDataEnabled: sendMessage: enable=" + enable);
8001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
8011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
8021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetUserDataEnabled(boolean enabled) {
804a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        synchronized (mDataEnabledSettings) {
805a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            if (mDataEnabledSettings.isUserDataEnabled() != enabled) {
806a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                mDataEnabledSettings.setUserDataEnabled(enabled);
8075b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu                if (!getDataRoamingEnabled() && mPhone.getServiceState().getDataRoaming()) {
8081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (enabled) {
8091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
8101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
8111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        notifyOffApnsOfAvailability(Phone.REASON_DATA_DISABLED);
8121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
8131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
8141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
815fcd5efef57e734966ed373ab7a4ce419d0034ceczxuan                mPhone.notifyUserMobileDataStateChanged(enabled);
816fcd5efef57e734966ed373ab7a4ce419d0034ceczxuan
817a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                // TODO: We should register for DataEnabledSetting's data enabled/disabled event and
818a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                // handle the rest from there.
8191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (enabled) {
820120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    reevaluateDataConnections();
8211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onTrySetupData(Phone.REASON_DATA_ENABLED);
8221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
8231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);
8241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
8251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
8261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
8271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
8281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8295292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt    /**
830120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * Reevaluate existing data connections when conditions change.
831120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     *
832120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * For example, handle reverting restricted networks back to unrestricted. If we're changing
833120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * user data to enabled and this makes data truly enabled (not disabled by other factors) we
834120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * need to tear down any metered apn type that was enabled anyway by a privileged request.
835120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * This allows us to reconnect to it in an unrestricted way.
836120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     *
837120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * Or when we brought up a unmetered data connection while data is off, we only limit this
838120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * data connection for unmetered use only. When data is turned back on, we need to tear that
839120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * down so a full capable data connection can be re-established.
8405292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt     */
841120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu    private void reevaluateDataConnections() {
842120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        if (mDataEnabledSettings.isDataEnabled()) {
8435292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt            for (ApnContext apnContext : mApnContexts.values()) {
844120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                if (apnContext.isConnectedOrConnecting()) {
845120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    final DcAsyncChannel dcac = apnContext.getDcAc();
846120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    if (dcac != null) {
847120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                        final NetworkCapabilities netCaps = dcac.getNetworkCapabilitiesSync();
848120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                        if (netCaps != null && !netCaps.hasCapability(NetworkCapabilities
849ee00c053e0cbbbdb22737c923b1a214e10453646Jack Yu                                .NET_CAPABILITY_NOT_RESTRICTED) && !netCaps.hasCapability(
850ee00c053e0cbbbdb22737c923b1a214e10453646Jack Yu                                NetworkCapabilities.NET_CAPABILITY_NOT_METERED)) {
851120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            if (DBG) {
852ee00c053e0cbbbdb22737c923b1a214e10453646Jack Yu                                log("Tearing down restricted metered net:" + apnContext);
853120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            }
854ee00c053e0cbbbdb22737c923b1a214e10453646Jack Yu                            // Tearing down the restricted metered data call when
855120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // conditions change. This will allow reestablishing a new unrestricted
856120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // data connection.
857120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            apnContext.setReason(Phone.REASON_DATA_ENABLED);
858120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            cleanUpConnection(true, apnContext);
85950734be549285702de00295778b8c2a4360215a0Jack Yu                        } else if (apnContext.getApnSetting().isMetered(mPhone)
860120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                                && (netCaps != null && netCaps.hasCapability(
861120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                                        NetworkCapabilities.NET_CAPABILITY_NOT_METERED))) {
862120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            if (DBG) {
863120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                                log("Tearing down unmetered net:" + apnContext);
864120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            }
865120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // The APN settings is metered, but the data was still marked as
866120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // unmetered data, must be the unmetered data connection brought up when
867120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // data is off. We need to tear that down when data is enabled again.
868120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // This will allow reestablishing a new full capability data connection.
869120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            apnContext.setReason(Phone.REASON_DATA_ENABLED);
870120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            cleanUpConnection(true, apnContext);
87176c5a9479d312139740dcaf7644172f2beb2f7e0Robert Greenwalt                        }
87276c5a9479d312139740dcaf7644172f2beb2f7e0Robert Greenwalt                    }
8735292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt                }
8745292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt            }
8755292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt        }
8765292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt    }
8775292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt
878f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    private void onDeviceProvisionedChange() {
879985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen        if (isDataEnabled()) {
880120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu            reevaluateDataConnections();
881f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            onTrySetupData(Phone.REASON_DATA_ENABLED);
882f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        } else {
883f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);
884f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        }
885f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    }
8861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public long getSubId() {
8891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mPhone.getSubId();
8901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
8911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public DctConstants.Activity getActivity() {
8931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mActivity;
8941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
8951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void setActivity(DctConstants.Activity activity) {
8971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("setActivity = " + activity);
8981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mActivity = activity;
8991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.notifyDataActivity();
9001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
9011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
902af5593594070f825032be46dced573cd195956e1Robert Greenwalt    public void requestNetwork(NetworkRequest networkRequest, LocalLog log) {
903af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final int apnId = ApnContext.apnIdForNetworkRequest(networkRequest);
904af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final ApnContext apnContext = mApnContextsById.get(apnId);
905af5593594070f825032be46dced573cd195956e1Robert Greenwalt        log.log("DcTracker.requestNetwork for " + networkRequest + " found " + apnContext);
906692640f429efa8e292c6261472b2c682e1079f8eRobert Greenwalt        if (apnContext != null) apnContext.requestNetwork(networkRequest, log);
907af5593594070f825032be46dced573cd195956e1Robert Greenwalt    }
908af5593594070f825032be46dced573cd195956e1Robert Greenwalt
909af5593594070f825032be46dced573cd195956e1Robert Greenwalt    public void releaseNetwork(NetworkRequest networkRequest, LocalLog log) {
910af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final int apnId = ApnContext.apnIdForNetworkRequest(networkRequest);
911af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final ApnContext apnContext = mApnContextsById.get(apnId);
912af5593594070f825032be46dced573cd195956e1Robert Greenwalt        log.log("DcTracker.releaseNetwork for " + networkRequest + " found " + apnContext);
913692640f429efa8e292c6261472b2c682e1079f8eRobert Greenwalt        if (apnContext != null) apnContext.releaseNetwork(networkRequest, log);
914af5593594070f825032be46dced573cd195956e1Robert Greenwalt    }
915af5593594070f825032be46dced573cd195956e1Robert Greenwalt
916bda761320929f714951c328bfec6a51a1978db97Wink Saville    public boolean isApnSupported(String name) {
91791bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal        if (name == null) {
91891bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal            loge("isApnSupported: name=null");
91991bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal            return false;
92091bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal        }
921bda761320929f714951c328bfec6a51a1978db97Wink Saville        ApnContext apnContext = mApnContexts.get(name);
922bda761320929f714951c328bfec6a51a1978db97Wink Saville        if (apnContext == null) {
923bda761320929f714951c328bfec6a51a1978db97Wink Saville            loge("Request for unsupported mobile name: " + name);
924bda761320929f714951c328bfec6a51a1978db97Wink Saville            return false;
925071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
926bda761320929f714951c328bfec6a51a1978db97Wink Saville        return true;
927bda761320929f714951c328bfec6a51a1978db97Wink Saville    }
928071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
929bda761320929f714951c328bfec6a51a1978db97Wink Saville    public int getApnPriority(String name) {
930071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        ApnContext apnContext = mApnContexts.get(name);
931071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (apnContext == null) {
932bda761320929f714951c328bfec6a51a1978db97Wink Saville            loge("Request for unsupported mobile name: " + name);
933071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
934bda761320929f714951c328bfec6a51a1978db97Wink Saville        return apnContext.priority;
935071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt    }
936071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
937b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    // Turn telephony radio on or off.
938b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private void setRadio(boolean on) {
939b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        final ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
940b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        try {
941b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            phone.setRadio(on);
942b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        } catch (Exception e) {
943b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            // Ignore.
944b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
945b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    }
946b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
947b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    // Class to handle Intent dispatched with user selects the "Sign-in to network"
948b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    // notification.
949b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private class ProvisionNotificationBroadcastReceiver extends BroadcastReceiver {
9502b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        private final String mNetworkOperator;
951b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        // Mobile provisioning URL.  Valid while provisioning notification is up.
952b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        // Set prior to notification being posted as URL contains ICCID which
953b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        // disappears when radio is off (which is the case when notification is up).
954b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        private final String mProvisionUrl;
955b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
9562b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        public ProvisionNotificationBroadcastReceiver(String provisionUrl, String networkOperator) {
9572b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mNetworkOperator = networkOperator;
958b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            mProvisionUrl = provisionUrl;
959b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
960b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
961b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        private void setEnableFailFastMobileData(int enabled) {
9626395443719ec3ee0257085945e753d02f603886bRobert Greenwalt            sendMessage(obtainMessage(DctConstants.CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA, enabled, 0));
963b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
964b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
965b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        private void enableMobileProvisioning() {
966b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            final Message msg = obtainMessage(DctConstants.CMD_ENABLE_MOBILE_PROVISIONING);
967b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            msg.setData(Bundle.forPair(DctConstants.PROVISIONING_URL_KEY, mProvisionUrl));
968b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            sendMessage(msg);
969b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
970b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
971b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        @Override
972b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        public void onReceive(Context context, Intent intent) {
9732b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // Turning back on the radio can take time on the order of a minute, so show user a
9742b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // spinner so they know something is going on.
975636fbb01fd32e23d1e9ef86497115b2c992b03daSanket Padawe            log("onReceive : ProvisionNotificationBroadcastReceiver");
9762b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner = new ProgressDialog(context);
9772b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setTitle(mNetworkOperator);
9782b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setMessage(
9792b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    // TODO: Don't borrow "Connecting..." i18n string; give Telephony a version.
9802b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    context.getText(com.android.internal.R.string.media_route_status_connecting));
9812b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setIndeterminate(true);
9822b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setCancelable(true);
9832b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // Allow non-Activity Service Context to create a View.
9842b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.getWindow().setType(
9852b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
9862b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.show();
9872b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // After timeout, hide spinner so user can at least use their device.
9882b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // TODO: Indicate to user that it is taking an unusually long time to connect?
9892b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            sendMessageDelayed(obtainMessage(DctConstants.CMD_CLEAR_PROVISIONING_SPINNER,
9902b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner), PROVISIONING_SPINNER_TIMEOUT_MILLIS);
991b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            // This code is almost identical to the old
992b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            // ConnectivityService.handleMobileProvisioningAction code.
993b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            setRadio(true);
994b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            setEnableFailFastMobileData(DctConstants.ENABLED);
995b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            enableMobileProvisioning();
996b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
997b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    }
998b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
999cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1000cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void finalize() {
10017e9240253edb59e0aa657de434faa1ccdf17a742Amit Mahajan        if(DBG && mPhone != null) log("finalize");
1002cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1003cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
10044a9b3afeb2ec4d573eca335a3706392ecf9f281eWink Saville    private ApnContext addApnContext(String type, NetworkConfig networkConfig) {
10050e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        ApnContext apnContext = new ApnContext(mPhone, type, LOG_TAG, networkConfig, this);
1006cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mApnContexts.put(type, apnContext);
1007af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mApnContextsById.put(ApnContext.apnIdForApnName(type), apnContext);
10083fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        mPrioritySortedApnContexts.add(apnContext);
1009bce3d2575122929bb27ec8a37d56e96da39a3ca2Robert Greenwalt        return apnContext;
1010cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1011c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
10121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void initApnContexts() {
1013d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        log("initApnContexts: E");
1014d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        // Load device network attributes from resources
1015d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        String[] networkConfigStrings = mPhone.getContext().getResources().getStringArray(
1016d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                com.android.internal.R.array.networkAttributes);
1017d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        for (String networkConfigString : networkConfigStrings) {
1018d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            NetworkConfig networkConfig = new NetworkConfig(networkConfigString);
1019d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            ApnContext apnContext = null;
1020d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
1021d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            switch (networkConfig.type) {
1022d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE:
1023d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_DEFAULT, networkConfig);
1024d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1025d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_MMS:
1026d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_MMS, networkConfig);
1027d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1028d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_SUPL:
1029d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_SUPL, networkConfig);
1030d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1031d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_DUN:
1032d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_DUN, networkConfig);
1033d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1034d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_HIPRI:
1035d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_HIPRI, networkConfig);
1036d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1037d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_FOTA:
1038d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_FOTA, networkConfig);
1039d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1040d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_IMS:
1041d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_IMS, networkConfig);
1042d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1043d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_CBS:
1044d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_CBS, networkConfig);
1045d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1046d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_IA:
1047d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_IA, networkConfig);
1048d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1049cf5205f70eb1eac497164124187a088ecb03fff5Ram            case ConnectivityManager.TYPE_MOBILE_EMERGENCY:
1050cf5205f70eb1eac497164124187a088ecb03fff5Ram                apnContext = addApnContext(PhoneConstants.APN_TYPE_EMERGENCY, networkConfig);
1051cf5205f70eb1eac497164124187a088ecb03fff5Ram                break;
1052d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            default:
1053d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                log("initApnContexts: skipping unknown type=" + networkConfig.type);
1054d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                continue;
1055d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            }
1056d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            log("initApnContexts: apnContext=" + apnContext);
1057d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        }
1058092e6bd60f1a4a3a55fb73ad0efca1122b8e15e2Jack Yu
1059092e6bd60f1a4a3a55fb73ad0efca1122b8e15e2Jack Yu        if (VDBG) log("initApnContexts: X mApnContexts=" + mApnContexts);
1060d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt    }
1061d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
1062cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public LinkProperties getLinkProperties(String apnType) {
1063cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1064cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
1065454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = apnContext.getDcAc();
1066cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac != null) {
1067cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("return link properites for " + apnType);
1068cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return dcac.getLinkPropertiesSync();
1069cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1070cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1071cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("return new LinkProperties");
1072cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return new LinkProperties();
1073cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1074cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1075608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt    public NetworkCapabilities getNetworkCapabilities(String apnType) {
1076608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        ApnContext apnContext = mApnContexts.get(apnType);
1077608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        if (apnContext!=null) {
1078608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            DcAsyncChannel dataConnectionAc = apnContext.getDcAc();
1079608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            if (dataConnectionAc != null) {
1080608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                if (DBG) {
1081608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                    log("get active pdp is not null, return NetworkCapabilities for " + apnType);
1082608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                }
1083608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                return dataConnectionAc.getNetworkCapabilitiesSync();
1084608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            }
1085608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        }
1086608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        if (DBG) log("return new NetworkCapabilities");
1087608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        return new NetworkCapabilities();
1088608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt    }
1089cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1090cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return all active apn types
1091cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public String[] getActiveApnTypes() {
1092cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("get all active apn types");
1093cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ArrayList<String> result = new ArrayList<String>();
1094cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1095cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1096187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (mAttached.get() && apnContext.isReady()) {
1097cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                result.add(apnContext.getApnType());
1098cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
1099cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1100c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1101cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result.toArray(new String[0]);
1102cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1103cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1104cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return active apn of specific apn type
1105cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public String getActiveApnString(String apnType) {
1106ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (VDBG) log( "get active apn string for type:" + apnType);
1107cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1108cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
1109cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ApnSetting apnSetting = apnContext.getApnSetting();
1110cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnSetting != null) {
1111cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return apnSetting.apn;
1112cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1113cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1114cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
1115cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1116cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1117cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return state of specific apn type
1118cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public DctConstants.State getState(String apnType) {
1119cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1120cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
1121cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return apnContext.getState();
1122c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1123cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return DctConstants.State.FAILED;
1124cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1125c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1126c9b81a0c05128694c617fcdd67e73821895822feWink Saville    // Return if apn type is a provisioning apn.
11271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean isProvisioningApn(String apnType) {
1128c9b81a0c05128694c617fcdd67e73821895822feWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1129c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (apnContext != null) {
1130c9b81a0c05128694c617fcdd67e73821895822feWink Saville            return apnContext.isProvisioningApn();
1131c9b81a0c05128694c617fcdd67e73821895822feWink Saville        }
1132c9b81a0c05128694c617fcdd67e73821895822feWink Saville        return false;
1133c9b81a0c05128694c617fcdd67e73821895822feWink Saville    }
1134c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1135cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return state of overall
1136cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public DctConstants.State getOverallState() {
1137cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isConnecting = false;
1138cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isFailed = true; // All enabled Apns should be FAILED.
1139cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isAnyEnabled = false;
1140cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1141cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1142cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.isEnabled()) {
1143cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                isAnyEnabled = true;
1144cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                switch (apnContext.getState()) {
1145cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case CONNECTED:
1146cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case DISCONNECTING:
11471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (VDBG) log("overall state is CONNECTED");
1148cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return DctConstants.State.CONNECTED;
1149ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                case RETRYING:
1150cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case CONNECTING:
1151cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isConnecting = true;
1152cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isFailed = false;
1153cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
1154cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case IDLE:
1155cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case SCANNING:
1156cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isFailed = false;
1157cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
1158cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                default:
1159cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isAnyEnabled = true;
1160cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
1161cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1162cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1163c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1164c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1165cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (!isAnyEnabled) { // Nothing enabled. return IDLE.
11661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is IDLE");
1167cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.IDLE;
1168c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1169c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1170cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnecting) {
11711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is CONNECTING");
1172cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.CONNECTING;
1173cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (!isFailed) {
11741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is IDLE");
1175cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.IDLE;
1176cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
11771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is FAILED");
1178cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.FAILED;
1179c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1180c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1181c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
11820b03bcd1eccc833d5cac5ecf937cf0e037375561Jack Yu    @VisibleForTesting
1183120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu    public boolean isDataEnabled() {
1184120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        return mDataEnabledSettings.isDataEnabled();
1185a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1186a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1187cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //****** Called from ServiceStateTracker
1188c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1189cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Invoked when ServiceStateTracker observes a transition from GPRS
1190cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * attach to detach.
1191c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
11921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataConnectionDetached() {
1193cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        /*
1194cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * We presently believe it is unnecessary to tear down the PDP context
1195cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * when GPRS detaches, but we should stop the network polling.
1196cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         */
1197cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log ("onDataConnectionDetached: stop polling and notify detached");
1198cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopNetStatPoll();
1199cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopDataStallAlarm();
1200cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyDataConnection(Phone.REASON_DATA_DETACHED);
1201187a39f896f88eb6c5e4306d9595546654825976Wink Saville        mAttached.set(false);
1202cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1203c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1204cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onDataConnectionAttached() {
1205cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onDataConnectionAttached");
12067ab10e4710bdb54c6d9a5ee01cd443a42a2689f5Sungmin Choi        mAttached.set(true);
1207cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getOverallState() == DctConstants.State.CONNECTED) {
1208cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onDataConnectionAttached: start polling notify attached");
1209cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            startNetStatPoll();
1210cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
1211cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_DATA_ATTACHED);
1212cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1213cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // update APN availability so that APN can be enabled.
1214cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_DATA_ATTACHED);
1215cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
121612fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        if (mAutoAttachOnCreationConfig) {
1217aacc11b299ac047e73e1e712aa396ea0a6a80158Robert Greenwalt            mAutoAttachOnCreation.set(true);
121812fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        }
1219ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(Phone.REASON_DATA_ATTACHED);
1220cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1221c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
122299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu    /**
122399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * Check if it is allowed to make a data connection (without checking APN context specific
122499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * conditions).
122599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *
122699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @param dataConnectionReasons Data connection allowed or disallowed reasons as the output
122799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *                              param. It's okay to pass null here and no reasons will be
122899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *                              provided.
122999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @return True if data connection is allowed, otherwise false.
123099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     */
123199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu    public boolean isDataAllowed(DataConnectionReasons dataConnectionReasons) {
123299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        return isDataAllowed(null, dataConnectionReasons);
123399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu    }
123499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
123599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu    /**
123699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * Check if it is allowed to make a data connection for a given APN type.
123799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *
123899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @param apnContext APN context. If passing null, then will only check general but not APN
123999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *                   specific conditions (e.g. APN state, metered/unmetered APN).
124099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @param dataConnectionReasons Data connection allowed or disallowed reasons as the output
124199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *                              param. It's okay to pass null here and no reasons will be
124299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *                              provided.
124399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @return True if data connection is allowed, otherwise false.
124499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     */
124599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu    boolean isDataAllowed(ApnContext apnContext, DataConnectionReasons dataConnectionReasons) {
124699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 1: Get all environment conditions.
124799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 2: Special handling for emergency APN.
124899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 3. Build disallowed reasons.
124999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 4: Determine if data should be allowed in some special conditions.
125099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
125199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        DataConnectionReasons reasons = new DataConnectionReasons();
1252cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
125399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 1: Get all environment conditions.
125499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        final boolean internalDataEnabled = mDataEnabledSettings.isInternalDataEnabled();
12559894b3fb2f35e21d9cfd45f233ed093589e14c26sy.yun        boolean attachedState = mAttached.get();
1256cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
12570d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu        boolean radioStateFromCarrier = mPhone.getServiceStateTracker().getPowerStateFromCarrier();
125899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // TODO: Remove this hack added by ag/641832.
12590e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
12600e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        if (radioTech == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN) {
12610e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            desiredPowerState = true;
12620d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu            radioStateFromCarrier = true;
12630e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        }
12640e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh
126599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        boolean recordsLoaded = mIccRecords.get() != null && mIccRecords.get().getRecordsLoaded();
126699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
126799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        boolean defaultDataSelected = SubscriptionManager.isValidSubscriptionId(
126899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                SubscriptionManager.getDefaultDataSubscriptionId());
1269cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
127099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        boolean isMeteredApnType = apnContext == null
127150734be549285702de00295778b8c2a4360215a0Jack Yu                || ApnSetting.isMeteredApnType(apnContext.getApnType(), mPhone);
12723d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
127399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        PhoneConstants.State phoneState = PhoneConstants.State.IDLE;
12740710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // Note this is explicitly not using mPhone.getState.  See b/19090488.
12750710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // mPhone.getState reports the merge of CS and PS (volte) voice call state
12760710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // but we only care about CS calls here for data/voice concurrency issues.
12770710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // Calling getCallTracker currently gives you just the CS side where the
12780710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // ImsCallTracker is held internally where applicable.
12790710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // This should be redesigned to ask explicitly what we want:
12800710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // voiceCallStateAllowDataCall, or dataCallAllowed or something similar.
1281b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com        if (mPhone.getCallTracker() != null) {
128299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            phoneState = mPhone.getCallTracker().getState();
128399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
128499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
128599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 2: Special handling for emergency APN.
128699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (apnContext != null
128799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                && apnContext.getApnType().equals(PhoneConstants.APN_TYPE_EMERGENCY)
128899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                && apnContext.isConnectable()) {
128999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            // If this is an emergency APN, as long as the APN is connectable, we
129099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            // should allow it.
129199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            if (dataConnectionReasons != null) {
129299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                dataConnectionReasons.add(DataAllowedReasonType.EMERGENCY_APN);
129399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            }
129499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            // Bail out without further checks.
129599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            return true;
129699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
129799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
129899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 3. Build disallowed reasons.
129999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (apnContext != null && !apnContext.isConnectable()) {
130099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.APN_NOT_CONNECTABLE);
130199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
130299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
130399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // If RAT is IWLAN then don't allow default/IA PDP at all.
130499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Rest of APN types can be evaluated for remaining conditions.
130599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if ((apnContext != null && (apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
130699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                || apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IA)))
130799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                && (radioTech == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN)) {
130899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.ON_IWLAN);
130999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
131099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
131199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (isEmergency()) {
131299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.IN_ECBM);
1313b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com        }
13141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
13153d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!(attachedState || mAutoAttachOnCreation.get())) {
131699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.NOT_ATTACHED);
13173d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13183d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!recordsLoaded) {
131999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.RECORD_NOT_LOADED);
13203d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
132199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (phoneState != PhoneConstants.State.IDLE
132299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                && !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
132399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.INVALID_PHONE_STATE);
132499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.CONCURRENT_VOICE_DATA_NOT_ALLOWED);
13253d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13263d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!internalDataEnabled) {
132799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.INTERNAL_DATA_DISABLED);
13283d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13293d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!defaultDataSelected) {
133099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.DEFAULT_DATA_UNSELECTED);
13313d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13325b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (mPhone.getServiceState().getDataRoaming() && !getDataRoamingEnabled()) {
133399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.ROAMING_DISABLED);
1334c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
13353d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (mIsPsRestricted) {
133699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.PS_RESTRICTED);
13373d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13383d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!desiredPowerState) {
133999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.UNDESIRED_POWER_STATE);
13403d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13410d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu        if (!radioStateFromCarrier) {
134299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.RADIO_DISABLED_BY_CARRIER);
134399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
134499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (!mDataEnabledSettings.isDataEnabled()) {
134599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.DATA_DISABLED);
13460d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu        }
13473d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
134899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // If there are hard disallowed reasons, we should not allow data connection no matter what.
134999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (reasons.containsHardDisallowedReasons()) {
135099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            if (dataConnectionReasons != null) {
135199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                dataConnectionReasons.copyFrom(reasons);
135299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            }
135399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            return false;
135499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
135599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
135699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 4: Determine if data should be allowed in some special conditions.
135799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
135899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // At this point, if data is not allowed, it must be because of the soft reasons. We
135999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // should start to check some special conditions that data will be allowed.
136099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
136199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // If the request APN type is unmetered and there are soft disallowed reasons (e.g. data
136299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // disabled, data roaming disabled) existing, we should allow the data because the user
136399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // won't be charged anyway.
136499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (!isMeteredApnType && !reasons.allowed()) {
136599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataAllowedReasonType.UNMETERED_APN);
136699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
136799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
136899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // If the request is restricted and there are only soft disallowed reasons (e.g. data
136999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // disabled, data roaming disabled) existing, we should allow the data.
137099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (apnContext != null
137199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                && !apnContext.hasNoRestrictedRequests(true)
137299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                && !reasons.allowed()) {
137399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataAllowedReasonType.RESTRICTED_REQUEST);
137499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
137599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
137699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // If at this point, we still haven't built any disallowed reasons, we should allow data.
137799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (reasons.allowed()) {
137899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataAllowedReasonType.NORMAL);
137999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
138099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
138199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (dataConnectionReasons != null) {
138299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            dataConnectionReasons.copyFrom(reasons);
138399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
138499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
138599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        return reasons.allowed();
1386cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1387c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1388c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    // arg for setupDataOnConnectableApns
1389c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    private enum RetryFailures {
1390c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        // retry failed networks always (the old default)
1391c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        ALWAYS,
13920e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        // retry only when a substantial change has occurred.  Either:
1393c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        // 1) we were restricted by voice/data concurrency and aren't anymore
1394c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        // 2) our apn list has change
1395c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        ONLY_ON_CHANGE
1396c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    };
1397c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt
1398ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void setupDataOnConnectableApns(String reason) {
1399c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        setupDataOnConnectableApns(reason, RetryFailures.ALWAYS);
1400c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    }
1401c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt
1402c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    private void setupDataOnConnectableApns(String reason, RetryFailures retryFailures) {
14039c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        if (VDBG) log("setupDataOnConnectableApns: " + reason);
14043fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
1405c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu        if (DBG && !VDBG) {
1406c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            StringBuilder sb = new StringBuilder(120);
1407c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            for (ApnContext apnContext : mPrioritySortedApnContexts) {
1408c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(apnContext.getApnType());
1409c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(":[state=");
1410c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(apnContext.getState());
1411c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(",enabled=");
1412c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(apnContext.isEnabled());
1413c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append("] ");
1414c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            }
14159c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            log("setupDataOnConnectableApns: " + reason + " " + sb);
1416c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu        }
1417c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu
14183fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        for (ApnContext apnContext : mPrioritySortedApnContexts) {
1419c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            if (VDBG) log("setupDataOnConnectableApns: apnContext " + apnContext);
1420c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu
1421735bc2f4524d68155765351912ffae11306c3bd5Chris Manton            if (apnContext.getState() == DctConstants.State.FAILED
14220e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                    || apnContext.getState() == DctConstants.State.SCANNING) {
1423c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                if (retryFailures == RetryFailures.ALWAYS) {
1424ee665b78ad648abd98b019a9c9047f206ed22994Robert Greenwalt                    apnContext.releaseDataConnection(reason);
1425c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                } else if (apnContext.isConcurrentVoiceAndDataAllowed() == false &&
14260e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                        mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
1427c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    // RetryFailures.ONLY_ON_CHANGE - check if voice concurrency has changed
1428ee665b78ad648abd98b019a9c9047f206ed22994Robert Greenwalt                    apnContext.releaseDataConnection(reason);
1429c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                }
1430cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1431ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.isConnectable()) {
14329c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                log("isConnectable() call trySetupData");
1433ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setReason(reason);
1434ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                trySetupData(apnContext);
1435cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1436cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1437c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1438c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
14391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    boolean isEmergency() {
1440a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        final boolean result = mPhone.isInEcm() || mPhone.isInEmergencyCall();
14411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("isEmergency: result=" + result);
14421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return result;
14431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
14441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1445cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean trySetupData(ApnContext apnContext) {
1446cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1447cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
1448cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
1449cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
1450cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setState(DctConstants.State.CONNECTED);
1451cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1452cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1453cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("trySetupData: X We're on the simulator; assuming connected retValue=true");
1454cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return true;
1455cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1456cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
145799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        DataConnectionReasons dataConnectionReasons = new DataConnectionReasons();
145899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        boolean isDataAllowed = isDataAllowed(apnContext, dataConnectionReasons);
145999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        String logStr = "trySetupData for APN type " + apnContext.getApnType() + ", reason: "
146099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                + apnContext.getReason() + ". " + dataConnectionReasons.toString();
146199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (DBG) log(logStr);
146299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        apnContext.requestLog(logStr);
1463120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        if (isDataAllowed) {
1464ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getState() == DctConstants.State.FAILED) {
14653d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                String str = "trySetupData: make a FAILED ApnContext IDLE so its reusable";
14662dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                if (DBG) log(str);
14672dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                apnContext.requestLog(str);
1468ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setState(DctConstants.State.IDLE);
1469ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1470203e588e3c42a81aa8a56f595119c181a63b12caWink Saville            int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
147199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            apnContext.setConcurrentVoiceAndDataAllowed(mPhone.getServiceStateTracker()
147299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                    .isConcurrentVoiceAndDataAllowed());
1473cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.getState() == DctConstants.State.IDLE) {
1474ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                ArrayList<ApnSetting> waitingApns =
1475ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                        buildWaitingApns(apnContext.getApnType(), radioTech);
1476cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (waitingApns.isEmpty()) {
1477ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    notifyNoData(DcFailCause.MISSING_UNKNOWN_APN, apnContext);
1478cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    notifyOffApnsOfAvailability(apnContext.getReason());
14792dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    String str = "trySetupData: X No APN found retValue=false";
14802dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    if (DBG) log(str);
14812dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    apnContext.requestLog(str);
1482cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return false;
1483cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1484cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setWaitingApns(waitingApns);
1485cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) {
1486ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        log ("trySetupData: Create from mAllApnSettings : "
1487ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                    + apnListToString(mAllApnSettings));
1488cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1489cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1490cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1491cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
149299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            boolean retValue = setupData(apnContext, radioTech, dataConnectionReasons.contains(
149399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                    DataAllowedReasonType.UNMETERED_APN));
1494cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(apnContext.getReason());
1495cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1496cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("trySetupData: X retValue=" + retValue);
1497cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return retValue;
1498cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1499cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
1500ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    && apnContext.isConnectable()) {
1501cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
1502ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1503cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(apnContext.getReason());
15042e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
15052e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            StringBuilder str = new StringBuilder();
15062e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
150799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            str.append("trySetupData failed. apnContext = [type=" + apnContext.getApnType()
150899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                    + ", mState=" + apnContext.getState() + ", apnEnabled="
150999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                    + apnContext.isEnabled() + ", mDependencyMet="
151099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                    + apnContext.getDependencyMet() + "] ");
15112e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
1512120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu            if (!mDataEnabledSettings.isDataEnabled()) {
151399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                str.append("isDataEnabled() = false. " + mDataEnabledSettings);
15142e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            }
15152e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
15169d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu            // If this is a data retry, we should set the APN state to FAILED so it won't stay
15179d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu            // in SCANNING forever.
15189d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu            if (apnContext.getState() == DctConstants.State.SCANNING) {
15199d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu                apnContext.setState(DctConstants.State.FAILED);
15209d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu                str.append(" Stop retrying.");
15219d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu            }
15229d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu
15232e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            if (DBG) log(str.toString());
15242e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            apnContext.requestLog(str.toString());
1525cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
1526cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1527c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1528c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
15290e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    // Disabled apn's still need avail/unavail notifications - send them out
15301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyOffApnsOfAvailability(String reason) {
1531cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1532187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (!mAttached.get() || !apnContext.isReady()) {
1533ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) log("notifyOffApnOfAvailability type:" + apnContext.getApnType());
1534cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
1535cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                            apnContext.getApnType(),
1536cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                            PhoneConstants.DataState.DISCONNECTED);
1537cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1538ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) {
1539187a39f896f88eb6c5e4306d9595546654825976Wink Saville                    log("notifyOffApnsOfAvailability skipped apn due to attached && isReady " +
1540cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            apnContext.toString());
1541cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1542c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1543c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1544c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1545c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1546cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1547cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * If tearDown is true, this only tears down a CONNECTED session. Presently,
1548cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * there is no mechanism for abandoning an CONNECTING session,
1549cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * but would likely involve cancelling pending async requests or
1550cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * setting a flag or new state to ignore them when they came in
1551cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param tearDown true if the underlying DataConnection should be
1552cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * disconnected.
1553cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param reason reason for the clean up.
15543fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return boolean - true if we did cleanup any connections, false if they
15553fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     *                   were already all disconnected.
1556cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
15571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean cleanUpAllConnections(boolean tearDown, String reason) {
1558cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("cleanUpAllConnections: tearDown=" + tearDown + " reason=" + reason);
15593fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        boolean didDisconnect = false;
15604c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu        boolean disableMeteredOnly = false;
1561a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
15624c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu        // reasons that only metered apn will be torn down
1563a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (!TextUtils.isEmpty(reason)) {
15644c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            disableMeteredOnly = reason.equals(Phone.REASON_DATA_SPECIFIC_DISABLED) ||
15654c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                    reason.equals(Phone.REASON_ROAMING_ON) ||
15664c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                    reason.equals(Phone.REASON_CARRIER_ACTION_DISABLE_METERED_APN);
1567a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1568cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1569cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
15703fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (apnContext.isDisconnected() == false) didDisconnect = true;
15714c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            if (disableMeteredOnly) {
1572783061ca03572618c01ce244d70d82fa4328d45ffionaxu                // Use ApnSetting to decide metered or non-metered.
1573783061ca03572618c01ce244d70d82fa4328d45ffionaxu                // Tear down all metered data connections.
1574783061ca03572618c01ce244d70d82fa4328d45ffionaxu                ApnSetting apnSetting = apnContext.getApnSetting();
157550734be549285702de00295778b8c2a4360215a0Jack Yu                if (apnSetting != null && apnSetting.isMetered(mPhone)) {
1576783061ca03572618c01ce244d70d82fa4328d45ffionaxu                    if (DBG) log("clean up metered ApnContext Type: " + apnContext.getApnType());
1577a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    apnContext.setReason(reason);
1578a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    cleanUpConnection(tearDown, apnContext);
1579a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1580a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
1581a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // TODO - only do cleanup if not disconnected
1582a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                apnContext.setReason(reason);
1583a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                cleanUpConnection(tearDown, apnContext);
1584a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1585c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1586cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1587cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopNetStatPoll();
1588cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopDataStallAlarm();
1589cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1590cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: Do we need mRequestedApnType?
1591cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
1592a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1593a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("cleanUpConnection: mDisconnectPendingCount = " + mDisconnectPendingCount);
1594a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (tearDown && mDisconnectPendingCount == 0) {
1595a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyDataDisconnectComplete();
1596a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
1597a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1598a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
15993fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return didDisconnect;
1600cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1601cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1602cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1603cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Cleanup all connections.
1604cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1605cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * TODO: Cleanup only a specified connection passed as a parameter.
1606cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *       Also, make sure when you clean up a conn, if it is last apply
1607cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *       logic as though it is cleanupAllConnections
1608cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1609cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param cause for the clean up.
1610cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
16111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onCleanUpAllConnections(String cause) {
1612cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, cause);
1613cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1614cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
16151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    void sendCleanUpConnection(boolean tearDown, ApnContext apnContext) {
16161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("sendCleanUpConnection: tearDown=" + tearDown + " apnContext=" + apnContext);
16171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_CLEAN_UP_CONNECTION);
16181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = tearDown ? 1 : 0;
16191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg2 = 0;
16201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.obj = apnContext;
16211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
16221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
1623cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
16241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void cleanUpConnection(boolean tearDown, ApnContext apnContext) {
1625cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
1626cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("cleanUpConnection: apn context is null");
1627cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
1628cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1629cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1630454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac = apnContext.getDcAc();
16312dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        String str = "cleanUpConnection: tearDown=" + tearDown + " reason=" +
16322dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                apnContext.getReason();
16339c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        if (VDBG) log(str + " apnContext=" + apnContext);
16342dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog(str);
1635cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (tearDown) {
1636cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.isDisconnected()) {
1637cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // The request is tearDown and but ApnContext is not connected.
1638cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // If apnContext is not enabled anymore, break the linkage to the DCAC/DC.
1639cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setState(DctConstants.State.IDLE);
1640cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (!apnContext.isReady()) {
16414750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                    if (dcac != null) {
16420e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                        str = "cleanUpConnection: teardown, disconnected, !ready";
16432dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        if (DBG) log(str + " apnContext=" + apnContext);
16442dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        apnContext.requestLog(str);
16454750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                        dcac.tearDown(apnContext, "", null);
16464750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                    }
1647cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setDataConnectionAc(null);
1648cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1649cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1650cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Connection is still there. Try to clean up.
1651cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (dcac != null) {
1652cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (apnContext.getState() != DctConstants.State.DISCONNECTING) {
1653cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        boolean disconnectAll = false;
1654cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (PhoneConstants.APN_TYPE_DUN.equals(apnContext.getApnType())) {
1655a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            // CAF_MSIM is this below condition required.
1656a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            // if (PhoneConstants.APN_TYPE_DUN.equals(PhoneConstants.APN_TYPE_DEFAULT)) {
16571484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                            if (teardownForDun()) {
165845eaa2335e64a8ff1ad8d5e8224c580ef996f370Wink Saville                                if (DBG) {
165945eaa2335e64a8ff1ad8d5e8224c580ef996f370Wink Saville                                    log("cleanUpConnection: disconnectAll DUN connection");
166045eaa2335e64a8ff1ad8d5e8224c580ef996f370Wink Saville                                }
1661cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // we need to tear it down - we brought it up just for dun and
1662cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // other people are camped on it and now dun is done.  We need
1663cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // to stop using it and let the normal apn list get used to find
1664cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // connections for the remaining desired connections
1665cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                disconnectAll = true;
1666cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            }
1667cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
16681a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                        final int generation = apnContext.getConnectionGeneration();
16691a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                        str = "cleanUpConnection: tearing down" + (disconnectAll ? " all" : "") +
16701a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                                " using gen#" + generation;
16712dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        if (DBG) log(str + "apnContext=" + apnContext);
16722dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        apnContext.requestLog(str);
167337cacdfe7ed079d89fb9e80317b5dfd2acb975e5Robert Greenwalt                        Pair<ApnContext, Integer> pair =
16741a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                                new Pair<ApnContext, Integer>(apnContext, generation);
167537cacdfe7ed079d89fb9e80317b5dfd2acb975e5Robert Greenwalt                        Message msg = obtainMessage(DctConstants.EVENT_DISCONNECT_DONE, pair);
1676cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (disconnectAll) {
1677ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            apnContext.getDcAc().tearDownAll(apnContext.getReason(), msg);
1678cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        } else {
1679ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            apnContext.getDcAc()
1680cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                .tearDown(apnContext, apnContext.getReason(), msg);
1681cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
1682cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.setState(DctConstants.State.DISCONNECTING);
1683a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        mDisconnectPendingCount++;
1684cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1685cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1686cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // apn is connected but no reference to dcac.
1687cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // Should not be happen, but reset the state in case.
1688cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setState(DctConstants.State.IDLE);
16892dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    apnContext.requestLog("cleanUpConnection: connected, bug no DCAC");
1690cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mPhone.notifyDataConnection(apnContext.getReason(),
1691cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                                apnContext.getApnType());
1692cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1693cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1694cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1695cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // force clean up the data connection.
1696ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac != null) dcac.reqReset();
1697cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setState(DctConstants.State.IDLE);
1698cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1699cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setDataConnectionAc(null);
1700cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1701cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1702ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // Make sure reconnection alarm is cleaned up if there is no ApnContext
1703cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // associated to the connection.
1704cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (dcac != null) {
1705ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            cancelReconnectAlarm(apnContext);
1706c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
17072dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        str = "cleanUpConnection: X tearDown=" + tearDown + " reason=" + apnContext.getReason();
17082dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        if (DBG) log(str + " apnContext=" + apnContext + " dcac=" + apnContext.getDcAc());
17092dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog(str);
1710cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1711c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
17125fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan    /**
17135fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan     * Fetch dun apn
17145fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan     * @return ApnSetting to be used for dun
17155fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan     */
17165fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan    @VisibleForTesting
17175fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan    public ApnSetting fetchDunApn() {
17181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (SystemProperties.getBoolean("net.tethering.noprovisioning", false)) {
17191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("fetchDunApn: net.tethering.noprovisioning=true ret: null");
17201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return null;
17211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
17221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int bearer = mPhone.getServiceState().getRilDataRadioTechnology();
1723d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        IccRecords r = mIccRecords.get();
1724d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        String operator = (r != null) ? r.getOperatorNumeric() : "";
1725d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        ArrayList<ApnSetting> dunCandidates = new ArrayList<ApnSetting>();
17261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting retDunSetting = null;
1727d92c67aa965200385acf3182ffb0af25297a366fJunda Liu
17285fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan        // Places to look for tether APN in order: TETHER_DUN_APN setting (to be deprecated soon),
17295fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan        // APN database, and config_tether_apndata resource (to be deprecated soon).
17301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        String apnData = Settings.Global.getString(mResolver, Settings.Global.TETHER_DUN_APN);
1731d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        if (!TextUtils.isEmpty(apnData)) {
1732d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            dunCandidates.addAll(ApnSetting.arrayFromString(apnData));
1733d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            if (VDBG) log("fetchDunApn: dunCandidates from Setting: " + dunCandidates);
1734d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        }
17355fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan
17365fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan        // todo: remove this and config_tether_apndata after APNs are moved from overlay to apns xml
17375fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan        // If TETHER_DUN_APN isn't set or APN database doesn't have dun APN,
1738d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        // try the resource as last resort.
1739d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        if (dunCandidates.isEmpty()) {
1740d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            String[] apnArrayData = mPhone.getContext().getResources()
1741d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                .getStringArray(R.array.config_tether_apndata);
1742ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu            if (!ArrayUtils.isEmpty(apnArrayData)) {
1743ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                for (String apnString : apnArrayData) {
1744ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                    ApnSetting apn = ApnSetting.fromString(apnString);
1745ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                    // apn may be null if apnString isn't valid or has error parsing
1746ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                    if (apn != null) dunCandidates.add(apn);
1747ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                }
1748ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                if (VDBG) log("fetchDunApn: dunCandidates from resource: " + dunCandidates);
1749d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            }
17501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
17511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
17525fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan        if (dunCandidates.isEmpty()) {
17535fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan            if (!ArrayUtils.isEmpty(mAllApnSettings)) {
17545fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan                for (ApnSetting apn : mAllApnSettings) {
17555fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan                    if (apn.canHandleType(PhoneConstants.APN_TYPE_DUN)) {
17565fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan                        dunCandidates.add(apn);
17575fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan                    }
17585fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan                }
17595fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan                if (VDBG) log("fetchDunApn: dunCandidates from database: " + dunCandidates);
17605fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan            }
17615fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan        }
17625fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan
1763d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        for (ApnSetting dunSetting : dunCandidates) {
1764d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            if (!ServiceState.bitmaskHasTech(dunSetting.bearerBitmask, bearer)) continue;
1765d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            if (dunSetting.numeric.equals(operator)) {
17661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (dunSetting.hasMvnoParams()) {
17671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (r != null && ApnSetting.mvnoMatches(r, dunSetting.mvnoType,
17681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            dunSetting.mvnoMatchData)) {
1769d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                        retDunSetting = dunSetting;
1770d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                        break;
17711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
17721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else if (mMvnoMatched == false) {
17731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    retDunSetting = dunSetting;
1774d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                    break;
17751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
17761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
17771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
17781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1779d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        if (VDBG) log("fetchDunApn: dunSetting=" + retDunSetting);
17801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return retDunSetting;
17811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
17821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
17831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public boolean hasMatchedTetherApnSetting() {
17841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting matched = fetchDunApn();
17851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("hasMatchedTetherApnSetting: APN=" + matched);
17861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return matched != null;
17871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
17881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1789cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
17901484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt     * Determine if DUN connection is special and we need to teardown on start/stop
17911484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt     */
17921484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt    private boolean teardownForDun() {
17931484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // CDMA always needs to do this the profile id is correct
17941484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        final int rilRat = mPhone.getServiceState().getRilDataRadioTechnology();
17951484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        if (ServiceState.isCdma(rilRat)) return true;
17961484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt
17971484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        return (fetchDunApn() != null);
17981484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt    }
17991484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt
18001484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt    /**
1801ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Cancels the alarm associated with apnContext.
1802cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1803ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * @param apnContext on which the alarm should be stopped.
1804cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1805ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void cancelReconnectAlarm(ApnContext apnContext) {
1806ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnContext == null) return;
1807cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1808ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        PendingIntent intent = apnContext.getReconnectIntent();
1809cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1810cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (intent != null) {
1811cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                AlarmManager am =
1812cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
1813cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                am.cancel(intent);
1814ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setReconnectIntent(null);
1815cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1816c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1817c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1818cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1819cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param types comma delimited list of APN types
1820cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return array of APN types
1821cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1822cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private String[] parseTypes(String types) {
1823c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String[] result;
1824cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // If unset, set to DEFAULT.
1825cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (types == null || types.equals("")) {
1826c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            result = new String[1];
1827cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result[0] = PhoneConstants.APN_TYPE_ALL;
1828cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1829cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result = types.split(",");
1830c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1831c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
1832c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1833c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1834ccfe5ebaf81c1378e8dbe44e45df26b0dc462a21Jack Yu    boolean isPermanentFailure(DcFailCause dcFailCause) {
1835ccfe5ebaf81c1378e8dbe44e45df26b0dc462a21Jack Yu        return (dcFailCause.isPermanentFailure(mPhone.getContext(), mPhone.getSubId()) &&
1836796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan                (mAttached.get() == false || dcFailCause != DcFailCause.SIGNAL_LOST));
1837796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan    }
1838796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan
1839fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    private ApnSetting makeApnSetting(Cursor cursor) {
1840fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        String[] types = parseTypes(
1841fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.TYPE)));
1842fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        ApnSetting apn = new ApnSetting(
1843fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID)),
1844fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NUMERIC)),
1845fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NAME)),
1846fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN)),
1847fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1848fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1849fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY))),
1850fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PORT)),
1851fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1852fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1853fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC))),
1854fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1855fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1856fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY))),
1857fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPORT)),
1858fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)),
1859fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)),
18601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.AUTH_TYPE)),
1861fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                types,
1862fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROTOCOL)),
1863fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(
1864fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        Telephony.Carriers.ROAMING_PROTOCOL)),
1865fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(
1866fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        Telephony.Carriers.CARRIER_ENABLED)) == 1,
18679d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.BEARER)),
1868aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.BEARER_BITMASK)),
18699d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROFILE_ID)),
18709d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(
18719d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                        Telephony.Carriers.MODEM_COGNITIVE)) == 1,
18729d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MAX_CONNS)),
18739d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(
18749d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                        Telephony.Carriers.WAIT_TIME)),
1875e9701717e43cc5aacbcf624f77a53be92350662cw                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MAX_CONNS_TIME)),
18763262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MTU)),
18773262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_TYPE)),
18783262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_MATCH_DATA)));
1879fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        return apn;
1880fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    }
1881fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
1882cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ArrayList<ApnSetting> createApnList(Cursor cursor) {
18833262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        ArrayList<ApnSetting> mnoApns = new ArrayList<ApnSetting>();
18843262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        ArrayList<ApnSetting> mvnoApns = new ArrayList<ApnSetting>();
1885fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        IccRecords r = mIccRecords.get();
1886fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
1887cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor.moveToFirst()) {
1888cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            do {
18893262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                ApnSetting apn = makeApnSetting(cursor);
18903262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                if (apn == null) {
18913262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                    continue;
18923262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                }
18933262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
18943262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                if (apn.hasMvnoParams()) {
189563913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan                    if (r != null && ApnSetting.mvnoMatches(r, apn.mvnoType, apn.mvnoMatchData)) {
18963262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                        mvnoApns.add(apn);
1897fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    }
1898fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                } else {
18993262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                    mnoApns.add(apn);
1900fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                }
1901cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } while (cursor.moveToNext());
1902cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
19033262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
19041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ArrayList<ApnSetting> result;
19051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mvnoApns.isEmpty()) {
19061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            result = mnoApns;
19071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mMvnoMatched = false;
19081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
19091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            result = mvnoApns;
19101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mMvnoMatched = true;
19111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
1912cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createApnList: X result=" + result);
1913c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
1914c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1915c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1916454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private boolean dataConnectionNotInUse(DcAsyncChannel dcac) {
1917ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("dataConnectionNotInUse: check if dcac is inuse dcac=" + dcac);
1918cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1919ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getDcAc() == dcac) {
1920cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("dataConnectionNotInUse: in use by apnContext=" + apnContext);
1921cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
1922cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1923cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1924cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: Fix retry handling so free DataConnections have empty apnlists.
1925cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Probably move retry handling into DataConnections and reduce complexity
1926cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // of DCT.
1927cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("dataConnectionNotInUse: tearDownAll");
1928ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        dcac.tearDownAll("No connection", null);
1929cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("dataConnectionNotInUse: not in use return true");
1930cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
1931cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1932cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1933454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel findFreeDataConnection() {
1934454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
1935cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac.isInactiveSync() && dataConnectionNotInUse(dcac)) {
1936cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
1937cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("findFreeDataConnection: found free DataConnection=" +
1938ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        " dcac=" + dcac);
1939cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1940ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                return dcac;
1941cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1942cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1943cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("findFreeDataConnection: NO free DataConnection");
1944cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
1945cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1946cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
194799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu    /**
194899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * Setup a data connection based on given APN type.
194999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *
195099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @param apnContext APN context
195199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @param radioTech RAT of the data connection
195299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @param unmeteredUseOnly True if this data connection should be only used for unmetered
195399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *                         purposes only.
195499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @return True if successful, otherwise false.
195599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     */
1956120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu    private boolean setupData(ApnContext apnContext, int radioTech, boolean unmeteredUseOnly) {
1957cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setupData: apnContext=" + apnContext);
19582dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog("setupData");
1959ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnSetting apnSetting;
19601484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        DcAsyncChannel dcac = null;
1961cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
19620e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        apnSetting = apnContext.getNextApnSetting();
19630e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
1964ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnSetting == null) {
1965cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("setupData: return for no apn found!");
1966cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
1967cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1968cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1969231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        int profileId = apnSetting.profileId;
1970231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        if (profileId == 0) {
1971231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen            profileId = getApnProfileID(apnContext.getApnType());
1972231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        }
1973231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen
19741484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // On CDMA, if we're explicitly asking for DUN, we need have
19751484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // a dun-profiled connection so we can't share an existing one
19761484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // On GSM/LTE we can share existing apn connections provided they support
19771484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // this type.
19781484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        if (apnContext.getApnType() != PhoneConstants.APN_TYPE_DUN ||
19791484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                teardownForDun() == false) {
19801484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt            dcac = checkForCompatibleConnectedApnContext(apnContext);
19811484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt            if (dcac != null) {
19821484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // Get the dcacApnSetting for the connection we want to share.
19831484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                ApnSetting dcacApnSetting = dcac.getApnSettingSync();
19841484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                if (dcacApnSetting != null) {
19851484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    // Setting is good, so use it.
19861484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    apnSetting = dcacApnSetting;
19871484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                }
1988ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1989ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
1990ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (dcac == null) {
19913fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (isOnlySingleDcAllowed(radioTech)) {
19923fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (isHigherPriorityApnContextActive(apnContext)) {
19933fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (DBG) {
19943fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        log("setupData: Higher priority ApnContext active.  Ignoring call");
19953fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    }
19963fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    return false;
19973fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                }
19983fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
19993fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // Only lower priority calls left.  Disconnect them all in this single PDP case
20003fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // so that we can bring up the requested higher priority call (once we receive
20010e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                // response for deactivate request for the calls we are about to disconnect
20023fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (cleanUpAllConnections(true, Phone.REASON_SINGLE_PDN_ARBITRATION)) {
20033fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // If any call actually requested to be disconnected, means we can't
20043fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // bring up this connection yet as we need to wait for those data calls
20053fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // to be disconnected.
20063fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (DBG) log("setupData: Some calls are disconnecting first.  Wait and retry");
20073fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    return false;
20083fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                }
20093fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
20103fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // No other calls are active, so proceed
20113fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (DBG) log("setupData: Single pdp. Continue setting up data call.");
20123fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
20133fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
2014ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            dcac = findFreeDataConnection();
2015cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2016ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac == null) {
2017ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                dcac = createDataConnection();
2018cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2019cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2020ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac == null) {
2021ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) log("setupData: No free DataConnection and couldn't create one, WEIRD");
2022cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
2023cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2024cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
20251a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        final int generation = apnContext.incAndGetConnectionGeneration();
20261a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        if (DBG) {
20271a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt            log("setupData: dcac=" + dcac + " apnSetting=" + apnSetting + " gen#=" + generation);
20281a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        }
2029cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2030cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setDataConnectionAc(dcac);
2031ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setApnSetting(apnSetting);
2032cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setState(DctConstants.State.CONNECTING);
2033cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
2034cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2035cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Message msg = obtainMessage();
2036cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        msg.what = DctConstants.EVENT_DATA_SETUP_COMPLETE;
20371a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        msg.obj = new Pair<ApnContext, Integer>(apnContext, generation);
2038120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        dcac.bringUp(apnContext, profileId, radioTech, unmeteredUseOnly, msg, generation);
2039cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2040cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setupData: initing!");
2041cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
2042cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2043cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
20441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void setInitialAttachApn() {
20451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting iaApnSetting = null;
20461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting defaultApnSetting = null;
20471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting firstApnSetting = null;
20481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
20491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("setInitialApn: E mPreferredApn=" + mPreferredApn);
20501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
205140b0e247a4a79e83f10b6410025ef1d7cc537692Robert Greenwalt        if (mPreferredApn != null && mPreferredApn.canHandleType(PhoneConstants.APN_TYPE_IA)) {
205240b0e247a4a79e83f10b6410025ef1d7cc537692Robert Greenwalt              iaApnSetting = mPreferredApn;
205340b0e247a4a79e83f10b6410025ef1d7cc537692Robert Greenwalt        } else if (mAllApnSettings != null && !mAllApnSettings.isEmpty()) {
20541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            firstApnSetting = mAllApnSettings.get(0);
20551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("setInitialApn: firstApnSetting=" + firstApnSetting);
20561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
20571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Search for Initial APN setting and the first apn that can handle default
20581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (ApnSetting apn : mAllApnSettings) {
205940b0e247a4a79e83f10b6410025ef1d7cc537692Robert Greenwalt                if (apn.canHandleType(PhoneConstants.APN_TYPE_IA)) {
20601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // The Initial Attach APN is highest priority so use it if there is one
20611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("setInitialApn: iaApnSetting=" + apn);
20621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    iaApnSetting = apn;
20631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    break;
20641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else if ((defaultApnSetting == null)
20651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        && (apn.canHandleType(PhoneConstants.APN_TYPE_DEFAULT))) {
20661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // Use the first default apn if no better choice
20671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("setInitialApn: defaultApnSetting=" + apn);
20681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    defaultApnSetting = apn;
20691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
20701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
20711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
20721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
20731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // The priority of apn candidates from highest to lowest is:
20740e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        //   1) APN_TYPE_IA (Initial Attach)
20751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        //   2) mPreferredApn, i.e. the current preferred apn
20761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        //   3) The first apn that than handle APN_TYPE_DEFAULT
20771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        //   4) The first APN we can find.
20781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
20791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting initialAttachApnSetting = null;
20801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (iaApnSetting != null) {
20811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using iaApnSetting");
20821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = iaApnSetting;
20831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (mPreferredApn != null) {
20841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using mPreferredApn");
20851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = mPreferredApn;
20861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (defaultApnSetting != null) {
20871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using defaultApnSetting");
20881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = defaultApnSetting;
20891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (firstApnSetting != null) {
20901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using firstApnSetting");
20911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = firstApnSetting;
20921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
20931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
20941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (initialAttachApnSetting == null) {
20951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: X There in no available apn");
20961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
20971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: X selected Apn=" + initialAttachApnSetting);
20981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2099886183cde1263ea524cdf08524442724e246ed42Jack Yu            mPhone.mCi.setInitialAttachApn(createDataProfile(initialAttachApnSetting),
2100cc40713c49908aeaac0070bf4ea796247f9066b5Jack Yu                    mPhone.getServiceState().getDataRoamingFromRegistration(), null);
21011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
21021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
21031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2104c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
2105cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Handles changes to the APN database.
2106c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
2107cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onApnChanged() {
2108cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        DctConstants.State overallState = getOverallState();
2109cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isDisconnected = (overallState == DctConstants.State.IDLE ||
2110cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                overallState == DctConstants.State.FAILED);
2111cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
21121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mPhone instanceof GsmCdmaPhone) {
2113cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // The "current" may no longer be valid.  MMS depends on this to send properly. TBD
21141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            ((GsmCdmaPhone)mPhone).updateCurrentCarrierInProvider();
2115cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2116cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2117cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: It'd be nice to only do this if the changed entrie(s)
2118cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // match the current operator.
2119cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onApnChanged: createAllApnList and cleanUpAllConnections");
2120cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        createAllApnList();
21215d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi        setInitialAttachApn();
2122ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu        cleanUpConnectionsOnUpdatedApns(!isDisconnected, Phone.REASON_APN_CHANGED);
2123bda761320929f714951c328bfec6a51a1978db97Wink Saville
21248f6f52e4f7598e44cea1f9e5f4781291f9060d1dWink Saville        // FIXME: See bug 17426028 maybe no conditional is needed.
212538ca51d0f643405df51e78fce6c546424e9f410dShishir Agrawal        if (mPhone.getSubId() == SubscriptionManager.getDefaultDataSubscriptionId()) {
2126ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_APN_CHANGED);
2127c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2128c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2129c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2130c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
2131cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param cid Connection id provided from RIL.
2132cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return DataConnectionAc associated with specified cid.
2133c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
2134454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel findDataConnectionAcByCid(int cid) {
2135454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
2136cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac.getCidSync() == cid) {
2137cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return dcac;
2138cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2139c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2140cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
2141c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2142c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2143cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // TODO: For multiple Active APNs not exactly sure how to do this.
21441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void gotoIdleAndNotifyDataConnection(String reason) {
2145cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("gotoIdleAndNotifyDataConnection: reason=" + reason);
2146cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyDataConnection(reason);
2147cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2148cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
21493fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    /**
21503fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * "Active" here means ApnContext isEnabled() and not in FAILED state
21513fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @param apnContext to compare with
21523fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return true if higher priority active apn found
21533fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     */
21543fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean isHigherPriorityApnContextActive(ApnContext apnContext) {
21553fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        for (ApnContext otherContext : mPrioritySortedApnContexts) {
21563fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (apnContext.getApnType().equalsIgnoreCase(otherContext.getApnType())) return false;
21573fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (otherContext.isEnabled() && otherContext.getState() != DctConstants.State.FAILED) {
21583fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                return true;
21593fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
21603fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
21613fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return false;
21623fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    }
21633fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
21643fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    /**
21653fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * Reports if we support multiple connections or not.
21663fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * This is a combination of factors, based on carrier and RAT.
21673fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @param rilRadioTech the RIL Radio Tech currently in use
21683fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return true if only single DataConnection is allowed
21693fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     */
21703fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean isOnlySingleDcAllowed(int rilRadioTech) {
2171bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        // Default single dc rats with no knowledge of carrier
2172bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        int[] singleDcRats = null;
2173bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        // get the carrier specific value, if it exists, from CarrierConfigManager.
2174bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        // generally configManager and bundle should not be null, but if they are it should be okay
2175bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        // to leave singleDcRats null as well
2176bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        CarrierConfigManager configManager = (CarrierConfigManager)
2177bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu                mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
2178bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        if (configManager != null) {
2179bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu            PersistableBundle bundle = configManager.getConfig();
2180bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu            if (bundle != null) {
2181bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu                singleDcRats = bundle.getIntArray(
2182bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu                        CarrierConfigManager.KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY);
2183bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu            }
2184bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        }
21853fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        boolean onlySingleDcAllowed = false;
21863fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (Build.IS_DEBUGGABLE &&
21873fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                SystemProperties.getBoolean("persist.telephony.test.singleDc", false)) {
21883fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            onlySingleDcAllowed = true;
21893fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
21903fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (singleDcRats != null) {
21913fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            for (int i=0; i < singleDcRats.length && onlySingleDcAllowed == false; i++) {
21923fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (rilRadioTech == singleDcRats[i]) onlySingleDcAllowed = true;
21933fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
21943fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
21953fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
21963fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (DBG) log("isOnlySingleDcAllowed(" + rilRadioTech + "): " + onlySingleDcAllowed);
21973fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return onlySingleDcAllowed;
21983fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    }
21993fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
22001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    void sendRestartRadio() {
22011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG)log("sendRestartRadio:");
22021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_RESTART_RADIO);
22031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
22041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
22051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
22061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void restartRadio() {
2207cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("restartRadio: ************TURN OFF RADIO**************");
2208cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, Phone.REASON_RADIO_TURNED_OFF);
2209cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().powerOffRadioSafely(this);
2210cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        /* Note: no need to call setRadioPower(true).  Assuming the desired
2211cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * radio power state is still ON (as tracked by ServiceStateTracker),
2212cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * ServiceStateTracker will call setRadioPower when it receives the
2213cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * RADIO_STATE_CHANGED notification for the power off.  And if the
2214cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * desired power state has changed in the interim, we don't want to
2215cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * override it with an unconditional power on.
2216cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         */
2217cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2218cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int reset = Integer.parseInt(SystemProperties.get("net.ppp.reset-by-timeout", "0"));
22190e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        SystemProperties.set("net.ppp.reset-by-timeout", String.valueOf(reset + 1));
2220cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2221cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2222cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
2223cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Return true if data connection need to be setup after disconnected due to
2224cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * reason.
2225cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
22260e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu     * @param apnContext APN context
2227cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return true if try setup data connection is need for this reason
2228cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
22293fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean retryAfterDisconnected(ApnContext apnContext) {
2230cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean retry = true;
22313fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        String reason = apnContext.getReason();
2232cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
22333fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) ||
22343fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())
22353fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                 && isHigherPriorityApnContextActive(apnContext))) {
2236cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            retry = false;
2237cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2238cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return retry;
2239cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2240cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
22410e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    private void startAlarmForReconnect(long delay, ApnContext apnContext) {
2242cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String apnType = apnContext.getApnType();
224374672e8ee972f12406b72551261b4cc7e0651933Wink Saville
224474672e8ee972f12406b72551261b4cc7e0651933Wink Saville        Intent intent = new Intent(INTENT_RECONNECT_ALARM + "." + apnType);
224574672e8ee972f12406b72551261b4cc7e0651933Wink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, apnContext.getReason());
2246cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, apnType);
224767d43cfed4b996c20780bfec8fde1ae8c1391779Junda Liu        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
2248cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2249a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // Get current sub id.
22504f580e63be8e5787ce636c3b47335529ceb973b9Susheel nyamala        int subId = mPhone.getSubId();
2251a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
2252a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
225374672e8ee972f12406b72551261b4cc7e0651933Wink Saville        if (DBG) {
225474672e8ee972f12406b72551261b4cc7e0651933Wink Saville            log("startAlarmForReconnect: delay=" + delay + " action=" + intent.getAction()
225574672e8ee972f12406b72551261b4cc7e0651933Wink Saville                    + " apn=" + apnContext);
225674672e8ee972f12406b72551261b4cc7e0651933Wink Saville        }
225774672e8ee972f12406b72551261b4cc7e0651933Wink Saville
22580e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        PendingIntent alarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0,
2259cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                        intent, PendingIntent.FLAG_UPDATE_CURRENT);
2260ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setReconnectIntent(alarmIntent);
22617d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu
22627d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu        // Use the exact timer instead of the inexact one to provide better user experience.
22637d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu        // In some extreme cases, we saw the retry was delayed for few minutes.
22640852a954be5937a1b0bca94df0c2007d7ee3c0c7Jack Yu        // Note that if the stated trigger time is in the past, the alarm will be triggered
22650852a954be5937a1b0bca94df0c2007d7ee3c0c7Jack Yu        // immediately.
22667d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu        mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
2267cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                SystemClock.elapsedRealtime() + delay, alarmIntent);
2268cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2269cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2270ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void notifyNoData(DcFailCause lastFailCauseCode,
2271cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                              ApnContext apnContext) {
2272cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log( "notifyNoData: type=" + apnContext.getApnType());
2273ccfe5ebaf81c1378e8dbe44e45df26b0dc462a21Jack Yu        if (isPermanentFailure(lastFailCauseCode)
2274cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            && (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT))) {
2275cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
2276cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2277cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2278cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
22791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public boolean getAutoAttachOnCreation() {
22801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mAutoAttachOnCreation.get();
22811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
22821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
22831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRecordsLoadedOrSubIdChanged() {
22841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("onRecordsLoadedOrSubIdChanged: createAllApnList");
228512fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        mAutoAttachOnCreationConfig = mPhone.getContext().getResources()
228612fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao                .getBoolean(com.android.internal.R.bool.config_auto_attach_data_on_creation);
2287bda761320929f714951c328bfec6a51a1978db97Wink Saville
2288cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        createAllApnList();
22895d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi        setInitialAttachApn();
229022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPhone.mCi.getRadioState().isOn()) {
22911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("onRecordsLoadedOrSubIdChanged: notifying data availability");
2292cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_SIM_LOADED);
2293cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2294bda761320929f714951c328bfec6a51a1978db97Wink Saville        setupDataOnConnectableApns(Phone.REASON_SIM_LOADED);
2295cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2296cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
22974c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu    /**
22984c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu     * Action set from carrier signalling broadcast receivers to enable/disable metered apns.
22994c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu     */
23006a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu    private void onSetCarrierDataEnabled(AsyncResult ar) {
23016a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu        if (ar.exception != null) {
23026a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu            Rlog.e(LOG_TAG, "CarrierDataEnable exception: " + ar.exception);
23036a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu            return;
23046a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu        }
2305a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        synchronized (mDataEnabledSettings) {
23066a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu            boolean enabled = (boolean) ar.result;
2307a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            if (enabled != mDataEnabledSettings.isCarrierDataEnabled()) {
2308a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                if (DBG) {
2309a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                    log("carrier Action: set metered apns enabled: " + enabled);
2310a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                }
2311a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
2312a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                // Disable/enable all metered apns
2313a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                mDataEnabledSettings.setCarrierDataEnabled(enabled);
2314a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
2315a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                if (!enabled) {
2316a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                    // Send otasp_sim_unprovisioned so that SuW is able to proceed and notify users
23176432c2f4a4f438b72fa0d4b51d5098b179935868Nathan Harold                    mPhone.notifyOtaspChanged(TelephonyManager.OTASP_SIM_UNPROVISIONED);
2318a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                    // Tear down all metered apns
2319a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                    cleanUpAllConnections(true, Phone.REASON_CARRIER_ACTION_DISABLE_METERED_APN);
2320a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                } else {
2321120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    // Re-evaluate Otasp state
23224839eb565b4294443a34a93ee2ca93ac70b72b87fionaxu                    int otaspState = mPhone.getServiceStateTracker().getOtasp();
23234839eb565b4294443a34a93ee2ca93ac70b72b87fionaxu                    mPhone.notifyOtaspChanged(otaspState);
23244839eb565b4294443a34a93ee2ca93ac70b72b87fionaxu
2325120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    reevaluateDataConnections();
2326a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                    setupDataOnConnectableApns(Phone.REASON_DATA_ENABLED);
2327a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                }
232868f4f4a0bc8d4060b5775e7a24a97ea5b485989efionaxu            }
2329a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        }
2330a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    }
2331a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
23320469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal    private void onSimNotReady() {
23330469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        if (DBG) log("onSimNotReady");
23340469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal
23350469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        cleanUpAllConnections(true, Phone.REASON_SIM_NOT_READY);
23360469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        mAllApnSettings = null;
23370469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        mAutoAttachOnCreationConfig = false;
23387e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C        // Clear auto attach as modem is expected to do a new attach once SIM is ready
23397e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C        mAutoAttachOnCreation.set(false);
23400469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal    }
23410469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal
23421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetDependencyMet(String apnType, boolean met) {
2343cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // don't allow users to tweak hipri to work around default dependency not met
2344cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_HIPRI.equals(apnType)) return;
2345cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2346cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
2347cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
2348cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onSetDependencyMet: ApnContext not found in onSetDependencyMet(" +
2349cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnType + ", " + met + ")");
2350cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
2351cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2352cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        applyNewState(apnContext, apnContext.isEnabled(), met);
2353cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_DEFAULT.equals(apnType)) {
2354cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // tie actions on default to similar actions on HIPRI regarding dependencyMet
2355cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext = mApnContexts.get(PhoneConstants.APN_TYPE_HIPRI);
2356cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext != null) applyNewState(apnContext, apnContext.isEnabled(), met);
2357cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2358cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2359c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2360a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    public void setPolicyDataEnabled(boolean enabled) {
2361a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        if (DBG) log("setPolicyDataEnabled: " + enabled);
2362a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        Message msg = obtainMessage(DctConstants.CMD_SET_POLICY_DATA_ENABLE);
2363a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        msg.arg1 = (enabled ? DctConstants.ENABLED : DctConstants.DISABLED);
2364a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        sendMessage(msg);
2365a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    }
2366a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
23671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetPolicyDataEnabled(boolean enabled) {
2368a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        synchronized (mDataEnabledSettings) {
236999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            final boolean prevEnabled = isDataEnabled();
2370a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            if (mDataEnabledSettings.isPolicyDataEnabled() != enabled) {
2371a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                mDataEnabledSettings.setPolicyDataEnabled(enabled);
2372a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                // TODO: We should register for DataEnabledSetting's data enabled/disabled event and
2373a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                // handle the rest from there.
237499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                if (prevEnabled != isDataEnabled()) {
23751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (!prevEnabled) {
2376120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                        reevaluateDataConnections();
23771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onTrySetupData(Phone.REASON_DATA_ENABLED);
23781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
23791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);
23801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
23811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
23821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
23831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
23841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
23851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2386cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void applyNewState(ApnContext apnContext, boolean enabled, boolean met) {
2387cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean cleanup = false;
2388cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean trySetup = false;
23892dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        String str ="applyNewState(" + apnContext.getApnType() + ", " + enabled +
23902dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                "(" + apnContext.isEnabled() + "), " + met + "(" +
23912dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                apnContext.getDependencyMet() +"))";
23922dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        if (DBG) log(str);
23932dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog(str);
23942dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt
2395cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext.isReady()) {
2396305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt            cleanup = true;
23972428693913ae731d4ace3414429f5e91af24ea36Wink Saville            if (enabled && met) {
23982428693913ae731d4ace3414429f5e91af24ea36Wink Saville                DctConstants.State state = apnContext.getState();
23992428693913ae731d4ace3414429f5e91af24ea36Wink Saville                switch(state) {
24002428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case CONNECTING:
24012428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case CONNECTED:
24022428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case DISCONNECTING:
24032428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // We're "READY" and active so just return
24042428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        if (DBG) log("applyNewState: 'ready' so return");
24052dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        apnContext.requestLog("applyNewState state=" + state + ", so return");
24062428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        return;
24072428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case IDLE:
24082428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // fall through: this is unexpected but if it happens cleanup and try setup
24092428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case FAILED:
24109d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu                    case SCANNING:
24112428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case RETRYING: {
24122428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // We're "READY" but not active so disconnect (cleanup = true) and
24132428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // connect (trySetup = true) to be sure we retry the connection.
24142428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        trySetup = true;
24152428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        apnContext.setReason(Phone.REASON_DATA_ENABLED);
24162428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        break;
24172428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    }
24182428693913ae731d4ace3414429f5e91af24ea36Wink Saville                }
2419305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt            } else if (met) {
2420cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setReason(Phone.REASON_DATA_DISABLED);
2421305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // If ConnectivityService has disabled this network, stop trying to bring
2422305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // it up, but do not tear it down - ConnectivityService will do that
2423305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // directly by talking with the DataConnection.
24241484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                //
24251484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // This doesn't apply to DUN, however.  Those connections have special
24261484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // requirements from carriers and we need stop using them when the dun
24271484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // request goes away.  This applies to both CDMA and GSM because they both
24281484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // can declare the DUN APN sharable by default traffic, thus still satisfying
24291484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // those requests and not torn down organically.
24309db4884401d436d0796138f9190079df310cee95Sukanya Rajkhowa                if ((apnContext.getApnType() == PhoneConstants.APN_TYPE_DUN && teardownForDun())
24319db4884401d436d0796138f9190079df310cee95Sukanya Rajkhowa                        || apnContext.getState() != DctConstants.State.CONNECTED) {
24329db4884401d436d0796138f9190079df310cee95Sukanya Rajkhowa                    str = "Clean up the connection. Apn type = " + apnContext.getApnType()
24339db4884401d436d0796138f9190079df310cee95Sukanya Rajkhowa                            + ", state = " + apnContext.getState();
24349db4884401d436d0796138f9190079df310cee95Sukanya Rajkhowa                    if (DBG) log(str);
24359db4884401d436d0796138f9190079df310cee95Sukanya Rajkhowa                    apnContext.requestLog(str);
24361484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    cleanup = true;
24371484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                } else {
24381484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    cleanup = false;
24391484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                }
2440cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
2441cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_UNMET);
2442cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2443cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2444cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (enabled && met) {
2445cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apnContext.isEnabled()) {
2446cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_MET);
2447cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2448cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setReason(Phone.REASON_DATA_ENABLED);
2449c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
2450cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apnContext.getState() == DctConstants.State.FAILED) {
2451cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setState(DctConstants.State.IDLE);
2452cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2453cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                trySetup = true;
2454cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2455cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2456cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setEnabled(enabled);
2457cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setDependencyMet(met);
2458cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cleanup) cleanUpConnection(true, apnContext);
24590d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt        if (trySetup) {
24600d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt            apnContext.resetErrorCodeRetries();
24610d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt            trySetupData(apnContext);
24620d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt        }
2463cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2464c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2465454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel checkForCompatibleConnectedApnContext(ApnContext apnContext) {
2466cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String apnType = apnContext.getApnType();
2467cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnSetting dunSetting = null;
2468cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2469cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_DUN.equals(apnType)) {
2470cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            dunSetting = fetchDunApn();
2471cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2472ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) {
2473ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            log("checkForCompatibleConnectedApnContext: apnContext=" + apnContext );
2474ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
2475cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2476454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel potentialDcac = null;
2477ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnContext potentialApnCtx = null;
2478ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        for (ApnContext curApnCtx : mApnContexts.values()) {
2479454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel curDcac = curApnCtx.getDcAc();
2480ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (curDcac != null) {
2481ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                ApnSetting apnSetting = curApnCtx.getApnSetting();
2482a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("apnSetting: " + apnSetting);
2483cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (dunSetting != null) {
2484cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (dunSetting.equals(apnSetting)) {
2485ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        switch (curApnCtx.getState()) {
2486cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            case CONNECTED:
2487cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                if (DBG) {
2488ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                    log("checkForCompatibleConnectedApnContext:"
2489ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                            + " found dun conn=" + curDcac
2490ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                            + " curApnCtx=" + curApnCtx);
2491cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                }
2492ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                return curDcac;
2493ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            case RETRYING:
2494cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            case CONNECTING:
2495ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                potentialDcac = curDcac;
2496ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                potentialApnCtx = curApnCtx;
2497cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            default:
2498cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // Not connected, potential unchanged
2499cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                break;
2500cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
2501cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2502cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else if (apnSetting != null && apnSetting.canHandleType(apnType)) {
2503ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    switch (curApnCtx.getState()) {
2504cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        case CONNECTED:
2505cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            if (DBG) {
2506ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                log("checkForCompatibleConnectedApnContext:"
2507ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        + " found canHandle conn=" + curDcac
2508ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        + " curApnCtx=" + curApnCtx);
2509cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            }
2510ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            return curDcac;
2511ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        case RETRYING:
2512cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        case CONNECTING:
2513ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            potentialDcac = curDcac;
2514ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            potentialApnCtx = curApnCtx;
2515cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        default:
2516cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            // Not connected, potential unchanged
2517cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            break;
2518cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2519cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2520ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            } else {
2521ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) {
2522ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    log("checkForCompatibleConnectedApnContext: not conn curApnCtx=" + curApnCtx);
2523ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                }
2524cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2525cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2526ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (potentialDcac != null) {
2527cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
2528ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                log("checkForCompatibleConnectedApnContext: found potential conn=" + potentialDcac
2529ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        + " curApnCtx=" + potentialApnCtx);
2530cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2531ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            return potentialDcac;
2532cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2533c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2534ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("checkForCompatibleConnectedApnContext: NO conn apnContext=" + apnContext);
2535cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
2536cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2537c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
253827b650c406018355a88a41528db7859e232728a0Jack Yu    public void setEnabled(int id, boolean enable) {
25391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_ENABLE_NEW_APN);
25401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = id;
25411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg2 = (enable ? DctConstants.ENABLED : DctConstants.DISABLED);
25421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
25431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
25441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
25451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onEnableApn(int apnId, int enabled) {
2546af5593594070f825032be46dced573cd195956e1Robert Greenwalt        ApnContext apnContext = mApnContextsById.get(apnId);
2547cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
2548cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onEnableApn(" + apnId + ", " + enabled + "): NO ApnContext");
2549cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
2550cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2551cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO change our retry manager to use the appropriate numbers for the new APN
2552cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onEnableApn: apnContext=" + apnContext + " call applyNewState");
2553cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        applyNewState(apnContext, enabled == DctConstants.ENABLED, apnContext.getDependencyMet());
2554af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla
2555af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla        if ((enabled == DctConstants.DISABLED) &&
2556af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology()) &&
2557af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            !isHigherPriorityApnContextActive(apnContext)) {
2558af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla
2559af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            if(DBG) log("onEnableApn: isOnlySingleDcAllowed true & higher priority APN disabled");
2560af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            // If the highest priority APN is disabled and only single
2561af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            // data call is allowed, try to setup data call on other connectable APN.
2562af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            setupDataOnConnectableApns(Phone.REASON_SINGLE_PDN_ARBITRATION);
2563af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla        }
2564cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2565c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2566cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // TODO: We shouldnt need this.
25671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean onTrySetupData(String reason) {
2568cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onTrySetupData: reason=" + reason);
2569ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(reason);
2570cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
2571cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2572c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
25731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean onTrySetupData(ApnContext apnContext) {
2574cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onTrySetupData: apnContext=" + apnContext);
2575cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return trySetupData(apnContext);
2576cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2577c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
25781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
25791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Return current {@link android.provider.Settings.Global#MOBILE_DATA} value.
25801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
25811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public boolean getDataEnabled() {
2582985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen        if (mDataEnabledSettings.isProvisioning()) {
2583985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen            return mDataEnabledSettings.isProvisioningDataEnabled();
2584f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        } else {
2585985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen            return mDataEnabledSettings.isUserDataEnabled();
25861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
25871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
25881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
25891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
259021e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * Modify {@link android.provider.Settings.Global#DATA_ROAMING} value for user modification only
25911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
259221e6af8d6197a071d025733fffeffc157d0085bcfionaxu    public void setDataRoamingEnabledByUser(boolean enabled) {
25931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        final int phoneSubId = mPhone.getSubId();
25945b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (getDataRoamingEnabled() != enabled) {
25951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            int roaming = enabled ? 1 : 0;
25961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
25971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // For single SIM phones, this is a per phone property.
25981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (TelephonyManager.getDefault().getSimCount() == 1) {
25991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Settings.Global.putInt(mResolver, Settings.Global.DATA_ROAMING, roaming);
260021e6af8d6197a071d025733fffeffc157d0085bcfionaxu                setDataRoamingFromUserAction(true);
26011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
26021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Settings.Global.putInt(mResolver, Settings.Global.DATA_ROAMING +
26031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                         phoneSubId, roaming);
26041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
26051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
26061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSubscriptionManager.setDataRoaming(roaming, phoneSubId);
26071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // will trigger handleDataOnRoamingChange() through observer
26081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
260921e6af8d6197a071d025733fffeffc157d0085bcfionaxu                log("setDataRoamingEnabledByUser: set phoneSubId=" + phoneSubId
26105b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu                        + " isRoaming=" + enabled);
26111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
26121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
26131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
261421e6af8d6197a071d025733fffeffc157d0085bcfionaxu                log("setDataRoamingEnabledByUser: unchanged phoneSubId=" + phoneSubId
26151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        + " isRoaming=" + enabled);
26161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu             }
26171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
26181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
26191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
26201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
26211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Return current {@link android.provider.Settings.Global#DATA_ROAMING} value.
26221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
26235b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    public boolean getDataRoamingEnabled() {
262421e6af8d6197a071d025733fffeffc157d0085bcfionaxu        boolean isDataRoamingEnabled;
26251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        final int phoneSubId = mPhone.getSubId();
26261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2627985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen        // For single SIM phones, this is a per phone property.
2628985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen        if (TelephonyManager.getDefault().getSimCount() == 1) {
2629985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen            isDataRoamingEnabled = Settings.Global.getInt(mResolver,
2630985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen                    Settings.Global.DATA_ROAMING,
2631985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen                    getDefaultDataRoamingEnabled() ? 1 : 0) != 0;
2632985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen        } else {
2633985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen            isDataRoamingEnabled = Settings.Global.getInt(mResolver,
2634985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen                    Settings.Global.DATA_ROAMING + phoneSubId,
2635985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen                    getDefaultDataRoamingEnabled() ? 1 : 0) != 0;
26361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
2637985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen
26381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) {
26395b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            log("getDataRoamingEnabled: phoneSubId=" + phoneSubId
26405b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu                    + " isDataRoamingEnabled=" + isDataRoamingEnabled);
26411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
26421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return isDataRoamingEnabled;
26431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
26441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
264521e6af8d6197a071d025733fffeffc157d0085bcfionaxu    /**
264621e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * get default values for {@link Settings.Global#DATA_ROAMING}
264721e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * return {@code true} if either
264821e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} or
264921e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * system property ro.com.android.dataroaming is set to true. otherwise return {@code false}
265021e6af8d6197a071d025733fffeffc157d0085bcfionaxu     */
265121e6af8d6197a071d025733fffeffc157d0085bcfionaxu    private boolean getDefaultDataRoamingEnabled() {
265221e6af8d6197a071d025733fffeffc157d0085bcfionaxu        final CarrierConfigManager configMgr = (CarrierConfigManager)
265321e6af8d6197a071d025733fffeffc157d0085bcfionaxu                mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
265421e6af8d6197a071d025733fffeffc157d0085bcfionaxu        boolean isDataRoamingEnabled = "true".equalsIgnoreCase(SystemProperties.get(
265521e6af8d6197a071d025733fffeffc157d0085bcfionaxu                "ro.com.android.dataroaming", "false"));
265621e6af8d6197a071d025733fffeffc157d0085bcfionaxu        isDataRoamingEnabled |= configMgr.getConfigForSubId(mPhone.getSubId()).getBoolean(
265721e6af8d6197a071d025733fffeffc157d0085bcfionaxu                CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
265821e6af8d6197a071d025733fffeffc157d0085bcfionaxu        return isDataRoamingEnabled;
265921e6af8d6197a071d025733fffeffc157d0085bcfionaxu    }
266021e6af8d6197a071d025733fffeffc157d0085bcfionaxu
266121e6af8d6197a071d025733fffeffc157d0085bcfionaxu    /**
266221e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * Set default value for {@link android.provider.Settings.Global#DATA_ROAMING}
266321e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * if the setting is not from user actions. default value is based on carrier config and system
266421e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * properties.
266521e6af8d6197a071d025733fffeffc157d0085bcfionaxu     */
266621e6af8d6197a071d025733fffeffc157d0085bcfionaxu    private void setDefaultDataRoamingEnabled() {
266721e6af8d6197a071d025733fffeffc157d0085bcfionaxu        // For single SIM phones, this is a per phone property.
266821e6af8d6197a071d025733fffeffc157d0085bcfionaxu        String setting = Settings.Global.DATA_ROAMING;
266921e6af8d6197a071d025733fffeffc157d0085bcfionaxu        boolean useCarrierSpecificDefault = false;
267021e6af8d6197a071d025733fffeffc157d0085bcfionaxu        if (TelephonyManager.getDefault().getSimCount() != 1) {
267121e6af8d6197a071d025733fffeffc157d0085bcfionaxu            setting = setting + mPhone.getSubId();
267221e6af8d6197a071d025733fffeffc157d0085bcfionaxu            try {
267321e6af8d6197a071d025733fffeffc157d0085bcfionaxu                Settings.Global.getInt(mResolver, setting);
267421e6af8d6197a071d025733fffeffc157d0085bcfionaxu            } catch (SettingNotFoundException ex) {
267521e6af8d6197a071d025733fffeffc157d0085bcfionaxu                // For msim, update to carrier default if uninitialized.
267621e6af8d6197a071d025733fffeffc157d0085bcfionaxu                useCarrierSpecificDefault = true;
267721e6af8d6197a071d025733fffeffc157d0085bcfionaxu            }
267821e6af8d6197a071d025733fffeffc157d0085bcfionaxu        } else if (!isDataRoamingFromUserAction()) {
267921e6af8d6197a071d025733fffeffc157d0085bcfionaxu            // for single sim device, update to carrier default if user action is not set
268021e6af8d6197a071d025733fffeffc157d0085bcfionaxu            useCarrierSpecificDefault = true;
268121e6af8d6197a071d025733fffeffc157d0085bcfionaxu        }
268221e6af8d6197a071d025733fffeffc157d0085bcfionaxu        if (useCarrierSpecificDefault) {
268321e6af8d6197a071d025733fffeffc157d0085bcfionaxu            boolean defaultVal = getDefaultDataRoamingEnabled();
268421e6af8d6197a071d025733fffeffc157d0085bcfionaxu            log("setDefaultDataRoamingEnabled: " + setting + "default value: " + defaultVal);
268521e6af8d6197a071d025733fffeffc157d0085bcfionaxu            Settings.Global.putInt(mResolver, setting, defaultVal ? 1 : 0);
268621e6af8d6197a071d025733fffeffc157d0085bcfionaxu            mSubscriptionManager.setDataRoaming(defaultVal ? 1 : 0, mPhone.getSubId());
268721e6af8d6197a071d025733fffeffc157d0085bcfionaxu        }
268821e6af8d6197a071d025733fffeffc157d0085bcfionaxu    }
268921e6af8d6197a071d025733fffeffc157d0085bcfionaxu
269021e6af8d6197a071d025733fffeffc157d0085bcfionaxu    private boolean isDataRoamingFromUserAction() {
269121e6af8d6197a071d025733fffeffc157d0085bcfionaxu        final SharedPreferences sp = PreferenceManager
269221e6af8d6197a071d025733fffeffc157d0085bcfionaxu                .getDefaultSharedPreferences(mPhone.getContext());
269321e6af8d6197a071d025733fffeffc157d0085bcfionaxu        // since we don't want to unset user preference from system update, pass true as the default
269421e6af8d6197a071d025733fffeffc157d0085bcfionaxu        // value if shared pref does not exist and set shared pref to false explicitly from factory
269521e6af8d6197a071d025733fffeffc157d0085bcfionaxu        // reset.
269621e6af8d6197a071d025733fffeffc157d0085bcfionaxu        if (!sp.contains(Phone.DATA_ROAMING_IS_USER_SETTING_KEY)
269721e6af8d6197a071d025733fffeffc157d0085bcfionaxu                && Settings.Global.getInt(mResolver, Settings.Global.DEVICE_PROVISIONED, 0) == 0) {
269821e6af8d6197a071d025733fffeffc157d0085bcfionaxu            sp.edit().putBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, false).commit();
269921e6af8d6197a071d025733fffeffc157d0085bcfionaxu        }
270021e6af8d6197a071d025733fffeffc157d0085bcfionaxu        return sp.getBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, true);
270121e6af8d6197a071d025733fffeffc157d0085bcfionaxu    }
270221e6af8d6197a071d025733fffeffc157d0085bcfionaxu
270321e6af8d6197a071d025733fffeffc157d0085bcfionaxu    private void setDataRoamingFromUserAction(boolean isUserAction) {
270421e6af8d6197a071d025733fffeffc157d0085bcfionaxu        final SharedPreferences.Editor sp = PreferenceManager
270521e6af8d6197a071d025733fffeffc157d0085bcfionaxu                .getDefaultSharedPreferences(mPhone.getContext()).edit();
270621e6af8d6197a071d025733fffeffc157d0085bcfionaxu        sp.putBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, isUserAction).commit();
270721e6af8d6197a071d025733fffeffc157d0085bcfionaxu    }
270821e6af8d6197a071d025733fffeffc157d0085bcfionaxu
27095b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    // When the data roaming status changes from roaming to non-roaming.
27105b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    private void onDataRoamingOff() {
27115b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (DBG) log("onDataRoamingOff");
2712c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
27135b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (!getDataRoamingEnabled()) {
27145b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // TODO: Remove this once all old vendor RILs are gone. We don't need to set initial apn
27155b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // attach and send the data profile again as the modem should have both roaming and
27165b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // non-roaming protocol in place. Modem should choose the right protocol based on the
27175b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // roaming condition.
27185b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            setInitialAttachApn();
27195b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            setDataProfilesAsNeeded();
27208e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu
27215b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // If the user did not enable data roaming, now when we transit from roaming to
27225b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // non-roaming, we should try to reestablish the data connection.
2723c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2724cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_OFF);
2725bda761320929f714951c328bfec6a51a1978db97Wink Saville            setupDataOnConnectableApns(Phone.REASON_ROAMING_OFF);
2726cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2727cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_ROAMING_OFF);
2728cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2729cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2730cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
27315b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    // This method is called
27325b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    // 1. When the data roaming status changes from non-roaming to roaming.
27335b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    // 2. When allowed data roaming settings is changed by the user.
2734d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen    private void onDataRoamingOnOrSettingsChanged(int messageType) {
27355b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (DBG) log("onDataRoamingOnOrSettingsChanged");
2736d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen        // Used to differentiate data roaming turned on vs settings changed.
2737d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen        boolean settingChanged = (messageType == DctConstants.EVENT_ROAMING_SETTING_CHANGE);
2738f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu
2739f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu        // Check if the device is actually data roaming
2740f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu        if (!mPhone.getServiceState().getDataRoaming()) {
2741f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu            if (DBG) log("device is not roaming. ignored the request.");
2742f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu            return;
2743f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu        }
2744cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2745d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen        checkDataRoamingStatus(settingChanged);
2746d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen
27475b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (getDataRoamingEnabled()) {
27485b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            if (DBG) log("onDataRoamingOnOrSettingsChanged: setup data on roaming");
27495b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu
2750ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_ROAMING_ON);
2751cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_ROAMING_ON);
2752cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
27535b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // If the user does not turn on data roaming, when we transit from non-roaming to
27545b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // roaming, we need to tear down the data connection otherwise the user might be
27555b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // charged for data roaming usage.
27565b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            if (DBG) log("onDataRoamingOnOrSettingsChanged: Tear down data connection on roaming.");
2757cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpAllConnections(true, Phone.REASON_ROAMING_ON);
2758cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
2759cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2760cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2761cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2762d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen    // We want to track possible roaming data leakage. Which is, if roaming setting
2763d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen    // is disabled, yet we still setup a roaming data connection or have a connected ApnContext
2764d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen    // switched to roaming. When this happens, we log it in a local log.
2765d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen    private void checkDataRoamingStatus(boolean settingChanged) {
2766d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen        if (!settingChanged && !getDataRoamingEnabled()
2767d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                && mPhone.getServiceState().getDataRoaming()) {
2768d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen            for (ApnContext apnContext : mApnContexts.values()) {
2769d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                if (apnContext.getState() == DctConstants.State.CONNECTED) {
2770d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                    mDataRoamingLeakageLog.log("PossibleRoamingLeakage "
2771d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                            + " connection params: " + (apnContext.getDcAc() != null
2772d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                            ? apnContext.getDcAc().mLastConnectionParams : ""));
2773d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                }
2774d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen            }
2775d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen        }
2776d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen    }
2777d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen
27781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRadioAvailable() {
2779cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onRadioAvailable");
2780cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
2781cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
2782cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
2783cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // setState(DctConstants.State.CONNECTED);
2784cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(null);
2785cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2786cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("onRadioAvailable: We're on the simulator; assuming data is connected");
2787cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2788cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2789cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
2790cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (r != null && r.getRecordsLoaded()) {
2791cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(null);
2792cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2793cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2794cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getOverallState() != DctConstants.State.IDLE) {
2795cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpConnection(true, null);
2796cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2797cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2798cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
27991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRadioOffOrNotAvailable() {
2800cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Make sure our reconnect delay starts at the initial value
2801cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // next time the radio comes on
2802cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2803cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mReregisterOnReconnectFailure = false;
2804cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
28057e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C        // Clear auto attach as modem is expected to do a new attach
28067e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C        mAutoAttachOnCreation.set(false);
28077e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C
2808cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
2809cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
2810cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
2811cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("We're on the simulator; assuming radio off is meaningless");
2812cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2813cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRadioOffOrNotAvailable: is off and clean up all connections");
2814cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpAllConnections(false, Phone.REASON_RADIO_TURNED_OFF);
2815cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2816cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyOffApnsOfAvailability(null);
2817cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2818cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
28191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void completeConnection(ApnContext apnContext) {
2820c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2821c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (DBG) log("completeConnection: successful, notify the world apnContext=" + apnContext);
2822c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2823c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (mIsProvisioning && !TextUtils.isEmpty(mProvisioningUrl)) {
2824c9b81a0c05128694c617fcdd67e73821895822feWink Saville            if (DBG) {
2825c9b81a0c05128694c617fcdd67e73821895822feWink Saville                log("completeConnection: MOBILE_PROVISIONING_ACTION url="
2826c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        + mProvisioningUrl);
2827c9b81a0c05128694c617fcdd67e73821895822feWink Saville            }
2828c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt            Intent newIntent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN,
2829c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt                    Intent.CATEGORY_APP_BROWSER);
2830c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt            newIntent.setData(Uri.parse(mProvisioningUrl));
2831c9b81a0c05128694c617fcdd67e73821895822feWink Saville            newIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
2832c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    Intent.FLAG_ACTIVITY_NEW_TASK);
2833c9b81a0c05128694c617fcdd67e73821895822feWink Saville            try {
2834c9b81a0c05128694c617fcdd67e73821895822feWink Saville                mPhone.getContext().startActivity(newIntent);
2835c9b81a0c05128694c617fcdd67e73821895822feWink Saville            } catch (ActivityNotFoundException e) {
2836c9b81a0c05128694c617fcdd67e73821895822feWink Saville                loge("completeConnection: startActivityAsUser failed" + e);
2837c9b81a0c05128694c617fcdd67e73821895822feWink Saville            }
2838c9b81a0c05128694c617fcdd67e73821895822feWink Saville        }
2839c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mIsProvisioning = false;
2840c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mProvisioningUrl = null;
28412b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        if (mProvisioningSpinner != null) {
28422b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            sendMessage(obtainMessage(DctConstants.CMD_CLEAR_PROVISIONING_SPINNER,
28432b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner));
28442b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        }
2845c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2846c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
2847c9b81a0c05128694c617fcdd67e73821895822feWink Saville        startNetStatPoll();
2848c9b81a0c05128694c617fcdd67e73821895822feWink Saville        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
2849c9b81a0c05128694c617fcdd67e73821895822feWink Saville    }
2850c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2851ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
2852ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * A SETUP (aka bringUp) has completed, possibly with an error. If
2853ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * there is an error this method will call {@link #onDataSetupCompleteError}.
2854ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
28551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataSetupComplete(AsyncResult ar) {
2856608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt
2857ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        DcFailCause cause = DcFailCause.UNKNOWN;
2858cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean handleError = false;
2859ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDataSetupComplete");
2860cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2861ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
2862cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2863cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (ar.exception == null) {
2864454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = apnContext.getDcAc();
2865cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2866cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (RADIO_TESTS) {
2867cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Note: To change radio.test.onDSC.null.dcac from command line you need to
2868cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // adb root and adb remount and from the command line you can only change the
2869cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // value to 1 once. To change it a second time you can reboot or execute
2870cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // adb shell stop and then adb shell start. The command line to set the value is:
2871ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink 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');"
2872cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ContentResolver cr = mPhone.getContext().getContentResolver();
2873cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                String radioTestProperty = "radio.test.onDSC.null.dcac";
2874cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (Settings.System.getInt(cr, radioTestProperty, 0) == 1) {
2875cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: " + radioTestProperty +
2876cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            " is true, set dcac to null and reset property to false");
2877cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    dcac = null;
2878cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    Settings.System.putInt(cr, radioTestProperty, 0);
2879cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: " + radioTestProperty + "=" +
2880cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            Settings.System.getInt(mPhone.getContext().getContentResolver(),
2881cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                    radioTestProperty, -1));
2882cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2883c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2884cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac == null) {
2885cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("onDataSetupComplete: no connection to DC, handle as error");
2886ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                cause = DcFailCause.CONNECTION_TO_DATACONNECTIONAC_BROKEN;
2887cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                handleError = true;
2888cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
2889cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ApnSetting apn = apnContext.getApnSetting();
2890cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
2891cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: success apn=" + (apn == null ? "unknown" : apn.apn));
2892cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2893cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn != null && apn.proxy != null && apn.proxy.length() != 0) {
2894cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    try {
2895cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        String port = apn.port;
2896cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (TextUtils.isEmpty(port)) port = "8080";
28979c180aedfc9f0d20525c0128487d3500e6c0a715Jason Monk                        ProxyInfo proxy = new ProxyInfo(apn.proxy,
2898cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                Integer.parseInt(port), null);
2899cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        dcac.setLinkPropertiesHttpProxySync(proxy);
2900cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    } catch (NumberFormatException e) {
2901cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        loge("onDataSetupComplete: NumberFormatException making ProxyProperties (" +
2902cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                apn.port + "): " + e);
2903cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2904cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2905cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2906cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // everything is setup
2907d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                if (TextUtils.equals(apnContext.getApnType(), PhoneConstants.APN_TYPE_DEFAULT)) {
290827b650c406018355a88a41528db7859e232728a0Jack Yu                    try {
290927b650c406018355a88a41528db7859e232728a0Jack Yu                        SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "true");
291027b650c406018355a88a41528db7859e232728a0Jack Yu                    } catch (RuntimeException ex) {
291127b650c406018355a88a41528db7859e232728a0Jack Yu                        log("Failed to set PUPPET_MASTER_RADIO_STRESS_TEST to true");
291227b650c406018355a88a41528db7859e232728a0Jack Yu                    }
291322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mCanSetPreferApn && mPreferredApn == null) {
29140e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                        if (DBG) log("onDataSetupComplete: PREFERRED APN is null");
2915cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mPreferredApn = apn;
2916cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (mPreferredApn != null) {
2917cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            setPreferredApn(mPreferredApn.id);
2918cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
2919cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2920cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
292127b650c406018355a88a41528db7859e232728a0Jack Yu                    try {
292227b650c406018355a88a41528db7859e232728a0Jack Yu                        SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
292327b650c406018355a88a41528db7859e232728a0Jack Yu                    } catch (RuntimeException ex) {
292427b650c406018355a88a41528db7859e232728a0Jack Yu                        log("Failed to set PUPPET_MASTER_RADIO_STRESS_TEST to false");
292527b650c406018355a88a41528db7859e232728a0Jack Yu                    }
2926cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2927c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2928c9b81a0c05128694c617fcdd67e73821895822feWink Saville                // A connection is setup
2929c9b81a0c05128694c617fcdd67e73821895822feWink Saville                apnContext.setState(DctConstants.State.CONNECTED);
29300e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
2931d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                checkDataRoamingStatus(false);
2932d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen
2933c9b81a0c05128694c617fcdd67e73821895822feWink Saville                boolean isProvApn = apnContext.isProvisioningApn();
2934b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                final ConnectivityManager cm = ConnectivityManager.from(mPhone.getContext());
2935b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                if (mProvisionBroadcastReceiver != null) {
2936b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mPhone.getContext().unregisterReceiver(mProvisionBroadcastReceiver);
2937b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mProvisionBroadcastReceiver = null;
2938b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                }
2939c9b81a0c05128694c617fcdd67e73821895822feWink Saville                if ((!isProvApn) || mIsProvisioning) {
2940b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // Hide any provisioning notification.
2941b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    cm.setProvisioningNotificationVisible(false, ConnectivityManager.TYPE_MOBILE,
2942b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                            mProvisionActionName);
2943c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // Complete the connection normally notifying the world we're connected.
2944c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // We do this if this isn't a special provisioning apn or if we've been
2945c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // told its time to provision.
2946c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    completeConnection(apnContext);
2947c9b81a0c05128694c617fcdd67e73821895822feWink Saville                } else {
2948c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // This is a provisioning APN that we're reporting as connected. Later
2949c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // when the user desires to upgrade this to a "default" connection,
2950c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // mIsProvisioning == true, we'll go through the code path above.
2951c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // mIsProvisioning becomes true when CMD_ENABLE_MOBILE_PROVISIONING
2952c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // is sent to the DCT.
2953c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    if (DBG) {
2954c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        log("onDataSetupComplete: successful, BUT send connected to prov apn as"
2955c9b81a0c05128694c617fcdd67e73821895822feWink Saville                                + " mIsProvisioning:" + mIsProvisioning + " == false"
2956c9b81a0c05128694c617fcdd67e73821895822feWink Saville                                + " && (isProvisioningApn:" + isProvApn + " == true");
2957c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    }
2958c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2959b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // While radio is up, grab provisioning URL.  The URL contains ICCID which
2960b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // disappears when radio is off.
2961b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mProvisionBroadcastReceiver = new ProvisionNotificationBroadcastReceiver(
29622b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                            cm.getMobileProvisioningUrl(),
29632b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                            TelephonyManager.getDefault().getNetworkOperatorName());
2964b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mPhone.getContext().registerReceiver(mProvisionBroadcastReceiver,
2965b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                            new IntentFilter(mProvisionActionName));
2966b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // Put up user notification that sign-in is required.
2967b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    cm.setProvisioningNotificationVisible(true, ConnectivityManager.TYPE_MOBILE,
2968b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                            mProvisionActionName);
2969b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // Turn off radio to save battery and avoid wasting carrier resources.
2970b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // The network isn't usable and network validation will just fail anyhow.
2971b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    setRadio(false);
2972c9b81a0c05128694c617fcdd67e73821895822feWink Saville                }
2973c9b81a0c05128694c617fcdd67e73821895822feWink Saville                if (DBG) {
2974c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    log("onDataSetupComplete: SETUP complete type=" + apnContext.getApnType()
2975c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        + ", reason:" + apnContext.getReason());
2976c9b81a0c05128694c617fcdd67e73821895822feWink Saville                }
29774c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                if (Build.IS_DEBUGGABLE) {
29784c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                    // adb shell setprop persist.radio.test.pco [pco_val]
29794c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                    String radioTestProperty = "persist.radio.test.pco";
2980cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    int pcoVal = SystemProperties.getInt(radioTestProperty, -1);
2981cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    if (pcoVal != -1) {
2982cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        log("PCO testing: read pco value from persist.radio.test.pco " + pcoVal);
2983cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        final byte[] value = new byte[1];
2984cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        value[0] = (byte) pcoVal;
2985cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        final Intent intent =
2986cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                                new Intent(TelephonyIntents.ACTION_CARRIER_SIGNAL_PCO_VALUE);
2987cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        intent.putExtra(TelephonyIntents.EXTRA_APN_TYPE_KEY, "default");
2988cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        intent.putExtra(TelephonyIntents.EXTRA_APN_PROTO_KEY, "IPV4V6");
2989cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        intent.putExtra(TelephonyIntents.EXTRA_PCO_ID_KEY, 0xFF00);
2990cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        intent.putExtra(TelephonyIntents.EXTRA_PCO_VALUE_KEY, value);
2991cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
2992cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    }
29934c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                }
2994c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2995cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2996ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            cause = (DcFailCause) (ar.result);
2997cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
2998cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ApnSetting apn = apnContext.getApnSetting();
2999cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log(String.format("onDataSetupComplete: error apn=%s cause=%s",
3000cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        (apn == null ? "unknown" : apn.apn), cause));
3001c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3002cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cause.isEventLoggable()) {
3003cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Log this failure to the Event Logs.
3004cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                int cid = getCellLocationId();
3005cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                EventLog.writeEvent(EventLogTags.PDP_SETUP_FAIL,
3006cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        cause.ordinal(), cid, TelephonyManager.getDefault().getNetworkType());
3007c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
30080742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela            ApnSetting apn = apnContext.getApnSetting();
30090742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela            mPhone.notifyPreciseDataConnectionFailed(apnContext.getReason(),
30100742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela                    apnContext.getApnType(), apn != null ? apn.apn : "unknown", cause.toString());
3011cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
30124c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            // Compose broadcast intent send to the specific carrier signaling receivers
30134c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            Intent intent = new Intent(TelephonyIntents
30144c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                    .ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED);
30154c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            intent.putExtra(TelephonyIntents.EXTRA_ERROR_CODE_KEY, cause.getErrorCode());
30164c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            intent.putExtra(TelephonyIntents.EXTRA_APN_TYPE_KEY, apnContext.getApnType());
30174c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
3018a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
301931f84bf1a4f1c945f7ca4646095ef4717a261c98Jordan Liu            if (cause.isRestartRadioFail(mPhone.getContext(), mPhone.getSubId()) ||
302031f84bf1a4f1c945f7ca4646095ef4717a261c98Jordan Liu                    apnContext.restartOnError(cause.getErrorCode())) {
30210e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                if (DBG) log("Modem restarted.");
30220e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                sendRestartRadio();
30230e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            }
3024cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
30250e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // If the data call failure cause is a permanent failure, we mark the APN as permanent
30260e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // failed.
3027ccfe5ebaf81c1378e8dbe44e45df26b0dc462a21Jack Yu            if (isPermanentFailure(cause)) {
30280e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                log("cause = " + cause + ", mark apn as permanent failed. apn = " + apn);
30290e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                apnContext.markApnPermanentFailed(apn);
3030c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
30310e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
3032cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            handleError = true;
3033cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3034cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3035cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (handleError) {
3036ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            onDataSetupCompleteError(ar);
3037ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
3038a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3039a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        /* If flag is set to false after SETUP_DATA_CALL is invoked, we need
3040a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         * to clean data connections.
3041a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         */
3042a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        if (!mDataEnabledSettings.isInternalDataEnabled()) {
30434fdc57b9bf223c908474c4545cc6f63456117a3bSanket Padawe            cleanUpAllConnections(Phone.REASON_DATA_DISABLED);
3044a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
3045a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3046ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
3047cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3048ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
3049ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt     * check for obsolete messages.  Return ApnContext if valid, null if not
3050ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt     */
3051ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt    private ApnContext getValidApnContext(AsyncResult ar, String logString) {
3052ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (ar != null && ar.userObj instanceof Pair) {
3053ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            Pair<ApnContext, Integer>pair = (Pair<ApnContext, Integer>)ar.userObj;
3054ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            ApnContext apnContext = pair.first;
3055ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            if (apnContext != null) {
30561a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                final int generation = apnContext.getConnectionGeneration();
30571a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                if (DBG) {
30581a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                    log("getValidApnContext (" + logString + ") on " + apnContext + " got " +
30591a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                            generation + " vs " + pair.second);
30601a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                }
30611a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                if (generation == pair.second) {
3062ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                    return apnContext;
3063ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                } else {
3064ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                    log("ignoring obsolete " + logString);
3065ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                    return null;
3066ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                }
3067ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            }
3068ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        }
3069ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        throw new RuntimeException(logString + ": No apnContext");
3070ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt    }
3071ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt
3072ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt    /**
3073ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Error has occurred during the SETUP {aka bringUP} request and the DCT
3074ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * should either try the next waiting APN or start over from the
3075ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * beginning if the list is empty. Between each SETUP request there will
3076ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville     * be a delay defined by {@link #getApnDelay()}.
3077ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
30781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataSetupCompleteError(AsyncResult ar) {
30790e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
3080ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDataSetupCompleteError");
3081ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3082ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
3083ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
30840e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        long delay = apnContext.getDelayForNextApn(mFailFast);
3085ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
30860e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        // Check if we need to retry or not.
30870852a954be5937a1b0bca94df0c2007d7ee3c0c7Jack Yu        if (delay >= 0) {
30880e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (DBG) log("onDataSetupCompleteError: Try next APN. delay = " + delay);
3089ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext.setState(DctConstants.State.SCANNING);
3090ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // Wait a bit before trying the next APN, so that
3091ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // we're not tying up the RIL command channel
30920e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            startAlarmForReconnect(delay, apnContext);
30930e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        } else {
30940e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // If we are not going to retry any APN, set this APN context to failed state.
30950e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // This would be the final state of a data connection.
30960e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            apnContext.setState(DctConstants.State.FAILED);
30970e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType());
30980e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            apnContext.setDataConnectionAc(null);
30990e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            log("onDataSetupCompleteError: Stop retrying APNs.");
3100c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3101c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3102c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3103c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
3104a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu     * Called when EVENT_REDIRECTION_DETECTED is received.
3105a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu     */
31064c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu    private void onDataConnectionRedirected(String redirectUrl) {
3107a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        if (!TextUtils.isEmpty(redirectUrl)) {
31084c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            Intent intent = new Intent(TelephonyIntents.ACTION_CARRIER_SIGNAL_REDIRECTED);
31094c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            intent.putExtra(TelephonyIntents.EXTRA_REDIRECTION_URL_KEY, redirectUrl);
31106a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu            mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
31116a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu            log("Notify carrier signal receivers with redirectUrl: " + redirectUrl);
3112a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        }
3113a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    }
3114a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
3115a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    /**
3116cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Called when EVENT_DISCONNECT_DONE is received.
3117c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
31181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDisconnectDone(AsyncResult ar) {
3119ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDisconnectDone");
3120ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
3121c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3122cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE apnContext=" + apnContext);
3123cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setState(DctConstants.State.IDLE);
3124cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3125cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
3126cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3127cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // if all data connection are gone, check whether Airplane mode request was
3128cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // pending.
3129cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isDisconnected()) {
3130cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPhone.getServiceStateTracker().processPendingRadioPowerOffAfterDataOff()) {
3131a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                if (DBG) log("onDisconnectDone: radio will be turned off, no retries");
3132cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Radio will be turned off. No need to retry data setup
3133cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setApnSetting(null);
3134cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setDataConnectionAc(null);
3135a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3136a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // Need to notify disconnect as well, in the case of switching Airplane mode.
3137a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // Otherwise, it would cause 30s delayed to turn on Airplane mode.
31380e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                if (mDisconnectPendingCount > 0) {
3139a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mDisconnectPendingCount--;
31400e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                }
3141a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3142a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mDisconnectPendingCount == 0) {
3143a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    notifyDataDisconnectComplete();
3144a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    notifyAllDataDisconnected();
3145a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
3146cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return;
3147cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3148c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3149cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // If APN is still enabled, try to bring it back up automatically
31503fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (mAttached.get() && apnContext.isReady() && retryAfterDisconnected(apnContext)) {
315127b650c406018355a88a41528db7859e232728a0Jack Yu            try {
315227b650c406018355a88a41528db7859e232728a0Jack Yu                SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
315327b650c406018355a88a41528db7859e232728a0Jack Yu            } catch (RuntimeException ex) {
315427b650c406018355a88a41528db7859e232728a0Jack Yu                log("Failed to set PUPPET_MASTER_RADIO_STRESS_TEST to false");
315527b650c406018355a88a41528db7859e232728a0Jack Yu            }
3156cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Wait a bit before trying the next APN, so that
3157cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // we're not tying up the RIL command channel.
3158cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // This also helps in any external dependency to turn off the context.
31590e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (DBG) log("onDisconnectDone: attached, ready and retry after disconnect");
3160da21f0de2087657b20b18817b33d59778720bffbJack Yu            long delay = apnContext.getRetryAfterDisconnectDelay();
31610e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (delay > 0) {
31620e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                // Data connection is in IDLE state, so when we reconnect later, we'll rebuild
31630e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                // the waiting APN list, which will also reset/reconfigure the retry manager.
31640e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                startAlarmForReconnect(delay, apnContext);
31650e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            }
3166c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
3167449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            boolean restartRadioAfterProvisioning = mPhone.getContext().getResources().getBoolean(
3168449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                    com.android.internal.R.bool.config_restartRadioAfterProvisioning);
3169449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville
3170449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            if (apnContext.isProvisioningApn() && restartRadioAfterProvisioning) {
3171449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                log("onDisconnectDone: restartRadio after provisioning");
3172449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                restartRadio();
3173449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            }
3174cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setApnSetting(null);
3175cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setDataConnectionAc(null);
31763fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())) {
3177449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                if(DBG) log("onDisconnectDone: isOnlySigneDcAllowed true so setup single apn");
31783fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                setupDataOnConnectableApns(Phone.REASON_SINGLE_PDN_ARBITRATION);
3179449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            } else {
3180449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                if(DBG) log("onDisconnectDone: not retrying");
31813fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
3182c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3183a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3184a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mDisconnectPendingCount > 0)
3185a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mDisconnectPendingCount--;
3186a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3187a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mDisconnectPendingCount == 0) {
3188c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt            apnContext.setConcurrentVoiceAndDataAllowed(
3189c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed());
3190a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyDataDisconnectComplete();
3191a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
3192a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
3193a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3194c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3195c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3196ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
3197ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Called when EVENT_DISCONNECT_DC_RETRYING is received.
3198ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
31991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDisconnectDcRetrying(AsyncResult ar) {
3200ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // We could just do this in DC!!!
3201ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDisconnectDcRetrying");
3202ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
3203ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3204ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setState(DctConstants.State.RETRYING);
3205ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if(DBG) log("onDisconnectDcRetrying: apnContext=" + apnContext);
3206ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3207ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
3208ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
3209ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
32101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onVoiceCallStarted() {
3211cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onVoiceCallStarted");
3212ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        mInVoiceCall = true;
3213cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnected() && ! mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
3214cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onVoiceCallStarted stop polling");
3215cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            stopNetStatPoll();
3216cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            stopDataStallAlarm();
3217cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
3218c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3219c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3220c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onVoiceCallEnded() {
3222cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onVoiceCallEnded");
3223ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        mInVoiceCall = false;
3224cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnected()) {
3225cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
3226cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                startNetStatPoll();
3227cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
3228cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
3229cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
3230cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // clean slate after call end.
3231cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                resetPollStats();
3232c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3233c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3234bda761320929f714951c328bfec6a51a1978db97Wink Saville        // reset reconnect timer
3235bda761320929f714951c328bfec6a51a1978db97Wink Saville        setupDataOnConnectableApns(Phone.REASON_VOICE_CALL_ENDED);
3236c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3237c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onCleanUpConnection(boolean tearDown, int apnId, String reason) {
3239cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onCleanUpConnection");
3240af5593594070f825032be46dced573cd195956e1Robert Greenwalt        ApnContext apnContext = mApnContextsById.get(apnId);
3241cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
3242cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setReason(reason);
3243cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpConnection(tearDown, apnContext);
3244c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3245c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3246c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean isConnected() {
3248cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
3249ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getState() == DctConstants.State.CONNECTED) {
3250cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // At least one context is connected, return true
3251cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return true;
3252c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3253c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3254cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // There are not any contexts connected, return false
3255cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return false;
3256c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3257c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3258cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isDisconnected() {
3259cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
3260cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!apnContext.isDisconnected()) {
3261cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // At least one context was not disconnected return false
3262cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
3263cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3264c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3265cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // All contexts were disconnected so return true
3266cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
3267c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3268c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyDataConnection(String reason) {
3270cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("notifyDataConnection: reason=" + reason);
3271cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
3272187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (mAttached.get() && apnContext.isReady()) {
3273187a39f896f88eb6c5e4306d9595546654825976Wink Saville                if (DBG) log("notifyDataConnection: type:" + apnContext.getApnType());
3274cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
3275cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.getApnType());
3276cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3277c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3278cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyOffApnsOfAvailability(reason);
3279c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3280c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void setDataProfilesAsNeeded() {
32821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("setDataProfilesAsNeeded");
32831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mAllApnSettings != null && !mAllApnSettings.isEmpty()) {
32841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            ArrayList<DataProfile> dps = new ArrayList<DataProfile>();
32851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (ApnSetting apn : mAllApnSettings) {
32861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (apn.modemCognitive) {
3287886183cde1263ea524cdf08524442724e246ed42Jack Yu                    DataProfile dp = createDataProfile(apn);
32888e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                    if (!dps.contains(dp)) {
32891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        dps.add(dp);
32901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
32911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
32921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
32938e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu            if (dps.size() > 0) {
32948e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                mPhone.mCi.setDataProfile(dps.toArray(new DataProfile[0]),
3295cc40713c49908aeaac0070bf4ea796247f9066b5Jack Yu                        mPhone.getServiceState().getDataRoamingFromRegistration(), null);
32961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
32971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
32981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
32991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3300c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
3301cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Based on the sim operator numeric, create a list for all possible
3302cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Data Connections and setup the preferredApn.
3303c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
3304cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void createAllApnList() {
33051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mMvnoMatched = false;
33068e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu        mAllApnSettings = new ArrayList<>();
3307cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
3308cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String operator = (r != null) ? r.getOperatorNumeric() : "";
3309cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (operator != null) {
33103c89e23cf33c3c7f795554b29cd926219f28fe34Sungmin Choi            String selection = Telephony.Carriers.NUMERIC + " = '" + operator + "'";
3311cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // query only enabled apn.
3312cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // carrier_enabled : 1 means enabled apn, 0 disabled apn.
33139d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan            // selection += " and carrier_enabled = 1";
3314cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: selection=" + selection);
3315cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
33163c89e23cf33c3c7f795554b29cd926219f28fe34Sungmin Choi            // ORDER BY Telephony.Carriers._ID ("_id")
3317cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            Cursor cursor = mPhone.getContext().getContentResolver().query(
33183c89e23cf33c3c7f795554b29cd926219f28fe34Sungmin Choi                    Telephony.Carriers.CONTENT_URI, null, selection, null, Telephony.Carriers._ID);
3319cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3320cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cursor != null) {
3321cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (cursor.getCount() > 0) {
3322ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    mAllApnSettings = createApnList(cursor);
3323cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3324cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cursor.close();
3325cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3326c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3327c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
332876f43316a5a6082d601bffd4b6898d0bd81e11fcram        addEmergencyApnSetting();
332976f43316a5a6082d601bffd4b6898d0bd81e11fcram
333029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        dedupeApnSettings();
333129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
3332ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings.isEmpty()) {
3333cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: No APN found for carrier: " + operator);
3334cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPreferredApn = null;
3335ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // TODO: What is the right behavior?
3336cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            //notifyNoData(DataConnection.FailCause.MISSING_UNKNOWN_APN);
3337c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
3338cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPreferredApn = getPreferredApn();
3339cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator)) {
3340cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn = null;
3341cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                setPreferredApn(-1);
3342cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3343cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: mPreferredApn=" + mPreferredApn);
3344c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3345ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("createAllApnList: X mAllApnSettings=" + mAllApnSettings);
33469d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan
33479d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        setDataProfilesAsNeeded();
3348c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3349c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
335029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    private void dedupeApnSettings() {
335129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        ArrayList<ApnSetting> resultApns = new ArrayList<ApnSetting>();
335229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
335329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        // coalesce APNs if they are similar enough to prevent
335429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        // us from bringing up two data calls with the same interface
335529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        int i = 0;
335629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        while (i < mAllApnSettings.size() - 1) {
335729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            ApnSetting first = mAllApnSettings.get(i);
335829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            ApnSetting second = null;
335929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            int j = i + 1;
336029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            while (j < mAllApnSettings.size()) {
336129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                second = mAllApnSettings.get(j);
33629fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                if (first.similar(second)) {
336329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    ApnSetting newApn = mergeApns(first, second);
336429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    mAllApnSettings.set(i, newApn);
336529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    first = newApn;
336629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    mAllApnSettings.remove(j);
336729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                } else {
336829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    j++;
336929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                }
337029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            }
337129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            i++;
337229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        }
337329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    }
337429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
337529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    private ApnSetting mergeApns(ApnSetting dest, ApnSetting src) {
3376bca51fc3a191d3ca30df627b75374db0941571c5Sungmin Choi        int id = dest.id;
337729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        ArrayList<String> resultTypes = new ArrayList<String>();
337829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        resultTypes.addAll(Arrays.asList(dest.types));
337929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        for (String srcType : src.types) {
338029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            if (resultTypes.contains(srcType) == false) resultTypes.add(srcType);
3381bca51fc3a191d3ca30df627b75374db0941571c5Sungmin Choi            if (srcType.equals(PhoneConstants.APN_TYPE_DEFAULT)) id = src.id;
338229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        }
338329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        String mmsc = (TextUtils.isEmpty(dest.mmsc) ? src.mmsc : dest.mmsc);
338429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        String mmsProxy = (TextUtils.isEmpty(dest.mmsProxy) ? src.mmsProxy : dest.mmsProxy);
338529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        String mmsPort = (TextUtils.isEmpty(dest.mmsPort) ? src.mmsPort : dest.mmsPort);
338661cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String proxy = (TextUtils.isEmpty(dest.proxy) ? src.proxy : dest.proxy);
338761cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String port = (TextUtils.isEmpty(dest.port) ? src.port : dest.port);
338861cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String protocol = src.protocol.equals("IPV4V6") ? src.protocol : dest.protocol;
338961cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String roamingProtocol = src.roamingProtocol.equals("IPV4V6") ? src.roamingProtocol :
339061cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                dest.roamingProtocol;
3391aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan        int bearerBitmask = (dest.bearerBitmask == 0 || src.bearerBitmask == 0) ?
3392aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                0 : (dest.bearerBitmask | src.bearerBitmask);
339329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
3394bca51fc3a191d3ca30df627b75374db0941571c5Sungmin Choi        return new ApnSetting(id, dest.numeric, dest.carrier, dest.apn,
339561cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                proxy, port, mmsc, mmsProxy, mmsPort, dest.user, dest.password,
339661cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                dest.authType, resultTypes.toArray(new String[0]), protocol,
3397aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                roamingProtocol, dest.carrierEnabled, 0, bearerBitmask, dest.profileId,
339829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                (dest.modemCognitive || src.modemCognitive), dest.maxConns, dest.waitTime,
339929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                dest.maxConnsTime, dest.mtu, dest.mvnoType, dest.mvnoMatchData);
340029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    }
340129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
3402ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /** Return the DC AsyncChannel for the new data connection */
3403454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel createDataConnection() {
3404cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createDataConnection E");
3405cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3406cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int id = mUniqueIdGenerator.getAndIncrement();
3407ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        DataConnection conn = DataConnection.makeDataConnection(mPhone, id,
3408ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                                this, mDcTesterFailBringUpAll, mDcc);
3409cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mDataConnections.put(id, conn);
3410454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac = new DcAsyncChannel(conn, LOG_TAG);
3411cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int status = dcac.fullyConnectSync(mPhone.getContext(), this, conn.getHandler());
3412cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (status == AsyncChannel.STATUS_SUCCESSFUL) {
3413ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            mDataConnectionAcHashMap.put(dcac.getDataConnectionIdSync(), dcac);
3414c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
3415ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            loge("createDataConnection: Could not connect to dcac=" + dcac + " status=" + status);
3416c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3417cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3418cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createDataConnection() X id=" + id + " dc=" + conn);
3419ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        return dcac;
3420c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3421c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3422cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void destroyDataConnections() {
3423cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(mDataConnections != null) {
3424cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("destroyDataConnections: clear mDataConnectionList");
3425cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mDataConnections.clear();
3426cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
3427cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("destroyDataConnections: mDataConnecitonList is empty, ignore");
3428c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3429c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3430c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3431c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
3432cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Build a list of APNs to be used to create PDP's.
3433c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
3434cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param requestedApnType
3435cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return waitingApns list to be used to create PDP
3436cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *          error when waitingApns.isEmpty()
3437c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
3438203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    private ArrayList<ApnSetting> buildWaitingApns(String requestedApnType, int radioTech) {
3439cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("buildWaitingApns: E requestedApnType=" + requestedApnType);
3440cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ArrayList<ApnSetting> apnList = new ArrayList<ApnSetting>();
3441cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3442cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (requestedApnType.equals(PhoneConstants.APN_TYPE_DUN)) {
3443cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ApnSetting dun = fetchDunApn();
3444cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dun != null) {
3445cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnList.add(dun);
3446cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: X added APN_TYPE_DUN apnList=" + apnList);
3447cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return apnList;
3448c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3449c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3450c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3451cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
3452cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String operator = (r != null) ? r.getOperatorNumeric() : "";
3453c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3454cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // This is a workaround for a bug (7305641) where we don't failover to other
3455cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // suitable APNs if our preferred APN fails.  On prepaid ATT sims we need to
3456cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // failover to a provisioning APN, but once we've used their default data
3457cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // connection we are locked to it for life.  This change allows ATT devices
3458cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // to say they don't want to use preferred at all.
3459cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean usePreferred = true;
3460cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        try {
3461cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            usePreferred = ! mPhone.getContext().getResources().getBoolean(com.android.
3462cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    internal.R.bool.config_dontPreferApn);
3463cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } catch (Resources.NotFoundException e) {
3464cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("buildWaitingApns: usePreferred NotFoundException set to true");
3465cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            usePreferred = true;
3466cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3467bf660a4647db8151609cdfa0ecc4c96e1518947fSungmin Choi        if (usePreferred) {
3468bf660a4647db8151609cdfa0ecc4c96e1518947fSungmin Choi            mPreferredApn = getPreferredApn();
3469bf660a4647db8151609cdfa0ecc4c96e1518947fSungmin Choi        }
3470cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
3471cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("buildWaitingApns: usePreferred=" + usePreferred
347222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    + " canSetPreferApn=" + mCanSetPreferApn
3473cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " mPreferredApn=" + mPreferredApn
3474cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " operator=" + operator + " radioTech=" + radioTech
3475cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " IccRecords r=" + r);
3476cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3477c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
347822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (usePreferred && mCanSetPreferApn && mPreferredApn != null &&
3479cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn.canHandleType(requestedApnType)) {
3480cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
3481cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("buildWaitingApns: Preferred APN:" + operator + ":"
3482cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        + mPreferredApn.numeric + ":" + mPreferredApn);
3483cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3484cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPreferredApn.numeric.equals(operator)) {
3485aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                if (ServiceState.bitmaskHasTech(mPreferredApn.bearerBitmask, radioTech)) {
3486cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnList.add(mPreferredApn);
3487cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
3488cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return apnList;
3489cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
3490cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("buildWaitingApns: no preferred APN");
3491cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    setPreferredApn(-1);
3492cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mPreferredApn = null;
3493c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
3494cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
3495cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: no preferred APN");
3496cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                setPreferredApn(-1);
3497cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn = null;
3498c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3499c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3500ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings != null) {
3501ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (DBG) log("buildWaitingApns: mAllApnSettings=" + mAllApnSettings);
3502ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for (ApnSetting apn : mAllApnSettings) {
3503cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn.canHandleType(requestedApnType)) {
3504aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                    if (ServiceState.bitmaskHasTech(apn.bearerBitmask, radioTech)) {
35059232dafa7ea833fc0b3a6024d6c7e23fc8e961eaRobert Greenwalt                        if (DBG) log("buildWaitingApns: adding apn=" + apn);
3506cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnList.add(apn);
3507c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else {
3508cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (DBG) {
3509aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                            log("buildWaitingApns: bearerBitmask:" + apn.bearerBitmask + " does " +
3510aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                                    "not include radioTech:" + radioTech);
3511cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
3512c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
35139232dafa7ea833fc0b3a6024d6c7e23fc8e961eaRobert Greenwalt                } else if (DBG) {
351427b650c406018355a88a41528db7859e232728a0Jack Yu                    log("buildWaitingApns: couldn't handle requested ApnType="
3515cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            + requestedApnType);
3516c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
3517c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3518cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
35194bd0ae43eb0cb9969dee4f30cddc18a71da68190Jack Yu            loge("mAllApnSettings is null!");
3520c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
35210e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        if (DBG) log("buildWaitingApns: " + apnList.size() + " APNs in the list: " + apnList);
3522cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return apnList;
3523c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3524c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3525cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private String apnListToString (ArrayList<ApnSetting> apns) {
3526cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        StringBuilder result = new StringBuilder();
3527cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (int i = 0, size = apns.size(); i < size; i++) {
3528cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result.append('[')
3529cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                  .append(apns.get(i).toString())
3530cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                  .append(']');
3531c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3532cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result.toString();
3533c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3534c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3535cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void setPreferredApn(int pos) {
353622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (!mCanSetPreferApn) {
3537cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("setPreferredApn: X !canSEtPreferApn");
3538cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
3539cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3540cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
35416bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        String subId = Long.toString(mPhone.getSubId());
35426bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        Uri uri = Uri.withAppendedPath(PREFERAPN_NO_UPDATE_URI_USING_SUBID, subId);
3543cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("setPreferredApn: delete");
3544cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ContentResolver resolver = mPhone.getContext().getContentResolver();
35456bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        resolver.delete(uri, null, null);
3546cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3547cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (pos >= 0) {
3548cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("setPreferredApn: insert");
3549cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ContentValues values = new ContentValues();
3550cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            values.put(APN_ID, pos);
35516bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville            resolver.insert(uri, values);
3552cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3553cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
3554cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3555cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ApnSetting getPreferredApn() {
35564bd0ae43eb0cb9969dee4f30cddc18a71da68190Jack Yu        if (mAllApnSettings == null || mAllApnSettings.isEmpty()) {
35574bd0ae43eb0cb9969dee4f30cddc18a71da68190Jack Yu            log("getPreferredApn: mAllApnSettings is " + ((mAllApnSettings == null)?"null":"empty"));
3558cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return null;
3559cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3560cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
35616bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        String subId = Long.toString(mPhone.getSubId());
35626bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        Uri uri = Uri.withAppendedPath(PREFERAPN_NO_UPDATE_URI_USING_SUBID, subId);
3563cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Cursor cursor = mPhone.getContext().getContentResolver().query(
35646bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville                uri, new String[] { "_id", "name", "apn" },
3565cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
3566cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3567cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor != null) {
356822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCanSetPreferApn = true;
3569cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
357022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCanSetPreferApn = false;
3571cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3572cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("getPreferredApn: mRequestedApnType=" + mRequestedApnType + " cursor=" + cursor
3573cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                + " cursor.count=" + ((cursor != null) ? cursor.getCount() : 0));
3574cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
357522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mCanSetPreferApn && cursor.getCount() > 0) {
3576cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            int pos;
3577cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cursor.moveToFirst();
3578cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            pos = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID));
3579ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for(ApnSetting p : mAllApnSettings) {
3580cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("getPreferredApn: apnSetting=" + p);
3581cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (p.id == pos && p.canHandleType(mRequestedApnType)) {
3582cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("getPreferredApn: X found apnSetting" + p);
3583cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    cursor.close();
3584cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return p;
3585cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3586cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
3587cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3588cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3589cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor != null) {
3590cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cursor.close();
3591cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3592cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3593cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("getPreferredApn: X not found");
3594cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
3595cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
3596cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3597cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
3598cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void handleMessage (Message msg) {
35991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) log("handleMessage msg=" + msg);
3600cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3601cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        switch (msg.what) {
3602cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_RECORDS_LOADED:
36031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // If onRecordsLoadedOrSubIdChanged() is not called here, it should be called on
36041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // onSubscriptionsChanged() when a valid subId is available.
36051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                int subId = mPhone.getSubId();
36061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (SubscriptionManager.isValidSubscriptionId(subId)) {
36071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onRecordsLoadedOrSubIdChanged();
36081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
36091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("Ignoring EVENT_RECORDS_LOADED as subId is not valid: " + subId);
36101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
3611cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3612cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3613cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_CONNECTION_DETACHED:
3614cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onDataConnectionDetached();
3615cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3616cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3617cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_CONNECTION_ATTACHED:
3618bda761320929f714951c328bfec6a51a1978db97Wink Saville                onDataConnectionAttached();
3619cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3620cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3621cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DO_RECOVERY:
3622cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                doRecovery();
3623cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3624cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3625cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_APN_CHANGED:
3626cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onApnChanged();
3627cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3628cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3629cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_PS_RESTRICT_ENABLED:
3630cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                /**
3631cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * We don't need to explicitly to tear down the PDP context
3632cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * when PS restricted is enabled. The base band will deactive
3633cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * PDP context and notify us with PDP_CONTEXT_CHANGED.
3634cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * But we should stop the network polling and prevent reset PDP.
3635cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 */
3636cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
3637cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                stopNetStatPoll();
3638cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                stopDataStallAlarm();
3639cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsPsRestricted = true;
3640cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
3641cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3642cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_PS_RESTRICT_DISABLED:
3643cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                /**
3644cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * When PS restrict is removed, we need setup PDP connection if
3645cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * PDP connection is down.
3646cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 */
3647cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_PS_RESTRICT_DISABLED " + mIsPsRestricted);
3648cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsPsRestricted  = false;
3649cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (isConnected()) {
3650cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    startNetStatPoll();
3651cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
3652cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
3653cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // TODO: Should all PDN states be checked to fail?
3654ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    if (mState == DctConstants.State.FAILED) {
3655cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        cleanUpAllConnections(false, Phone.REASON_PS_RESTRICT_ENABLED);
3656cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mReregisterOnReconnectFailure = false;
3657cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
3658af5593594070f825032be46dced573cd195956e1Robert Greenwalt                    ApnContext apnContext = mApnContextsById.get(DctConstants.APN_DEFAULT_ID);
36593fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (apnContext != null) {
36603fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        apnContext.setReason(Phone.REASON_PS_RESTRICT_ENABLED);
36613fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        trySetupData(apnContext);
36623fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    } else {
36633fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        loge("**** Default ApnContext not found ****");
36643fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        if (Build.IS_DEBUGGABLE) {
36653fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                            throw new RuntimeException("Default ApnContext not found");
36663fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        }
36673fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    }
3668cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3669cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
3670ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3671cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_TRY_SETUP_DATA:
3672cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (msg.obj instanceof ApnContext) {
3673cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    onTrySetupData((ApnContext)msg.obj);
3674cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else if (msg.obj instanceof String) {
3675cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    onTrySetupData((String)msg.obj);
3676cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
3677cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    loge("EVENT_TRY_SETUP request w/o apnContext or String");
3678cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3679cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
3680cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3681cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_CLEAN_UP_CONNECTION:
3682cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                boolean tearDown = (msg.arg1 == 0) ? false : true;
3683cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_CLEAN_UP_CONNECTION tearDown=" + tearDown);
3684cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (msg.obj instanceof ApnContext) {
3685cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    cleanUpConnection(tearDown, (ApnContext)msg.obj);
3686cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
36871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onCleanUpConnection(tearDown, msg.arg2, (String) msg.obj);
3688cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3689cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
36901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE: {
36911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
3692a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                onSetInternalDataEnabled(enabled, (Message) msg.obj);
3693a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
36941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
3695a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS:
36961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if ((msg.obj != null) && (msg.obj instanceof String == false)) {
36971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    msg.obj = null;
3698a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
36991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onCleanUpAllConnections((String) msg.obj);
3700a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
3701ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3702220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville            case DctConstants.EVENT_DATA_RAT_CHANGED:
3703b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                if (mPhone.getServiceState().getRilDataRadioTechnology()
3704b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                        == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
3705b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                    // unknown rat is an exception for data rat change. It's only received when out
3706b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                    // of service and is not applicable for apn bearer bitmask. We should bypass the
3707b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                    // check of waiting apn list and keep the data connection on, and no need to
3708b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                    // setup a new one.
3709b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                    break;
3710b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                }
3711ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                cleanUpConnectionsOnUpdatedApns(false, Phone.REASON_NW_TYPE_CHANGED);
3712220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville                //May new Network allow setupData, so try it here
3713c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                setupDataOnConnectableApns(Phone.REASON_NW_TYPE_CHANGED,
3714c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                        RetryFailures.ONLY_ON_CHANGE);
3715220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville                break;
3716220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville
37172b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            case DctConstants.CMD_CLEAR_PROVISIONING_SPINNER:
37182b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                // Check message sender intended to clear the current spinner.
37192b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                if (mProvisioningSpinner == msg.obj) {
37202b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner.dismiss();
37212b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner = null;
37222b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                }
37232b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                break;
37241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
37251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("DISCONNECTED_CONNECTED: msg=" + msg);
37261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DcAsyncChannel dcac = (DcAsyncChannel) msg.obj;
37271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mDataConnectionAcHashMap.remove(dcac.getDataConnectionIdSync());
37281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                dcac.disconnected();
37291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
37311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ENABLE_NEW_APN:
37321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onEnableApn(msg.arg1, msg.arg2);
37331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_STALL_ALARM:
37361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDataStallAlarm(msg.arg1);
37371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ROAMING_OFF:
37405b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu                onDataRoamingOff();
37411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ROAMING_ON:
3744d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen            case DctConstants.EVENT_ROAMING_SETTING_CHANGE:
3745d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen                onDataRoamingOnOrSettingsChanged(msg.what);
37461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3748f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            case DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE:
3749f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                onDeviceProvisionedChange();
3750f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                break;
3751f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
3752a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            case DctConstants.EVENT_REDIRECTION_DETECTED:
37534c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                String url = (String) msg.obj;
375468f4f4a0bc8d4060b5775e7a24a97ea5b485989efionaxu                log("dataConnectionTracker.handleMessage: EVENT_REDIRECTION_DETECTED=" + url);
37554c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                onDataConnectionRedirected(url);
3756a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
37571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RADIO_AVAILABLE:
37581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onRadioAvailable();
37591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
37621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onRadioOffOrNotAvailable();
37631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_SETUP_COMPLETE:
37661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDataSetupComplete((AsyncResult) msg.obj);
37671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_SETUP_COMPLETE_ERROR:
37701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDataSetupCompleteError((AsyncResult) msg.obj);
37711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
3772a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
37731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DISCONNECT_DONE:
37741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("DataConnectionTracker.handleMessage: EVENT_DISCONNECT_DONE msg=" + msg);
37751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDisconnectDone((AsyncResult) msg.obj);
37761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DISCONNECT_DC_RETRYING:
37791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("DataConnectionTracker.handleMessage: EVENT_DISCONNECT_DC_RETRYING msg=" + msg);
37801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDisconnectDcRetrying((AsyncResult) msg.obj);
37811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_VOICE_CALL_STARTED:
37841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onVoiceCallStarted();
37851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_VOICE_CALL_ENDED:
37881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onVoiceCallEnded();
37891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RESET_DONE: {
37921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("EVENT_RESET_DONE");
37931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onResetDone((AsyncResult) msg.obj);
37941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
37961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_USER_DATA_ENABLE: {
37971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
37981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_SET_USER_DATA_ENABLE enabled=" + enabled);
37991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onSetUserDataEnabled(enabled);
38001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
38021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // TODO - remove
38031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_DEPENDENCY_MET: {
38041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                boolean met = (msg.arg1 == DctConstants.ENABLED) ? true : false;
38051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_SET_DEPENDENCY_MET met=" + met);
38061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Bundle bundle = msg.getData();
38071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (bundle != null) {
38081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    String apnType = (String)bundle.get(DctConstants.APN_TYPE_KEY);
38091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (apnType != null) {
38101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onSetDependencyMet(apnType, met);
38111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
38121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
38151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_POLICY_DATA_ENABLE: {
38161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
38171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onSetPolicyDataEnabled(enabled);
38181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
38201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: {
38211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                sEnableFailFastRefCounter += (msg.arg1 == DctConstants.ENABLED) ? 1 : -1;
38221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
38231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: "
38241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + " sEnableFailFastRefCounter=" + sEnableFailFastRefCounter);
38251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (sEnableFailFastRefCounter < 0) {
38271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    final String s = "CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: "
38281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + "sEnableFailFastRefCounter:" + sEnableFailFastRefCounter + " < 0";
38291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge(s);
38301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    sEnableFailFastRefCounter = 0;
38311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = sEnableFailFastRefCounter > 0;
38331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
38341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: enabled=" + enabled
38351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + " sEnableFailFastRefCounter=" + sEnableFailFastRefCounter);
38361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (mFailFast != enabled) {
38381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mFailFast = enabled;
38390e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
38401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mDataStallDetectionEnabled = !enabled;
38411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mDataStallDetectionEnabled
38421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            && (getOverallState() == DctConstants.State.CONNECTED)
38431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            && (!mInVoiceCall ||
38441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    mPhone.getServiceStateTracker()
38451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                        .isConcurrentVoiceAndDataAllowed())) {
38461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: start data stall");
38471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        stopDataStallAlarm();
38481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
38491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
38501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: stop data stall");
38511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        stopDataStallAlarm();
38521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
38531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38542b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen
38551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
38571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_ENABLE_MOBILE_PROVISIONING: {
38581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Bundle bundle = msg.getData();
38591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (bundle != null) {
38601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    try {
38611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mProvisioningUrl = (String)bundle.get(DctConstants.PROVISIONING_URL_KEY);
38621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } catch(ClassCastException e) {
38631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioning url not a string" + e);
38641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mProvisioningUrl = null;
38651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
38661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (TextUtils.isEmpty(mProvisioningUrl)) {
38681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioning url is empty, ignoring");
38691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mIsProvisioning = false;
38701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mProvisioningUrl = null;
38711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
38721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioningUrl=" + mProvisioningUrl);
38731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mIsProvisioning = true;
38741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    startProvisioningApnAlarm();
38751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
38781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_PROVISIONING_APN_ALARM: {
38791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("EVENT_PROVISIONING_APN_ALARM");
3880af5593594070f825032be46dced573cd195956e1Robert Greenwalt                ApnContext apnCtx = mApnContextsById.get(DctConstants.APN_DEFAULT_ID);
38811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (apnCtx.isProvisioningApn() && apnCtx.isConnectedOrConnecting()) {
38821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mProvisioningApnAlarmTag == msg.arg1) {
38831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) log("EVENT_PROVISIONING_APN_ALARM: Disconnecting");
38841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mIsProvisioning = false;
38851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mProvisioningUrl = null;
38861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        stopProvisioningApnAlarm();
38871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        sendCleanUpConnection(true, apnCtx);
38881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
38891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) {
38901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            log("EVENT_PROVISIONING_APN_ALARM: ignore stale tag,"
38911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    + " mProvisioningApnAlarmTag:" + mProvisioningApnAlarmTag
38921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    + " != arg1:" + msg.arg1);
38931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        }
38941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
38951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
38961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (DBG) log("EVENT_PROVISIONING_APN_ALARM: Not connected ignore");
38971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_IS_PROVISIONING_APN: {
39011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_IS_PROVISIONING_APN");
39021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                boolean isProvApn;
39031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                try {
39041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    String apnType = null;
39051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    Bundle bundle = msg.getData();
39061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (bundle != null) {
39071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        apnType = (String)bundle.get(DctConstants.APN_TYPE_KEY);
39081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
39091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (TextUtils.isEmpty(apnType)) {
39101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        loge("CMD_IS_PROVISIONING_APN: apnType is empty");
39111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        isProvApn = false;
39121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
39131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        isProvApn = isProvisioningApn(apnType);
39141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
39151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } catch (ClassCastException e) {
39161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge("CMD_IS_PROVISIONING_APN: NO provisioning url ignoring");
39171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    isProvApn = false;
39181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
39191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_IS_PROVISIONING_APN: ret=" + isProvApn);
39201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mReplyAc.replyToMessage(msg, DctConstants.CMD_IS_PROVISIONING_APN,
39211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        isProvApn ? DctConstants.ENABLED : DctConstants.DISABLED);
39221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ICC_CHANGED: {
39251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onUpdateIcc();
39261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RESTART_RADIO: {
39291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartRadio();
39301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_NET_STAT_POLL: {
39331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (msg.arg1 == DctConstants.ENABLED) {
39341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    handleStartNetStatPoll((DctConstants.Activity)msg.obj);
39351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else if (msg.arg1 == DctConstants.DISABLED) {
39361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    handleStopNetStatPoll((DctConstants.Activity)msg.obj);
39371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
39381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_STATE_CHANGED: {
39411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // no longer do anything, but still registered - clean up log
39421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // TODO - why are we still registering?
39431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39452e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            case DctConstants.EVENT_PCO_DATA_RECEIVED: {
39462e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt                handlePcoData((AsyncResult)msg.obj);
39472e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt                break;
39482e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            }
3949a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            case DctConstants.EVENT_SET_CARRIER_DATA_ENABLED:
39506a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu                onSetCarrierDataEnabled((AsyncResult) msg.obj);
3951a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                break;
3952e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu            case DctConstants.EVENT_DATA_RECONNECT:
3953e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                onDataReconnect(msg.getData());
3954e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                break;
3955cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            default:
39561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Rlog.e("DcTracker", "Unhandled event=" + msg);
3957cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
39581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3959cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3960cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
3961cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
39621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int getApnProfileID(String apnType) {
3963cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IMS)) {
3964cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_IMS;
3965cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_FOTA)) {
3966cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_FOTA;
3967cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_CBS)) {
3968cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_CBS;
39691b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IA)) {
39701b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            return RILConstants.DATA_PROFILE_DEFAULT; // DEFAULT for now
397145df26444864daad60afdd4d121ab4043da3834bSungmin Choi        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_DUN)) {
397245df26444864daad60afdd4d121ab4043da3834bSungmin Choi            return RILConstants.DATA_PROFILE_TETHERED;
3973cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
3974cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_DEFAULT;
3975cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3976cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
3977cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3978cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private int getCellLocationId() {
3979cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int cid = -1;
3980cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        CellLocation loc = mPhone.getCellLocation();
3981cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3982cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (loc != null) {
3983cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (loc instanceof GsmCellLocation) {
3984cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cid = ((GsmCellLocation)loc).getCid();
3985cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else if (loc instanceof CdmaCellLocation) {
3986cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cid = ((CdmaCellLocation)loc).getBaseStationId();
3987cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
3988cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3989cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return cid;
3990cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
3991cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3992a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private IccRecords getUiccRecords(int appFamily) {
3993a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return mUiccController.getIccRecords(mPhone.getPhoneId(), appFamily);
3994a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
3995a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3996a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
39971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onUpdateIcc() {
3998cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mUiccController == null ) {
3999cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            return;
4000cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
4001cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4002a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        IccRecords newIccRecords = getUiccRecords(UiccController.APP_FAM_3GPP);
4003cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4004cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
4005cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (r != newIccRecords) {
4006cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (r != null) {
4007cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("Removing stale icc objects.");
4008cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                r.unregisterForRecordsLoaded(this);
4009cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIccRecords.set(null);
40109aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan            }
4011cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (newIccRecords != null) {
40121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (SubscriptionManager.isValidSubscriptionId(mPhone.getSubId())) {
4013aa863054476b152fe9323defd197fa946a47033fSungmin Choi                    log("New records found.");
4014aa863054476b152fe9323defd197fa946a47033fSungmin Choi                    mIccRecords.set(newIccRecords);
4015aa863054476b152fe9323defd197fa946a47033fSungmin Choi                    newIccRecords.registerForRecordsLoaded(
4016aa863054476b152fe9323defd197fa946a47033fSungmin Choi                            this, DctConstants.EVENT_RECORDS_LOADED, null);
4017aa863054476b152fe9323defd197fa946a47033fSungmin Choi                }
40180469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal            } else {
40190469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal                onSimNotReady();
40209aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan            }
40219aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan        }
4022cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
4023cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4024a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void update() {
4025a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("update sub = " + mPhone.getSubId());
4026bda761320929f714951c328bfec6a51a1978db97Wink Saville        log("update(): Active DDS, register for all events now!");
4027bda761320929f714951c328bfec6a51a1978db97Wink Saville        onUpdateIcc();
4028a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
40290979b71e48405cab10bdf1d1b4170cfce72838a7Jack Yu        mAutoAttachOnCreation.set(false);
4030bda761320929f714951c328bfec6a51a1978db97Wink Saville
40311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ((GsmCdmaPhone)mPhone).updateCurrentCarrierInProvider();
4032a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4033a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4034a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void cleanUpAllConnections(String cause) {
4035a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cleanUpAllConnections(cause, null);
4036a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4037a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4038a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void updateRecords() {
4039bda761320929f714951c328bfec6a51a1978db97Wink Saville        onUpdateIcc();
4040a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4041a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4042a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void cleanUpAllConnections(String cause, Message disconnectAllCompleteMsg) {
4043a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("cleanUpAllConnections");
4044a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (disconnectAllCompleteMsg != null) {
4045a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mDisconnectAllCompleteMsgList.add(disconnectAllCompleteMsg);
4046a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4047a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4048a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Message msg = obtainMessage(DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS);
4049a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        msg.obj = cause;
4050a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sendMessage(msg);
4051a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4052a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
40531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyDataDisconnectComplete() {
4054a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("notifyDataDisconnectComplete");
4055a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        for (Message m: mDisconnectAllCompleteMsgList) {
4056a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            m.sendToTarget();
4057a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4058a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mDisconnectAllCompleteMsgList.clear();
4059a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4060a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4061a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
40621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyAllDataDisconnected() {
4063a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sEnableFailFastRefCounter = 0;
4064a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mFailFast = false;
4065a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.notifyRegistrants();
4066a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4067a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4068a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void registerForAllDataDisconnected(Handler h, int what, Object obj) {
4069a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.addUnique(h, what, obj);
4070a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4071a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (isDisconnected()) {
4072a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("notify All Data Disconnected");
4073a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
4074a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4075a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4076a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4077a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void unregisterForAllDataDisconnected(Handler h) {
4078a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.remove(h);
4079a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4080a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4081a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    public void registerForDataEnabledChanged(Handler h, int what, Object obj) {
4082a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        mDataEnabledSettings.registerForDataEnabledChanged(h, what, obj);
4083a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    }
4084a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
4085a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    public void unregisterForDataEnabledChanged(Handler h) {
4086a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        mDataEnabledSettings.unregisterForDataEnabledChanged(h);
4087a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    }
4088a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
40891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetInternalDataEnabled(boolean enabled, Message onCompleteMsg) {
4090a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        synchronized (mDataEnabledSettings) {
4091a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            if (DBG) log("onSetInternalDataEnabled: enabled=" + enabled);
4092a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            boolean sendOnComplete = true;
4093a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4094a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            mDataEnabledSettings.setInternalDataEnabled(enabled);
4095a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (enabled) {
4096a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("onSetInternalDataEnabled: changed to enabled, try to setup data call");
4097a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                onTrySetupData(Phone.REASON_DATA_ENABLED);
4098a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
4099a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                sendOnComplete = false;
4100a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("onSetInternalDataEnabled: changed to disabled, cleanUpAllConnections");
41014fdc57b9bf223c908474c4545cc6f63456117a3bSanket Padawe                cleanUpAllConnections(Phone.REASON_DATA_DISABLED, onCompleteMsg);
4102a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
4103a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4104a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            if (sendOnComplete) {
4105a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                if (onCompleteMsg != null) {
4106a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                    onCompleteMsg.sendToTarget();
4107a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                }
4108a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
4109a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4110a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4111a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4112a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean setInternalDataEnabled(boolean enable) {
4113a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return setInternalDataEnabled(enable, null);
4114a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4115a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4116a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean setInternalDataEnabled(boolean enable, Message onCompleteMsg) {
41176bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        if (DBG) log("setInternalDataEnabled(" + enable + ")");
4118a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4119a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Message msg = obtainMessage(DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE, onCompleteMsg);
4120a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        msg.arg1 = (enable ? DctConstants.ENABLED : DctConstants.DISABLED);
4121a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sendMessage(msg);
4122a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return true;
4123a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4124a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
41251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void log(String s) {
4126a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Rlog.d(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s);
4127cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
4128cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
41291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void loge(String s) {
4130a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Rlog.e(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s);
4131cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
4132cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4133c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
41341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println("DcTracker:");
41351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" RADIO_TESTS=" + RADIO_TESTS);
413699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        pw.println(" mDataEnabledSettings=" + mDataEnabledSettings);
413799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        pw.println(" isDataAllowed=" + isDataAllowed(null));
41381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
41391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mRequestedApnType=" + mRequestedApnType);
41401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mPhone=" + mPhone.getPhoneName());
41411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mActivity=" + mActivity);
41421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mState=" + mState);
41431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mTxPkts=" + mTxPkts);
41441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mRxPkts=" + mRxPkts);
41451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mNetStatPollPeriod=" + mNetStatPollPeriod);
41461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mNetStatPollEnabled=" + mNetStatPollEnabled);
41471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mDataStallTxRxSum=" + mDataStallTxRxSum);
41481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mDataStallAlarmTag=" + mDataStallAlarmTag);
4149a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        pw.println(" mDataStallDetectionEnabled=" + mDataStallDetectionEnabled);
41501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mSentSinceLastRecv=" + mSentSinceLastRecv);
41511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mNoRecvPollCount=" + mNoRecvPollCount);
41521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mResolver=" + mResolver);
41531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsWifiConnected=" + mIsWifiConnected);
41541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mReconnectIntent=" + mReconnectIntent);
41551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mAutoAttachOnCreation=" + mAutoAttachOnCreation.get());
41561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsScreenOn=" + mIsScreenOn);
41571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mUniqueIdGenerator=" + mUniqueIdGenerator);
4158d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen        pw.println(" mDataRoamingLeakageLog= ");
4159d5e1c529220ab72046a867825cbab09b37070bceMalcolm Chen        mDataRoamingLeakageLog.dump(fd, pw, args);
41601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
41611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
41621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        DcController dcc = mDcc;
41631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (dcc != null) {
41641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            dcc.dump(fd, pw, args);
41651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
41661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mDcc=null");
41671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
41681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
41691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        HashMap<Integer, DataConnection> dcs = mDataConnections;
41701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (dcs != null) {
41711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Set<Entry<Integer, DataConnection> > mDcSet = mDataConnections.entrySet();
41721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mDataConnections: count=" + mDcSet.size());
41731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (Entry<Integer, DataConnection> entry : mDcSet) {
41741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                pw.printf(" *** mDataConnection[%d] \n", entry.getKey());
41751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                entry.getValue().dump(fd, pw, args);
41761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
41771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
41781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println("mDataConnections=null");
41791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
41801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
41811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
41821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        HashMap<String, Integer> apnToDcId = mApnToDataConnectionId;
41831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (apnToDcId != null) {
41841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Set<Entry<String, Integer>> apnToDcIdSet = apnToDcId.entrySet();
41851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mApnToDataConnectonId size=" + apnToDcIdSet.size());
41861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (Entry<String, Integer> entry : apnToDcIdSet) {
41871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                pw.printf(" mApnToDataConnectonId[%s]=%d\n", entry.getKey(), entry.getValue());
41881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
41891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
41901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println("mApnToDataConnectionId=null");
41911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
41921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
41931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
41941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ConcurrentHashMap<String, ApnContext> apnCtxs = mApnContexts;
41951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (apnCtxs != null) {
41961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Set<Entry<String, ApnContext>> apnCtxsSet = apnCtxs.entrySet();
41971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mApnContexts size=" + apnCtxsSet.size());
41981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (Entry<String, ApnContext> entry : apnCtxsSet) {
41991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                entry.getValue().dump(fd, pw, args);
42001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
42011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" ***************************************");
42021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
42031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mApnContexts=null");
42041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
42051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
42061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ArrayList<ApnSetting> apnSettings = mAllApnSettings;
42071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (apnSettings != null) {
42081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mAllApnSettings size=" + apnSettings.size());
42091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (int i=0; i < apnSettings.size(); i++) {
42101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                pw.printf(" mAllApnSettings[%d]: %s\n", i, apnSettings.get(i));
42111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
42121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.flush();
42131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
42141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mAllApnSettings=null");
42151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
42161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mPreferredApn=" + mPreferredApn);
42171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsPsRestricted=" + mIsPsRestricted);
42181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsDisposed=" + mIsDisposed);
42191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIntentReceiver=" + mIntentReceiver);
4220cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mReregisterOnReconnectFailure=" + mReregisterOnReconnectFailure);
422122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" canSetPreferApn=" + mCanSetPreferApn);
4222cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mApnObserver=" + mApnObserver);
4223cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" getOverallState=" + getOverallState());
4224ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        pw.println(" mDataConnectionAsyncChannels=%s\n" + mDataConnectionAcHashMap);
4225187a39f896f88eb6c5e4306d9595546654825976Wink Saville        pw.println(" mAttached=" + mAttached.get());
4226985c1bee3c77000298a0ba01f1b69f46a564e3d3Malcolm Chen        mDataEnabledSettings.dump(fd, pw, args);
42271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
4228c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
4229a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4230bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram    public String[] getPcscfAddress(String apnType) {
4231a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("getPcscfAddress()");
4232bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        ApnContext apnContext = null;
4233bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram
4234bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        if(apnType == null){
4235bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            log("apnType is null, return null");
4236bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            return null;
4237bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        }
4238a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4239bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_EMERGENCY)) {
4240af5593594070f825032be46dced573cd195956e1Robert Greenwalt            apnContext = mApnContextsById.get(DctConstants.APN_EMERGENCY_ID);
4241bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IMS)) {
4242af5593594070f825032be46dced573cd195956e1Robert Greenwalt            apnContext = mApnContextsById.get(DctConstants.APN_IMS_ID);
4243bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        } else {
4244bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            log("apnType is invalid, return null");
4245bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            return null;
4246bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        }
4247a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4248a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (apnContext == null) {
4249a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("apnContext is null, return null");
4250a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return null;
4251a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4252a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4253a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        DcAsyncChannel dcac = apnContext.getDcAc();
4254a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        String[] result = null;
4255a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4256a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (dcac != null) {
4257a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            result = dcac.getPcscfAddr();
4258a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4259c0a3ed8c70021d47cd55bbc1406a9cf63bd6afe2Jack Yu            if (result != null) {
4260c0a3ed8c70021d47cd55bbc1406a9cf63bd6afe2Jack Yu                for (int i = 0; i < result.length; i++) {
4261c0a3ed8c70021d47cd55bbc1406a9cf63bd6afe2Jack Yu                    log("Pcscf[" + i + "]: " + result[i]);
4262c0a3ed8c70021d47cd55bbc1406a9cf63bd6afe2Jack Yu                }
4263a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
4264a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return result;
4265a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4266a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return null;
4267a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4268a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
426976f43316a5a6082d601bffd4b6898d0bd81e11fcram    /**
427076f43316a5a6082d601bffd4b6898d0bd81e11fcram     * Read APN configuration from Telephony.db for Emergency APN
427176f43316a5a6082d601bffd4b6898d0bd81e11fcram     * All opertors recognize the connection request for EPDN based on APN type
427276f43316a5a6082d601bffd4b6898d0bd81e11fcram     * PLMN name,APN name are not mandatory parameters
427376f43316a5a6082d601bffd4b6898d0bd81e11fcram     */
427476f43316a5a6082d601bffd4b6898d0bd81e11fcram    private void initEmergencyApnSetting() {
427576f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Operator Numeric is not available when sim records are not loaded.
427676f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Query Telephony.db with APN type as EPDN request does not
427776f43316a5a6082d601bffd4b6898d0bd81e11fcram        // require APN name, plmn and all operators support same APN config.
427876f43316a5a6082d601bffd4b6898d0bd81e11fcram        // DB will contain only one entry for Emergency APN
427976f43316a5a6082d601bffd4b6898d0bd81e11fcram        String selection = "type=\"emergency\"";
428076f43316a5a6082d601bffd4b6898d0bd81e11fcram        Cursor cursor = mPhone.getContext().getContentResolver().query(
428176f43316a5a6082d601bffd4b6898d0bd81e11fcram                Telephony.Carriers.CONTENT_URI, null, selection, null, null);
428276f43316a5a6082d601bffd4b6898d0bd81e11fcram
428376f43316a5a6082d601bffd4b6898d0bd81e11fcram        if (cursor != null) {
428476f43316a5a6082d601bffd4b6898d0bd81e11fcram            if (cursor.getCount() > 0) {
428576f43316a5a6082d601bffd4b6898d0bd81e11fcram                if (cursor.moveToFirst()) {
428676f43316a5a6082d601bffd4b6898d0bd81e11fcram                    mEmergencyApn = makeApnSetting(cursor);
428776f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
428876f43316a5a6082d601bffd4b6898d0bd81e11fcram            }
428976f43316a5a6082d601bffd4b6898d0bd81e11fcram            cursor.close();
429076f43316a5a6082d601bffd4b6898d0bd81e11fcram        }
429176f43316a5a6082d601bffd4b6898d0bd81e11fcram    }
429276f43316a5a6082d601bffd4b6898d0bd81e11fcram
429376f43316a5a6082d601bffd4b6898d0bd81e11fcram    /**
429476f43316a5a6082d601bffd4b6898d0bd81e11fcram     * Add the Emergency APN settings to APN settings list
429576f43316a5a6082d601bffd4b6898d0bd81e11fcram     */
429676f43316a5a6082d601bffd4b6898d0bd81e11fcram    private void addEmergencyApnSetting() {
429776f43316a5a6082d601bffd4b6898d0bd81e11fcram        if(mEmergencyApn != null) {
429876f43316a5a6082d601bffd4b6898d0bd81e11fcram            if(mAllApnSettings == null) {
429976f43316a5a6082d601bffd4b6898d0bd81e11fcram                mAllApnSettings = new ArrayList<ApnSetting>();
430076f43316a5a6082d601bffd4b6898d0bd81e11fcram            } else {
430176f43316a5a6082d601bffd4b6898d0bd81e11fcram                boolean hasEmergencyApn = false;
430276f43316a5a6082d601bffd4b6898d0bd81e11fcram                for (ApnSetting apn : mAllApnSettings) {
430376f43316a5a6082d601bffd4b6898d0bd81e11fcram                    if (ArrayUtils.contains(apn.types, PhoneConstants.APN_TYPE_EMERGENCY)) {
430476f43316a5a6082d601bffd4b6898d0bd81e11fcram                        hasEmergencyApn = true;
430576f43316a5a6082d601bffd4b6898d0bd81e11fcram                        break;
430676f43316a5a6082d601bffd4b6898d0bd81e11fcram                    }
430776f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
430876f43316a5a6082d601bffd4b6898d0bd81e11fcram
430976f43316a5a6082d601bffd4b6898d0bd81e11fcram                if(hasEmergencyApn == false) {
431076f43316a5a6082d601bffd4b6898d0bd81e11fcram                    mAllApnSettings.add(mEmergencyApn);
431176f43316a5a6082d601bffd4b6898d0bd81e11fcram                } else {
431276f43316a5a6082d601bffd4b6898d0bd81e11fcram                    log("addEmergencyApnSetting - E-APN setting is already present");
431376f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
431476f43316a5a6082d601bffd4b6898d0bd81e11fcram            }
431576f43316a5a6082d601bffd4b6898d0bd81e11fcram        }
431676f43316a5a6082d601bffd4b6898d0bd81e11fcram    }
43179a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
43189fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu    private boolean containsAllApns(ArrayList<ApnSetting> oldApnList,
43199fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                                    ArrayList<ApnSetting> newApnList) {
43209fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu        for (ApnSetting newApnSetting : newApnList) {
43219fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            boolean canHandle = false;
43229fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            for (ApnSetting oldApnSetting : oldApnList) {
43239fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                // Make sure at least one of the APN from old list can cover the new APN
43249fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                if (oldApnSetting.equals(newApnSetting,
43259fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                        mPhone.getServiceState().getDataRoamingFromRegistration())) {
43269fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                    canHandle = true;
43279fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                    break;
43289fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                }
43299fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            }
43309fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            if (!canHandle) return false;
43319fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu        }
43329fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu        return true;
43339fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu    }
43349fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu
4335ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu    private void cleanUpConnectionsOnUpdatedApns(boolean tearDown, String reason) {
43369a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (DBG) log("cleanUpConnectionsOnUpdatedApns: tearDown=" + tearDown);
4337ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu        if (mAllApnSettings != null && mAllApnSettings.isEmpty()) {
43389a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            cleanUpAllConnections(tearDown, Phone.REASON_APN_CHANGED);
43399a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        } else {
4340e996a89f15d07d8c9fae23e9b03d47fff17087d8fionaxu            int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
4341e996a89f15d07d8c9fae23e9b03d47fff17087d8fionaxu            if (radioTech == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
4342e996a89f15d07d8c9fae23e9b03d47fff17087d8fionaxu                // unknown rat is an exception for data rat change. Its only received when out of
4343e996a89f15d07d8c9fae23e9b03d47fff17087d8fionaxu                // service and is not applicable for apn bearer bitmask. We should bypass the check
4344e996a89f15d07d8c9fae23e9b03d47fff17087d8fionaxu                // of waiting apn list and keep the data connection on.
4345e996a89f15d07d8c9fae23e9b03d47fff17087d8fionaxu                return;
4346e996a89f15d07d8c9fae23e9b03d47fff17087d8fionaxu            }
43479a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            for (ApnContext apnContext : mApnContexts.values()) {
43489a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                ArrayList<ApnSetting> currentWaitingApns = apnContext.getWaitingApns();
4349ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                ArrayList<ApnSetting> waitingApns = buildWaitingApns(
4350b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                        apnContext.getApnType(),
4351b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                        mPhone.getServiceState().getRilDataRadioTechnology());
4352ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                if (VDBG) log("new waitingApns:" + waitingApns);
4353ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                if ((currentWaitingApns != null)
4354ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                        && ((waitingApns.size() != currentWaitingApns.size())
43559fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                        // Check if the existing waiting APN list can cover the newly built APN
43569fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                        // list. If yes, then we don't need to tear down the existing data call.
43579fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                        // TODO: We probably need to rebuild APN list when roaming status changes.
43589fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                        || !containsAllApns(currentWaitingApns, waitingApns))) {
4359ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                    if (VDBG) log("new waiting apn is different for " + apnContext);
4360ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                    apnContext.setWaitingApns(waitingApns);
4361ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                    if (!apnContext.isDisconnected()) {
4362ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                        if (VDBG) log("cleanUpConnectionsOnUpdatedApns for " + apnContext);
4363ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                        apnContext.setReason(reason);
4364ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                        cleanUpConnection(true, apnContext);
43659a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    }
43669a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                }
43679a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            }
43689a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        }
43699a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
43709a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (!isConnected()) {
43719a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            stopNetStatPoll();
43729a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            stopDataStallAlarm();
43739a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        }
43749a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
43759a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
43769a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
43779a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (DBG) log("mDisconnectPendingCount = " + mDisconnectPendingCount);
43789a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (tearDown && mDisconnectPendingCount == 0) {
43799a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            notifyDataDisconnectComplete();
43809a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            notifyAllDataDisconnected();
43819a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        }
43829a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang    }
43831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
43841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
43851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Polling stuff
43861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
43871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void resetPollStats() {
43881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mTxPkts = -1;
43891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mRxPkts = -1;
43901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mNetStatPollPeriod = POLL_NETSTAT_MILLIS;
43911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
43921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
43931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void startNetStatPoll() {
43941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (getOverallState() == DctConstants.State.CONNECTED
43951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                && mNetStatPollEnabled == false) {
43961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
43971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("startNetStatPoll");
43981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
43991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            resetPollStats();
44001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mNetStatPollEnabled = true;
44011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPollNetStat.run();
44021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mPhone != null) {
44041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPhone.notifyDataActivity();
44051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void stopNetStatPoll() {
44091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mNetStatPollEnabled = false;
44101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        removeCallbacks(mPollNetStat);
44111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
44121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("stopNetStatPoll");
44131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // To sync data activity icon in the case of switching data connection to send MMS.
44161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mPhone != null) {
44171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPhone.notifyDataActivity();
44181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void sendStartNetStatPoll(DctConstants.Activity activity) {
44221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.CMD_NET_STAT_POLL);
44231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = DctConstants.ENABLED;
44241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.obj = activity;
44251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
44261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void handleStartNetStatPoll(DctConstants.Activity activity) {
44291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startNetStatPoll();
44301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
44311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        setActivity(activity);
44321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void sendStopNetStatPoll(DctConstants.Activity activity) {
44351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.CMD_NET_STAT_POLL);
44361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = DctConstants.DISABLED;
44371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.obj = activity;
44381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
44391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void handleStopNetStatPoll(DctConstants.Activity activity) {
44421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        stopNetStatPoll();
44431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        stopDataStallAlarm();
44441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        setActivity(activity);
44451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void updateDataActivity() {
44481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        long sent, received;
44491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        DctConstants.Activity newActivity;
44511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        TxRxSum preTxRxSum = new TxRxSum(mTxPkts, mRxPkts);
44531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        TxRxSum curTxRxSum = new TxRxSum();
44541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        curTxRxSum.updateTxRxSum();
44551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mTxPkts = curTxRxSum.txPkts;
44561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mRxPkts = curTxRxSum.rxPkts;
44571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) {
44591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("updateDataActivity: curTxRxSum=" + curTxRxSum + " preTxRxSum=" + preTxRxSum);
44601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mNetStatPollEnabled && (preTxRxSum.txPkts > 0 || preTxRxSum.rxPkts > 0)) {
44631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            sent = mTxPkts - preTxRxSum.txPkts;
44641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            received = mRxPkts - preTxRxSum.rxPkts;
44651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG)
44671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("updateDataActivity: sent=" + sent + " received=" + received);
44681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (sent > 0 && received > 0) {
44691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = DctConstants.Activity.DATAINANDOUT;
44701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (sent > 0 && received == 0) {
44711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = DctConstants.Activity.DATAOUT;
44721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (sent == 0 && received > 0) {
44731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = DctConstants.Activity.DATAIN;
44741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
44751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = (mActivity == DctConstants.Activity.DORMANT) ?
44761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mActivity : DctConstants.Activity.NONE;
44771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
44781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mActivity != newActivity && mIsScreenOn) {
44801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (VDBG)
44811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("updateDataActivity: newActivity=" + newActivity);
44821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mActivity = newActivity;
44831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mPhone.notifyDataActivity();
44841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
44851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44882e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt    private void handlePcoData(AsyncResult ar) {
44892e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        if (ar.exception != null) {
44902e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            Rlog.e(LOG_TAG, "PCO_DATA exception: " + ar.exception);
44912e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            return;
44922e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        }
44932e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        PcoData pcoData = (PcoData)(ar.result);
4494cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        ArrayList<DataConnection> dcList = new ArrayList<>();
4495cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        DataConnection temp = mDcc.getActiveDcByCid(pcoData.cid);
4496cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        if (temp != null) {
4497cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            dcList.add(temp);
4498cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        }
4499cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        if (dcList.size() == 0) {
4500cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            Rlog.e(LOG_TAG, "PCO_DATA for unknown cid: " + pcoData.cid + ", inferring");
4501cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            for (DataConnection dc : mDataConnections.values()) {
4502cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                final int cid = dc.getCid();
4503cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                if (cid == pcoData.cid) {
4504cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    if (VDBG) Rlog.d(LOG_TAG, "  found " + dc);
4505cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    dcList.clear();
4506cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    dcList.add(dc);
4507cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    break;
4508cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                }
4509cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                // check if this dc is still connecting
4510cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                if (cid == -1) {
4511cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    for (ApnContext apnContext : dc.mApnContexts.keySet()) {
4512cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        if (apnContext.getState() == DctConstants.State.CONNECTING) {
4513cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                            if (VDBG) Rlog.d(LOG_TAG, "  found potential " + dc);
4514cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                            dcList.add(dc);
4515cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                            break;
4516cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        }
4517cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    }
4518cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                }
4519cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            }
4520cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        }
4521cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        if (dcList.size() == 0) {
4522cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            Rlog.e(LOG_TAG, "PCO_DATA - couldn't infer cid");
45232e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            return;
45242e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        }
4525cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        for (DataConnection dc : dcList) {
4526cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            if (dc.mApnContexts.size() == 0) {
4527cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                break;
4528cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            }
4529cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            // send one out for each apn type in play
4530cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            for (ApnContext apnContext : dc.mApnContexts.keySet()) {
4531cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                String apnType = apnContext.getApnType();
4532cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt
4533cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                final Intent intent = new Intent(TelephonyIntents.ACTION_CARRIER_SIGNAL_PCO_VALUE);
4534cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                intent.putExtra(TelephonyIntents.EXTRA_APN_TYPE_KEY, apnType);
4535cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                intent.putExtra(TelephonyIntents.EXTRA_APN_PROTO_KEY, pcoData.bearerProto);
4536cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                intent.putExtra(TelephonyIntents.EXTRA_PCO_ID_KEY, pcoData.pcoId);
4537cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                intent.putExtra(TelephonyIntents.EXTRA_PCO_VALUE_KEY, pcoData.contents);
4538cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
4539cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            }
45402e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        }
45412e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt    }
45422e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt
45431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
45441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Data-Stall
45451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
45461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Recovery action taken in case of data stall
45471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static class RecoveryAction {
45481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int GET_DATA_CALL_LIST      = 0;
45491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int CLEANUP                 = 1;
45501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int REREGISTER              = 2;
45511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int RADIO_RESTART           = 3;
45521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        private static boolean isAggressiveRecovery(int value) {
45541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return ((value == RecoveryAction.CLEANUP) ||
45551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    (value == RecoveryAction.REREGISTER) ||
4556fc7e59579742d8888abd288ac5c36f2da17c29dbNathan Harold                    (value == RecoveryAction.RADIO_RESTART));
45571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
45581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int getRecoveryAction() {
45611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int action = Settings.System.getInt(mResolver,
45621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                "radio.data.stall.recovery.action", RecoveryAction.GET_DATA_CALL_LIST);
45631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("getRecoveryAction: " + action);
45641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return action;
45651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void putRecoveryAction(int action) {
45681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Settings.System.putInt(mResolver, "radio.data.stall.recovery.action", action);
45691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("putRecoveryAction: " + action);
45701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void doRecovery() {
45731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (getOverallState() == DctConstants.State.CONNECTED) {
45741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Go through a series of recovery steps, each action transitions to the next action
45750a39f581e11eb7b040a5412229164ef72044279fRobert Greenwalt            final int recoveryAction = getRecoveryAction();
4576f2d0fa64860a12423fb8709766d6af90fba5e6cfJack Yu            TelephonyMetrics.getInstance().writeDataStallEvent(mPhone.getPhoneId(), recoveryAction);
45771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            switch (recoveryAction) {
45781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case RecoveryAction.GET_DATA_CALL_LIST:
45791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_GET_DATA_CALL_LIST,
45801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mSentSinceLastRecv);
45811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("doRecovery() get data call list");
45821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mPhone.mCi.getDataCallList(obtainMessage(DctConstants.EVENT_DATA_STATE_CHANGED));
45831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                putRecoveryAction(RecoveryAction.CLEANUP);
45841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
45851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case RecoveryAction.CLEANUP:
45861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_CLEANUP, mSentSinceLastRecv);
45871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("doRecovery() cleanup all connections");
45881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                cleanUpAllConnections(Phone.REASON_PDP_RESET);
45891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                putRecoveryAction(RecoveryAction.REREGISTER);
45901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
45911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case RecoveryAction.REREGISTER:
45921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_REREGISTER,
45931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mSentSinceLastRecv);
45941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("doRecovery() re-register");
45951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mPhone.getServiceStateTracker().reRegisterNetwork(null);
45961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                putRecoveryAction(RecoveryAction.RADIO_RESTART);
45971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
45981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case RecoveryAction.RADIO_RESTART:
45991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART,
46001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mSentSinceLastRecv);
46011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("restarting radio");
46021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartRadio();
46031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
46041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
46051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            default:
46061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                throw new RuntimeException("doRecovery: Invalid recoveryAction=" +
46071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    recoveryAction);
46081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSentSinceLastRecv = 0;
46101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
46121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void updateDataStallInfo() {
46141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        long sent, received;
46151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        TxRxSum preTxRxSum = new TxRxSum(mDataStallTxRxSum);
46171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDataStallTxRxSum.updateTxRxSum();
46181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) {
46201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("updateDataStallInfo: mDataStallTxRxSum=" + mDataStallTxRxSum +
46211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " preTxRxSum=" + preTxRxSum);
46221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sent = mDataStallTxRxSum.txPkts - preTxRxSum.txPkts;
46251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        received = mDataStallTxRxSum.rxPkts - preTxRxSum.rxPkts;
46261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (RADIO_TESTS) {
46281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (SystemProperties.getBoolean("radio.test.data.stall", false)) {
46291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("updateDataStallInfo: radio.test.data.stall true received = 0;");
46301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                received = 0;
46311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if ( sent > 0 && received > 0 ) {
46341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) log("updateDataStallInfo: IN/OUT");
46351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSentSinceLastRecv = 0;
46361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
46371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (sent > 0 && received == 0) {
46386a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta            if (isPhoneStateIdle()) {
46391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mSentSinceLastRecv += sent;
46401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
46411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mSentSinceLastRecv = 0;
46421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
46441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("updateDataStallInfo: OUT sent=" + sent +
46451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        " mSentSinceLastRecv=" + mSentSinceLastRecv);
46461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (sent == 0 && received > 0) {
46481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) log("updateDataStallInfo: IN");
46491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSentSinceLastRecv = 0;
46501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
46511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
46521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) log("updateDataStallInfo: NONE");
46531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
46551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46566a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta    private boolean isPhoneStateIdle() {
46576a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta        for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
46586a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta            Phone phone = PhoneFactory.getPhone(i);
46596a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta            if (phone != null && phone.getState() != PhoneConstants.State.IDLE) {
46606a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta                log("isPhoneStateIdle false: Voice call active on phone " + i);
46616a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta                return false;
46626a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta            }
46636a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta        }
46646a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta        return true;
46656a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta    }
46666a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta
46671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataStallAlarm(int tag) {
46681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mDataStallAlarmTag != tag) {
46691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
46701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("onDataStallAlarm: ignore, tag=" + tag + " expecting " + mDataStallAlarmTag);
46711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return;
46731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        updateDataStallInfo();
46751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int hangWatchdogTrigger = Settings.Global.getInt(mResolver,
46771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Settings.Global.PDP_WATCHDOG_TRIGGER_PACKET_COUNT,
46781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                NUMBER_SENT_PACKETS_OF_HANG);
46791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        boolean suspectedStall = DATA_STALL_NOT_SUSPECTED;
46811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mSentSinceLastRecv >= hangWatchdogTrigger) {
46821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
46831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("onDataStallAlarm: tag=" + tag + " do recovery action=" + getRecoveryAction());
46841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            suspectedStall = DATA_STALL_SUSPECTED;
46861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            sendMessage(obtainMessage(DctConstants.EVENT_DO_RECOVERY));
46871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
46881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) {
46891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("onDataStallAlarm: tag=" + tag + " Sent " + String.valueOf(mSentSinceLastRecv) +
46901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " pkts since last received, < watchdogTrigger=" + hangWatchdogTrigger);
46911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startDataStallAlarm(suspectedStall);
46941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
46951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void startDataStallAlarm(boolean suspectedStall) {
46971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int nextAction = getRecoveryAction();
46981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int delayInMs;
46991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mDataStallDetectionEnabled && getOverallState() == DctConstants.State.CONNECTED) {
47011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // If screen is on or data stall is currently suspected, set the alarm
47020e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // with an aggressive timeout.
47031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mIsScreenOn || suspectedStall || RecoveryAction.isAggressiveRecovery(nextAction)) {
47041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                delayInMs = Settings.Global.getInt(mResolver,
47051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS,
47061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
47071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
47081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                delayInMs = Settings.Global.getInt(mResolver,
47091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS,
47101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
47111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mDataStallAlarmTag += 1;
47141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) {
47151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("startDataStallAlarm: tag=" + mDataStallAlarmTag +
47161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        " delay=" + (delayInMs / 1000) + "s");
47171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Intent intent = new Intent(INTENT_DATA_STALL_ALARM);
47191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            intent.putExtra(DATA_STALL_ALARM_TAG_EXTRA, mDataStallAlarmTag);
47201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mDataStallAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
47211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    PendingIntent.FLAG_UPDATE_CURRENT);
4722128f3f36854fe183a6dd4d9917906b4723dd234fAjay Dudani            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME,
47231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    SystemClock.elapsedRealtime() + delayInMs, mDataStallAlarmIntent);
47241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
47251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) {
47261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("startDataStallAlarm: NOT started, no connection tag=" + mDataStallAlarmTag);
47271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void stopDataStallAlarm() {
47321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) {
47331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("stopDataStallAlarm: current tag=" + mDataStallAlarmTag +
47341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " mDataStallAlarmIntent=" + mDataStallAlarmIntent);
47351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDataStallAlarmTag += 1;
47371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mDataStallAlarmIntent != null) {
47381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mAlarmManager.cancel(mDataStallAlarmIntent);
47391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mDataStallAlarmIntent = null;
47401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void restartDataStallAlarm() {
47441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (isConnected() == false) return;
47451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // To be called on screen status change.
47461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // Do not cancel the alarm if it is set with aggressive timeout.
47471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int nextAction = getRecoveryAction();
47481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (RecoveryAction.isAggressiveRecovery(nextAction)) {
47501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("restartDataStallAlarm: action is pending. not resetting the alarm.");
47511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return;
47521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("restartDataStallAlarm: stop then start.");
47541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        stopDataStallAlarm();
47551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
47561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
47591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Provisioning APN
47601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
47611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onActionIntentProvisioningApnAlarm(Intent intent) {
47621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("onActionIntentProvisioningApnAlarm: action=" + intent.getAction());
47631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_PROVISIONING_APN_ALARM,
47641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                intent.getAction());
47651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = intent.getIntExtra(PROVISIONING_APN_ALARM_TAG_EXTRA, 0);
47661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
47671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void startProvisioningApnAlarm() {
47701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int delayInMs = Settings.Global.getInt(mResolver,
47711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                Settings.Global.PROVISIONING_APN_ALARM_DELAY_IN_MS,
47721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                PROVISIONING_APN_ALARM_DELAY_IN_MS_DEFAULT);
47731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (Build.IS_DEBUGGABLE) {
47741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Allow debug code to use a system property to provide another value
47751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            String delayInMsStrg = Integer.toString(delayInMs);
47761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            delayInMsStrg = System.getProperty(DEBUG_PROV_APN_ALARM, delayInMsStrg);
47771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            try {
47781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                delayInMs = Integer.parseInt(delayInMsStrg);
47791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } catch (NumberFormatException e) {
47801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                loge("startProvisioningApnAlarm: e=" + e);
47811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisioningApnAlarmTag += 1;
47841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
47851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("startProvisioningApnAlarm: tag=" + mProvisioningApnAlarmTag +
47861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " delay=" + (delayInMs / 1000) + "s");
47871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Intent intent = new Intent(INTENT_PROVISIONING_APN_ALARM);
47891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        intent.putExtra(PROVISIONING_APN_ALARM_TAG_EXTRA, mProvisioningApnAlarmTag);
47901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisioningApnAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
47911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                PendingIntent.FLAG_UPDATE_CURRENT);
47921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
47931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                SystemClock.elapsedRealtime() + delayInMs, mProvisioningApnAlarmIntent);
47941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void stopProvisioningApnAlarm() {
47971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
47981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("stopProvisioningApnAlarm: current tag=" + mProvisioningApnAlarmTag +
47991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " mProvsioningApnAlarmIntent=" + mProvisioningApnAlarmIntent);
48001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
48011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisioningApnAlarmTag += 1;
48021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mProvisioningApnAlarmIntent != null) {
48031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mAlarmManager.cancel(mProvisioningApnAlarmIntent);
48041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mProvisioningApnAlarmIntent = null;
48051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
48061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
48071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4808886183cde1263ea524cdf08524442724e246ed42Jack Yu    private static DataProfile createDataProfile(ApnSetting apn) {
4809886183cde1263ea524cdf08524442724e246ed42Jack Yu        return createDataProfile(apn, apn.profileId);
4810886183cde1263ea524cdf08524442724e246ed42Jack Yu    }
4811886183cde1263ea524cdf08524442724e246ed42Jack Yu
4812886183cde1263ea524cdf08524442724e246ed42Jack Yu    @VisibleForTesting
4813886183cde1263ea524cdf08524442724e246ed42Jack Yu    public static DataProfile createDataProfile(ApnSetting apn, int profileId) {
4814886183cde1263ea524cdf08524442724e246ed42Jack Yu        int profileType;
4815886183cde1263ea524cdf08524442724e246ed42Jack Yu        if (apn.bearerBitmask == 0) {
4816886183cde1263ea524cdf08524442724e246ed42Jack Yu            profileType = DataProfile.TYPE_COMMON;
4817886183cde1263ea524cdf08524442724e246ed42Jack Yu        } else if (ServiceState.bearerBitmapHasCdma(apn.bearerBitmask)) {
4818886183cde1263ea524cdf08524442724e246ed42Jack Yu            profileType = DataProfile.TYPE_3GPP2;
4819886183cde1263ea524cdf08524442724e246ed42Jack Yu        } else {
4820886183cde1263ea524cdf08524442724e246ed42Jack Yu            profileType = DataProfile.TYPE_3GPP;
4821886183cde1263ea524cdf08524442724e246ed42Jack Yu        }
4822886183cde1263ea524cdf08524442724e246ed42Jack Yu
4823886183cde1263ea524cdf08524442724e246ed42Jack Yu        return new DataProfile(profileId, apn.apn, apn.protocol,
4824886183cde1263ea524cdf08524442724e246ed42Jack Yu                apn.authType, apn.user, apn.password, profileType,
4825886183cde1263ea524cdf08524442724e246ed42Jack Yu                apn.maxConnsTime, apn.maxConns, apn.waitTime, apn.carrierEnabled, apn.typesBitmap,
4826886183cde1263ea524cdf08524442724e246ed42Jack Yu                apn.roamingProtocol, apn.bearerBitmask, apn.mtu, apn.mvnoType, apn.mvnoMatchData,
4827886183cde1263ea524cdf08524442724e246ed42Jack Yu                apn.modemCognitive);
4828886183cde1263ea524cdf08524442724e246ed42Jack Yu    }
4829c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville}
4830