DcTracker.java revision da21f0de2087657b20b18817b33d59778720bffb
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;
68cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.gsm.GsmCellLocation;
69c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.text.TextUtils;
70cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kallaimport android.util.EventLog;
712dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwaltimport android.util.LocalLog;
72ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwaltimport android.util.Pair;
73af5593594070f825032be46dced573cd195956e1Robert Greenwaltimport android.util.SparseArray;
742b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensenimport android.view.WindowManager;
75c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport com.android.internal.R;
77af5593594070f825032be46dced573cd195956e1Robert Greenwaltimport com.android.internal.annotations.VisibleForTesting;
786a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxuimport com.android.internal.telephony.CarrierActionAgent;
79cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.DctConstants;
80cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.EventLogTags;
814c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport com.android.internal.telephony.GsmCdmaPhone;
82b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensenimport com.android.internal.telephony.ITelephony;
834c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport com.android.internal.telephony.Phone;
844918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savilleimport com.android.internal.telephony.PhoneConstants;
856a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Guttaimport com.android.internal.telephony.PhoneFactory;
86cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.RILConstants;
87565b45663e85b82a8d7e653e181adfe858b71c82Jack Yuimport com.android.internal.telephony.SettingsObserver;
88a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxuimport com.android.internal.telephony.TelephonyIntents;
8999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yuimport com.android.internal.telephony.dataconnection.DataConnectionReasons.DataAllowedReasonType;
9099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yuimport com.android.internal.telephony.dataconnection.DataConnectionReasons.DataDisallowedReasonType;
91f2d0fa64860a12423fb8709766d6af90fba5e6cfJack Yuimport com.android.internal.telephony.metrics.TelephonyMetrics;
92d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccRecords;
93bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenkaimport com.android.internal.telephony.uicc.UiccController;
9476f43316a5a6082d601bffd4b6898d0bd81e11fcramimport com.android.internal.util.ArrayUtils;
954c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport com.android.internal.util.AsyncChannel;
96c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
97c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.io.FileDescriptor;
98c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.io.PrintWriter;
99c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.ArrayList;
10029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwaltimport java.util.Arrays;
1011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.Comparator;
1021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.HashMap;
1031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.Map.Entry;
1041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.PriorityQueue;
1051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.Set;
1061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.concurrent.ConcurrentHashMap;
1071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.concurrent.atomic.AtomicBoolean;
1081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.concurrent.atomic.AtomicInteger;
1091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.concurrent.atomic.AtomicReference;
110c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/**
111c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * {@hide}
112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
1130c3ec24396bb8c21b4d89f743b626c13dd35ba7bAmit Mahajanpublic class DcTracker extends Handler {
1141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String LOG_TAG = "DCT";
1151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean DBG = true;
1161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean VDBG = false; // STOPSHIP if true
1171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean VDBG_STALL = false; // STOPSHIP if true
1181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean RADIO_TESTS = false;
1191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1200e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    public AtomicBoolean isCleanupRequired = new AtomicBoolean(false);
1211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final AlarmManager mAlarmManager;
1231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Currently requested APN type (TODO: This should probably be a parameter not a member) */
1251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private String mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
1261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
127a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    // All data enabling/disabling related settings
128a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    private final DataEnabledSettings mDataEnabledSettings = new DataEnabledSettings();
129a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
1300a39f581e11eb7b040a5412229164ef72044279fRobert Greenwalt
1311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
1321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * After detecting a potential connection problem, this is the max number
1331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * of subsequent polls before attempting recovery.
1341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
1351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // 1 sec. default polling interval when screen is on.
1361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int POLL_NETSTAT_MILLIS = 1000;
1371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // 10 min. default polling interval when screen is off.
1381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int POLL_NETSTAT_SCREEN_OFF_MILLIS = 1000*60*10;
1391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Default sent packets without ack which triggers initial recovery steps
1401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int NUMBER_SENT_PACKETS_OF_HANG = 10;
1411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Default for the data stall alarm while non-aggressive stall detection
1431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60 * 6;
1441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Default for the data stall alarm for aggressive stall detection
1451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60;
1461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Tag for tracking stale alarms
1471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String DATA_STALL_ALARM_TAG_EXTRA = "data.stall.alram.tag";
1481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean DATA_STALL_SUSPECTED = true;
1501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean DATA_STALL_NOT_SUSPECTED = false;
1511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private String RADIO_RESET_PROPERTY = "gsm.radioreset";
1531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_RECONNECT_ALARM =
1551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "com.android.internal.telephony.data-reconnect";
1561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_RECONNECT_ALARM_EXTRA_TYPE = "reconnect_alarm_extra_type";
1571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_RECONNECT_ALARM_EXTRA_REASON =
1581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "reconnect_alarm_extra_reason";
1591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_DATA_STALL_ALARM =
1611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "com.android.internal.telephony.data-stall";
1621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DcTesterFailBringUpAll mDcTesterFailBringUpAll;
1641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DcController mDcc;
1651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** kept in sync with mApnContexts
1671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Higher numbers are higher priority and sorted so highest priority is first */
1681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final PriorityQueue<ApnContext>mPrioritySortedApnContexts =
1691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new PriorityQueue<ApnContext>(5,
1701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new Comparator<ApnContext>() {
1711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                public int compare(ApnContext c1, ApnContext c2) {
1721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    return c2.priority - c1.priority;
1731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
1741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } );
1751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** allApns holds all apns */
1771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ArrayList<ApnSetting> mAllApnSettings = null;
1781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** preferred apn */
1801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ApnSetting mPreferredApn = null;
1811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Is packet service restricted by network */
1831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsPsRestricted = false;
1841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** emergency apn Setting*/
1861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ApnSetting mEmergencyApn = null;
1871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Once disposed dont handle any messages */
1891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsDisposed = false;
1901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ContentResolver mResolver;
1921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Set to true with CMD_ENABLE_MOBILE_PROVISIONING */
1941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsProvisioning = false;
1951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* The Url passed as object parameter in CMD_ENABLE_MOBILE_PROVISIONING */
1971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private String mProvisioningUrl = null;
1981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Intent for the provisioning apn alarm */
2001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_PROVISIONING_APN_ALARM =
2011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "com.android.internal.telephony.provisioning_apn_alarm";
2021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Tag for tracking stale alarms */
2041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String PROVISIONING_APN_ALARM_TAG_EXTRA = "provisioning.apn.alarm.tag";
2051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Debug property for overriding the PROVISIONING_APN_ALARM_DELAY_IN_MS */
2071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String DEBUG_PROV_APN_ALARM = "persist.debug.prov_apn_alarm";
2081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Default for the provisioning apn alarm timeout */
2101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int PROVISIONING_APN_ALARM_DELAY_IN_MS_DEFAULT = 1000 * 60 * 15;
2111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* The provision apn alarm intent used to disable the provisioning apn */
2131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private PendingIntent mProvisioningApnAlarmIntent = null;
2141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Used to track stale provisioning apn alarms */
2161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mProvisioningApnAlarmTag = (int) SystemClock.elapsedRealtime();
2171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private AsyncChannel mReplyAc = new AsyncChannel();
2191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver () {
2211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
2221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void onReceive(Context context, Intent intent) {
2231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            String action = intent.getAction();
224c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu
2251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (action.equals(Intent.ACTION_SCREEN_ON)) {
226baecdb610b30a5d4b35345f8fc63fcbc2133c149Jack Yu                // TODO: Evaluate hooking this up with DeviceStateMonitor
227c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("screen on");
2281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mIsScreenOn = true;
2291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                stopNetStatPoll();
2301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                startNetStatPoll();
2311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartDataStallAlarm();
2321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
233c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("screen off");
2341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mIsScreenOn = false;
2351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                stopNetStatPoll();
2361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                startNetStatPoll();
2371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartDataStallAlarm();
2381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.startsWith(INTENT_RECONNECT_ALARM)) {
2391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("Reconnect alarm. Previous state was " + mState);
2401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onActionIntentReconnectAlarm(intent);
2411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(INTENT_DATA_STALL_ALARM)) {
242c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("Data stall alarm");
2431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onActionIntentDataStallAlarm(intent);
2441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(INTENT_PROVISIONING_APN_ALARM)) {
245c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("Provisioning apn alarm");
2461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onActionIntentProvisioningApnAlarm(intent);
2471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
2481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final android.net.NetworkInfo networkInfo = (NetworkInfo)
2491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
2501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mIsWifiConnected = (networkInfo != null && networkInfo.isConnected());
2511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("NETWORK_STATE_CHANGED_ACTION: mIsWifiConnected=" + mIsWifiConnected);
2521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
253c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("Wifi state changed");
2541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
2551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
2561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (!enabled) {
2571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // when WiFi got disabled, the NETWORK_STATE_CHANGED_ACTION
2581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // quit and won't report disconnected until next enabling.
2591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mIsWifiConnected = false;
2601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
2611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
2621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("WIFI_STATE_CHANGED_ACTION: enabled=" + enabled
2631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + " mIsWifiConnected=" + mIsWifiConnected);
2641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
26521e6af8d6197a071d025733fffeffc157d0085bcfionaxu            } else if (action.equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
26621e6af8d6197a071d025733fffeffc157d0085bcfionaxu                if (mIccRecords.get() != null && mIccRecords.get().getRecordsLoaded()) {
26721e6af8d6197a071d025733fffeffc157d0085bcfionaxu                    setDefaultDataRoamingEnabled();
26821e6af8d6197a071d025733fffeffc157d0085bcfionaxu                }
269c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            } else {
270c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("onReceive: Unknown action=" + action);
2711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
2721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
2731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    };
2741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final Runnable mPollNetStat = new Runnable() {
2761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
2771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void run() {
2781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            updateDataActivity();
2791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mIsScreenOn) {
2811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mNetStatPollPeriod = Settings.Global.getInt(mResolver,
2821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.PDP_WATCHDOG_POLL_INTERVAL_MS, POLL_NETSTAT_MILLIS);
2831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
2841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mNetStatPollPeriod = Settings.Global.getInt(mResolver,
2851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS,
2861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        POLL_NETSTAT_SCREEN_OFF_MILLIS);
2871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
2881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mNetStatPollEnabled) {
2901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mDataConnectionTracker.postDelayed(this, mNetStatPollPeriod);
2911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
2921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
2931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    };
2941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private SubscriptionManager mSubscriptionManager;
2961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final OnSubscriptionsChangedListener mOnSubscriptionsChangedListener =
2971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new OnSubscriptionsChangedListener() {
2981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                public final AtomicInteger mPreviousSubId =
2991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        new AtomicInteger(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
3001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                /**
3021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                 * Callback invoked when there is any change to any SubscriptionInfo. Typically
3031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                 * this method invokes {@link SubscriptionManager#getActiveSubscriptionInfoList}
3041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                 */
3051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                @Override
3061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                public void onSubscriptionsChanged() {
3071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (DBG) log("SubscriptionListener.onSubscriptionInfoChanged");
3081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // Set the network type, in case the radio does not restore it.
3091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    int subId = mPhone.getSubId();
3101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (SubscriptionManager.isValidSubscriptionId(subId)) {
311f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                        registerSettingsObserver();
3121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
3131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mPreviousSubId.getAndSet(subId) != subId &&
3141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            SubscriptionManager.isValidSubscriptionId(subId)) {
3151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onRecordsLoadedOrSubIdChanged();
3161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
3171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
3181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            };
3191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
320f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    private final SettingsObserver mSettingsObserver;
321f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
322f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    private void registerSettingsObserver() {
323f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.unobserve();
324f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        String simSuffix = "";
325f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu        if (TelephonyManager.getDefault().getSimCount() > 1) {
326f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            simSuffix = Integer.toString(mPhone.getSubId());
327f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        }
328f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu
329f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.observe(
330f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                Settings.Global.getUriFor(Settings.Global.DATA_ROAMING + simSuffix),
331f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                DctConstants.EVENT_ROAMING_ON);
332f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.observe(
333f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
334f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE);
335f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.observe(
336f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED),
337f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE);
338f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    }
3391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
3411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Maintain the sum of transmit and receive packets.
3421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     *
3431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * The packet counts are initialized and reset to -1 and
3441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * remain -1 until they can be updated.
3451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
3461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public static class TxRxSum {
3471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public long txPkts;
3481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public long rxPkts;
3491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public TxRxSum() {
3511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            reset();
3521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public TxRxSum(long txPkts, long rxPkts) {
3551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.txPkts = txPkts;
3561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.rxPkts = rxPkts;
3571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public TxRxSum(TxRxSum sum) {
3601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            txPkts = sum.txPkts;
3611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            rxPkts = sum.rxPkts;
3621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void reset() {
3651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            txPkts = -1;
3661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            rxPkts = -1;
3671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
3701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public String toString() {
3711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return "{txSum=" + txPkts + " rxSum=" + rxPkts + "}";
3721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void updateTxRxSum() {
3751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.txPkts = TrafficStats.getMobileTcpTxPackets();
3761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.rxPkts = TrafficStats.getMobileTcpRxPackets();
3771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
3791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onActionIntentReconnectAlarm(Intent intent) {
381e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        Message msg = obtainMessage(DctConstants.EVENT_DATA_RECONNECT);
382e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        msg.setData(intent.getExtras());
383e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        sendMessage(msg);
384e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu    }
385e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu
386e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu    private void onDataReconnect(Bundle bundle) {
387e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        String reason = bundle.getString(INTENT_RECONNECT_ALARM_EXTRA_REASON);
388e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        String apnType = bundle.getString(INTENT_RECONNECT_ALARM_EXTRA_TYPE);
3891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int phoneSubId = mPhone.getSubId();
391e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        int currSubId = bundle.getInt(PhoneConstants.SUBSCRIPTION_KEY,
3921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
393e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu        log("onDataReconnect: currSubId = " + currSubId + " phoneSubId=" + phoneSubId);
3941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // Stop reconnect if not current subId is not correct.
3961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // FIXME STOPSHIP - phoneSubId is coming up as -1 way after boot and failing this?
3971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (!SubscriptionManager.isValidSubscriptionId(currSubId) || (currSubId != phoneSubId)) {
3981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("receive ReconnectAlarm but subId incorrect, ignore");
3991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return;
4001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnContext apnContext = mApnContexts.get(apnType);
4031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
405e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu            log("onDataReconnect: mState=" + mState + " reason=" + reason + " apnType=" + apnType
406e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                    + " apnContext=" + apnContext + " mDataConnectionAsyncChannels="
407e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                    + mDataConnectionAcHashMap);
4081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if ((apnContext != null) && (apnContext.isEnabled())) {
4111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            apnContext.setReason(reason);
4121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            DctConstants.State apnContextState = apnContext.getState();
4131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
414e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                log("onDataReconnect: apnContext state=" + apnContextState);
4151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
4161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if ((apnContextState == DctConstants.State.FAILED)
4171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    || (apnContextState == DctConstants.State.IDLE)) {
4181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
419e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                    log("onDataReconnect: state is FAILED|IDLE, disassociate");
4201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
4211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DcAsyncChannel dcac = apnContext.getDcAc();
4221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (dcac != null) {
4231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (DBG) {
424e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                        log("onDataReconnect: tearDown apnContext=" + apnContext);
4251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
4261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    dcac.tearDown(apnContext, "", null);
4271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
4281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                apnContext.setDataConnectionAc(null);
4291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                apnContext.setState(DctConstants.State.IDLE);
4301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
431e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                if (DBG) log("onDataReconnect: keep associated");
4321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
4331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // TODO: IF already associated should we send the EVENT_TRY_SETUP_DATA???
4341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            sendMessage(obtainMessage(DctConstants.EVENT_TRY_SETUP_DATA, apnContext));
4351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            apnContext.setReconnectIntent(null);
4371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
4391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onActionIntentDataStallAlarm(Intent intent) {
4411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("onActionIntentDataStallAlarm: action=" + intent.getAction());
4421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_DATA_STALL_ALARM,
4431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                intent.getAction());
4441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = intent.getIntExtra(DATA_STALL_ALARM_TAG_EXTRA, 0);
4451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
4461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
4471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final ConnectivityManager mCm;
449c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
450b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla    /**
451a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * List of messages that are waiting to be posted, when data call disconnect
452a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * is complete
453a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
454a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ArrayList<Message> mDisconnectAllCompleteMsgList = new ArrayList<Message>();
455a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
456a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private RegistrantList mAllDataDisconnectedRegistrants = new RegistrantList();
457a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // member variables
4591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final Phone mPhone;
4601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final UiccController mUiccController;
4611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
4621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DctConstants.Activity mActivity = DctConstants.Activity.NONE;
4631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DctConstants.State mState = DctConstants.State.IDLE;
4641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final Handler mDataConnectionTracker;
4651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private long mTxPkts;
4671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private long mRxPkts;
4681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mNetStatPollPeriod;
4691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mNetStatPollEnabled = false;
4701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private TxRxSum mDataStallTxRxSum = new TxRxSum(0, 0);
4721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Used to track stale data stall alarms.
4731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mDataStallAlarmTag = (int) SystemClock.elapsedRealtime();
4741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // The current data stall alarm intent
4751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private PendingIntent mDataStallAlarmIntent = null;
4761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Number of packets sent since the last received packet
4771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private long mSentSinceLastRecv;
4781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Controls when a simple recovery attempt it to be tried
4791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mNoRecvPollCount = 0;
4800e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    // Reference counter for enabling fail fast
4811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static int sEnableFailFastRefCounter = 0;
4821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // True if data stall detection is enabled
4831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private volatile boolean mDataStallDetectionEnabled = true;
4841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private volatile boolean mFailFast = false;
4861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // True when in voice call
4881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mInVoiceCall = false;
4891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // wifi connection status will be updated by sticky intent
4911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsWifiConnected = false;
4921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Intent sent when the reconnect alarm fires. */
4941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private PendingIntent mReconnectIntent = null;
4951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // When false we will not auto attach and manually attaching is required.
4971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mAutoAttachOnCreationConfig = false;
4981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private AtomicBoolean mAutoAttachOnCreation = new AtomicBoolean(false);
4991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // State of screen
5011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // (TODO: Reconsider tying directly to screen, maybe this is
5021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    //        really a lower power mode")
5031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsScreenOn = true;
5041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Indicates if we found mvno-specific APNs in the full APN list.
5061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // used to determine if we can accept mno-specific APN for tethering.
5071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mMvnoMatched = false;
5081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Allows the generation of unique Id's for DataConnection objects */
5101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private AtomicInteger mUniqueIdGenerator = new AtomicInteger(0);
5111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** The data connections. */
5131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private HashMap<Integer, DataConnection> mDataConnections =
5141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new HashMap<Integer, DataConnection>();
5151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** The data connection async channels */
5171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private HashMap<Integer, DcAsyncChannel> mDataConnectionAcHashMap =
5181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new HashMap<Integer, DcAsyncChannel>();
5191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Convert an ApnType string to Id (TODO: Use "enumeration" instead of String for ApnType) */
5211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private HashMap<String, Integer> mApnToDataConnectionId = new HashMap<String, Integer>();
5221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Phone.APN_TYPE_* ===> ApnContext */
5241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final ConcurrentHashMap<String, ApnContext> mApnContexts =
5251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new ConcurrentHashMap<String, ApnContext>();
5261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
527af5593594070f825032be46dced573cd195956e1Robert Greenwalt    private final SparseArray<ApnContext> mApnContextsById = new SparseArray<ApnContext>();
528af5593594070f825032be46dced573cd195956e1Robert Greenwalt
5291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mDisconnectPendingCount = 0;
530a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
5314c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu    /** Indicate if metered APNs are disabled.
5324c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu     *  set to block all the metered APNs from continuously sending requests, which causes
5334c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu     *  undesired network load */
5344c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu    private boolean mMeteredApnDisabled = false;
53568f4f4a0bc8d4060b5775e7a24a97ea5b485989efionaxu
536a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
5374b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * int to remember whether has setDataProfiles and with roaming or not.
5384b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * 0: default, has never set data profile
5394b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * 1: has set data profile with home protocol
5404b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * 2: has set data profile with roaming protocol
5414b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * This is not needed once RIL command is updated to support both home and roaming protocol.
5424b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     */
5434b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu    private int mSetDataProfileStatus = 0;
5444b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu
5454b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu    /**
546cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Handles changes to the APN db.
547b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla     */
548cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private class ApnChangeObserver extends ContentObserver {
549cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public ApnChangeObserver () {
550cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            super(mDataConnectionTracker);
551cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
552c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
553cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
554cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public void onChange(boolean selfChange) {
555cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            sendMessage(obtainMessage(DctConstants.EVENT_APN_CHANGED));
556cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
557cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
558c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
559cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Instance Variables
560c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
561cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean mReregisterOnReconnectFailure = false;
562c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
563c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
564cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Constants
565c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
566ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    // Used by puppetmaster/*/radio_stress.py
567ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private static final String PUPPET_MASTER_RADIO_STRESS_TEST = "gsm.defaultpdpcontext.active";
568c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
569ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private static final int POLL_PDP_MILLIS = 5 * 1000;
570c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
5712b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen    private static final int PROVISIONING_SPINNER_TIMEOUT_MILLIS = 120 * 1000;
5722b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen
5736bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville    static final Uri PREFERAPN_NO_UPDATE_URI_USING_SUBID =
5746bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville                        Uri.parse("content://telephony/carriers/preferapn_no_update/subId/");
575cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final String APN_ID = "apn_id";
576cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
577ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private boolean mCanSetPreferApn = false;
578c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
579187a39f896f88eb6c5e4306d9595546654825976Wink Saville    private AtomicBoolean mAttached = new AtomicBoolean(false);
580187a39f896f88eb6c5e4306d9595546654825976Wink Saville
581cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** Watches for changes to the APN db. */
582cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ApnChangeObserver mApnObserver;
583cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
584b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private final String mProvisionActionName;
585b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private BroadcastReceiver mProvisionBroadcastReceiver;
5862b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen    private ProgressDialog mProvisioningSpinner;
587b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
588a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean mImsRegistrationState = false;
589a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
590cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Constructor
5911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public DcTracker(Phone phone) {
5921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        super();
5931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone = phone;
5941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("DCT.constructor");
5961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mResolver = mPhone.getContext().getContentResolver();
5981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mUiccController = UiccController.getInstance();
5991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mUiccController.registerForIccChanged(this, DctConstants.EVENT_ICC_CHANGED, null);
6001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mAlarmManager =
6011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
6021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mCm = (ConnectivityManager) mPhone.getContext().getSystemService(
6031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Context.CONNECTIVITY_SERVICE);
6041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        IntentFilter filter = new IntentFilter();
6071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(Intent.ACTION_SCREEN_ON);
6081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(Intent.ACTION_SCREEN_OFF);
6091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
6101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
6111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(INTENT_DATA_STALL_ALARM);
6121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(INTENT_PROVISIONING_APN_ALARM);
61321e6af8d6197a071d025733fffeffc157d0085bcfionaxu        filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
6141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // TODO - redundent with update call below?
615a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        mDataEnabledSettings.setUserDataEnabled(getDataEnabled());
6161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
6181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
6201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mAutoAttachOnCreation.set(sp.getBoolean(Phone.DATA_DISABLED_ON_BOOT_KEY, false));
6211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mSubscriptionManager = SubscriptionManager.from(mPhone.getContext());
6231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
6241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        HandlerThread dcHandlerThread = new HandlerThread("DcHandlerThread");
6261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        dcHandlerThread.start();
6271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Handler dcHandler = new Handler(dcHandlerThread.getLooper());
6281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcc = DcController.makeDcc(mPhone, this, dcHandler);
6291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcTesterFailBringUpAll = new DcTesterFailBringUpAll(mPhone, dcHandler);
630cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
631cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mDataConnectionTracker = this;
632c374098c17a81f73f51e9d7df99eba574882949bYifan Bai        registerForAllEvents();
633a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        update();
634cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mApnObserver = new ApnChangeObserver();
6351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        phone.getContext().getContentResolver().registerContentObserver(
636cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                Telephony.Carriers.CONTENT_URI, true, mApnObserver);
637cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
638d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        initApnContexts();
639d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
640d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        for (ApnContext apnContext : mApnContexts.values()) {
641d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            // Register the reconnect and restart actions.
6421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            filter = new IntentFilter();
643d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            filter.addAction(INTENT_RECONNECT_ALARM + '.' + apnContext.getApnType());
644d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
645d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        }
646d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
64776f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Add Emergency APN to APN setting list by default to support EPDN in sim absent cases
64876f43316a5a6082d601bffd4b6898d0bd81e11fcram        initEmergencyApnSetting();
64976f43316a5a6082d601bffd4b6898d0bd81e11fcram        addEmergencyApnSetting();
650b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
6511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisionActionName = "com.android.internal.telephony.PROVISION" + phone.getPhoneId();
652f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
653f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver = new SettingsObserver(mPhone.getContext(), this);
654f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        registerSettingsObserver();
6551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
6561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
657af5593594070f825032be46dced573cd195956e1Robert Greenwalt    @VisibleForTesting
658af5593594070f825032be46dced573cd195956e1Robert Greenwalt    public DcTracker() {
659af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mAlarmManager = null;
660af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mCm = null;
661af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mPhone = null;
662af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mUiccController = null;
663af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mDataConnectionTracker = null;
664af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mProvisionActionName = null;
665f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver = new SettingsObserver(null, this);
666af5593594070f825032be46dced573cd195956e1Robert Greenwalt    }
667af5593594070f825032be46dced573cd195956e1Robert Greenwalt
6681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void registerServiceStateTrackerEvents() {
6691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataConnectionAttached(this,
6701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null);
6711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataConnectionDetached(this,
6721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_DATA_CONNECTION_DETACHED, null);
6731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataRoamingOn(this,
6741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_ROAMING_ON, null);
6751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataRoamingOff(this,
6760d6ff7958dac61b9e2d689267c34ddfa0c666d9dfionaxu                DctConstants.EVENT_ROAMING_OFF, null, true);
6771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForPsRestrictedEnabled(this,
6781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_PS_RESTRICT_ENABLED, null);
6791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForPsRestrictedDisabled(this,
6801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_PS_RESTRICT_DISABLED, null);
6811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(this,
6821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_DATA_RAT_CHANGED, null);
683cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
684c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
6851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void unregisterServiceStateTrackerEvents() {
6861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataConnectionAttached(this);
6871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataConnectionDetached(this);
6881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataRoamingOn(this);
6891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataRoamingOff(this);
6901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForPsRestrictedEnabled(this);
6911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForPsRestrictedDisabled(this);
6921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged(this);
6931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
6941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void registerForAllEvents() {
696a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.mCi.registerForAvailable(this, DctConstants.EVENT_RADIO_AVAILABLE, null);
697a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.mCi.registerForOffOrNotAvailable(this,
6989c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
69937a3e51d244774ba156a88cf101432b62c8a42a3Jack Yu        mPhone.mCi.registerForDataCallListChanged(this,
7009c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                DctConstants.EVENT_DATA_STATE_CHANGED, null);
7010710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // Note, this is fragile - the Phone is now presenting a merged picture
7020710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // of PS (volte) & CS and by diving into its internals you're just seeing
7030710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // the CS data.  This works well for the purposes this is currently used for
7040710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // but that may not always be the case.  Should probably be redesigned to
7050710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // accurately reflect what we're really interested in (registerForCSVoiceCallEnded).
7061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getCallTracker().registerForVoiceCallEnded(this,
7071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_VOICE_CALL_ENDED, null);
7081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getCallTracker().registerForVoiceCallStarted(this,
7091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_VOICE_CALL_STARTED, null);
7101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        registerServiceStateTrackerEvents();
711a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     //   SubscriptionManager.registerForDdsSwitch(this,
712a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     //          DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS, null);
7132e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        mPhone.mCi.registerForPcoData(this, DctConstants.EVENT_PCO_DATA_RECEIVED, null);
7146a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu        mPhone.getCarrierActionAgent().registerForCarrierAction(
7156a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu                CarrierActionAgent.CARRIER_ACTION_SET_METERED_APNS_ENABLED, this,
7166a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu                DctConstants.EVENT_SET_CARRIER_DATA_ENABLED, null, false);
717a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
7181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
719cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void dispose() {
7201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("DCT.dispose");
7214dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt
722b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        if (mProvisionBroadcastReceiver != null) {
723b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            mPhone.getContext().unregisterReceiver(mProvisionBroadcastReceiver);
724b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            mProvisionBroadcastReceiver = null;
725b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
7262b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        if (mProvisioningSpinner != null) {
7272b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.dismiss();
7282b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner = null;
7292b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        }
730b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
731cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, null);
732cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
7331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
7341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            dcac.disconnect();
7351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
7361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDataConnectionAcHashMap.clear();
7371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mIsDisposed = true;
7381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getContext().unregisterReceiver(mIntentReceiver);
7391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mUiccController.unregisterForIccChanged(this);
740f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.unobserve();
741f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
7421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mSubscriptionManager
7431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                .removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
7441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcc.dispose();
7451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcTesterFailBringUpAll.dispose();
746cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
747a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getContext().getContentResolver().unregisterContentObserver(mApnObserver);
748a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mApnContexts.clear();
749af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mApnContextsById.clear();
750a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPrioritySortedApnContexts.clear();
751c374098c17a81f73f51e9d7df99eba574882949bYifan Bai        unregisterForAllEvents();
752a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
753a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        destroyDataConnections();
754a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
7551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void unregisterForAllEvents() {
757a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         //Unregister for all events
75822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.unregisterForAvailable(this);
75922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.unregisterForOffOrNotAvailable(this);
760cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
761a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (r != null) {
762a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            r.unregisterForRecordsLoaded(this);
763a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mIccRecords.set(null);
764a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
76537a3e51d244774ba156a88cf101432b62c8a42a3Jack Yu        mPhone.mCi.unregisterForDataCallListChanged(this);
766cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getCallTracker().unregisterForVoiceCallEnded(this);
767cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getCallTracker().unregisterForVoiceCallStarted(this);
7681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        unregisterServiceStateTrackerEvents();
769a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        //SubscriptionManager.unregisterForDdsSwitch(this);
7702e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        mPhone.mCi.unregisterForPcoData(this);
7716a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu        mPhone.getCarrierActionAgent().unregisterForCarrierAction(this,
7726a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu                CarrierActionAgent.CARRIER_ACTION_SET_METERED_APNS_ENABLED);
773cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
774cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
7751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
7761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Called when EVENT_RESET_DONE is received so goto
7771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * IDLE state and send notifications to those interested.
7781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     *
7791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * TODO - currently unused.  Needs to be hooked into DataConnection cleanup
7801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * TODO - needs to pass some notion of which connection is reset..
7811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
7821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onResetDone(AsyncResult ar) {
7831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("EVENT_RESET_DONE");
7841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        String reason = null;
7851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (ar.userObj instanceof String) {
7861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            reason = (String) ar.userObj;
7871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
7881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        gotoIdleAndNotifyDataConnection(reason);
7891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
7901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
7921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Modify {@link android.provider.Settings.Global#MOBILE_DATA} value.
7931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
7941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void setDataEnabled(boolean enable) {
7951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.CMD_SET_USER_DATA_ENABLE);
7961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = enable ? 1 : 0;
7971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("setDataEnabled: sendMessage: enable=" + enable);
7981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
7991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
8001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetUserDataEnabled(boolean enabled) {
802a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        synchronized (mDataEnabledSettings) {
803a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            if (mDataEnabledSettings.isUserDataEnabled() != enabled) {
804a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                mDataEnabledSettings.setUserDataEnabled(enabled);
8051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
806a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                //TODO: We should move the followings into DataEnabledSettings class.
8071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // For single SIM phones, this is a per phone property.
8081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (TelephonyManager.getDefault().getSimCount() == 1) {
8091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    Settings.Global.putInt(mResolver, Settings.Global.MOBILE_DATA, enabled ? 1 : 0);
8101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
8111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    int phoneSubId = mPhone.getSubId();
8121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    Settings.Global.putInt(mResolver, Settings.Global.MOBILE_DATA + phoneSubId,
8131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            enabled ? 1 : 0);
8141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
8155b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu                if (!getDataRoamingEnabled() && mPhone.getServiceState().getDataRoaming()) {
8161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (enabled) {
8171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
8181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
8191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        notifyOffApnsOfAvailability(Phone.REASON_DATA_DISABLED);
8201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
8211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
8221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
823a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                // TODO: We should register for DataEnabledSetting's data enabled/disabled event and
824a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                // handle the rest from there.
8251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (enabled) {
826120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    reevaluateDataConnections();
8271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onTrySetupData(Phone.REASON_DATA_ENABLED);
8281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
8291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);
8301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
8311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
8321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
8331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
8341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8355292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt    /**
836120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * Reevaluate existing data connections when conditions change.
837120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     *
838120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * For example, handle reverting restricted networks back to unrestricted. If we're changing
839120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * user data to enabled and this makes data truly enabled (not disabled by other factors) we
840120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * need to tear down any metered apn type that was enabled anyway by a privileged request.
841120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * This allows us to reconnect to it in an unrestricted way.
842120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     *
843120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * Or when we brought up a unmetered data connection while data is off, we only limit this
844120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * data connection for unmetered use only. When data is turned back on, we need to tear that
845120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * down so a full capable data connection can be re-established.
8465292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt     */
847120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu    private void reevaluateDataConnections() {
848120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        if (mDataEnabledSettings.isDataEnabled()) {
8495292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt            for (ApnContext apnContext : mApnContexts.values()) {
850120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                if (apnContext.isConnectedOrConnecting()) {
851120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    final DcAsyncChannel dcac = apnContext.getDcAc();
852120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    if (dcac != null) {
853120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                        final NetworkCapabilities netCaps = dcac.getNetworkCapabilitiesSync();
854120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                        if (netCaps != null && !netCaps.hasCapability(NetworkCapabilities
855ee00c053e0cbbbdb22737c923b1a214e10453646Jack Yu                                .NET_CAPABILITY_NOT_RESTRICTED) && !netCaps.hasCapability(
856ee00c053e0cbbbdb22737c923b1a214e10453646Jack Yu                                NetworkCapabilities.NET_CAPABILITY_NOT_METERED)) {
857120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            if (DBG) {
858ee00c053e0cbbbdb22737c923b1a214e10453646Jack Yu                                log("Tearing down restricted metered net:" + apnContext);
859120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            }
860ee00c053e0cbbbdb22737c923b1a214e10453646Jack Yu                            // Tearing down the restricted metered data call when
861120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // conditions change. This will allow reestablishing a new unrestricted
862120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // data connection.
863120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            apnContext.setReason(Phone.REASON_DATA_ENABLED);
864120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            cleanUpConnection(true, apnContext);
86550734be549285702de00295778b8c2a4360215a0Jack Yu                        } else if (apnContext.getApnSetting().isMetered(mPhone)
866120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                                && (netCaps != null && netCaps.hasCapability(
867120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                                        NetworkCapabilities.NET_CAPABILITY_NOT_METERED))) {
868120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            if (DBG) {
869120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                                log("Tearing down unmetered net:" + apnContext);
870120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            }
871120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // The APN settings is metered, but the data was still marked as
872120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // unmetered data, must be the unmetered data connection brought up when
873120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // data is off. We need to tear that down when data is enabled again.
874120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // This will allow reestablishing a new full capability data connection.
875120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            apnContext.setReason(Phone.REASON_DATA_ENABLED);
876120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            cleanUpConnection(true, apnContext);
87776c5a9479d312139740dcaf7644172f2beb2f7e0Robert Greenwalt                        }
87876c5a9479d312139740dcaf7644172f2beb2f7e0Robert Greenwalt                    }
8795292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt                }
8805292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt            }
8815292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt        }
8825292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt    }
8835292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt
884f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    private void onDeviceProvisionedChange() {
885f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        if (getDataEnabled()) {
886a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            mDataEnabledSettings.setUserDataEnabled(true);
887120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu            reevaluateDataConnections();
888f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            onTrySetupData(Phone.REASON_DATA_ENABLED);
889f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        } else {
890a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            mDataEnabledSettings.setUserDataEnabled(false);
891f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);
892f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        }
893f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    }
8941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public long getSubId() {
8971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mPhone.getSubId();
8981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
8991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
9001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public DctConstants.Activity getActivity() {
9011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mActivity;
9021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
9031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
9041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void setActivity(DctConstants.Activity activity) {
9051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("setActivity = " + activity);
9061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mActivity = activity;
9071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.notifyDataActivity();
9081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
9091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
910af5593594070f825032be46dced573cd195956e1Robert Greenwalt    public void requestNetwork(NetworkRequest networkRequest, LocalLog log) {
911af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final int apnId = ApnContext.apnIdForNetworkRequest(networkRequest);
912af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final ApnContext apnContext = mApnContextsById.get(apnId);
913af5593594070f825032be46dced573cd195956e1Robert Greenwalt        log.log("DcTracker.requestNetwork for " + networkRequest + " found " + apnContext);
914692640f429efa8e292c6261472b2c682e1079f8eRobert Greenwalt        if (apnContext != null) apnContext.requestNetwork(networkRequest, log);
915af5593594070f825032be46dced573cd195956e1Robert Greenwalt    }
916af5593594070f825032be46dced573cd195956e1Robert Greenwalt
917af5593594070f825032be46dced573cd195956e1Robert Greenwalt    public void releaseNetwork(NetworkRequest networkRequest, LocalLog log) {
918af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final int apnId = ApnContext.apnIdForNetworkRequest(networkRequest);
919af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final ApnContext apnContext = mApnContextsById.get(apnId);
920af5593594070f825032be46dced573cd195956e1Robert Greenwalt        log.log("DcTracker.releaseNetwork for " + networkRequest + " found " + apnContext);
921692640f429efa8e292c6261472b2c682e1079f8eRobert Greenwalt        if (apnContext != null) apnContext.releaseNetwork(networkRequest, log);
922af5593594070f825032be46dced573cd195956e1Robert Greenwalt    }
923af5593594070f825032be46dced573cd195956e1Robert Greenwalt
924bda761320929f714951c328bfec6a51a1978db97Wink Saville    public boolean isApnSupported(String name) {
92591bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal        if (name == null) {
92691bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal            loge("isApnSupported: name=null");
92791bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal            return false;
92891bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal        }
929bda761320929f714951c328bfec6a51a1978db97Wink Saville        ApnContext apnContext = mApnContexts.get(name);
930bda761320929f714951c328bfec6a51a1978db97Wink Saville        if (apnContext == null) {
931bda761320929f714951c328bfec6a51a1978db97Wink Saville            loge("Request for unsupported mobile name: " + name);
932bda761320929f714951c328bfec6a51a1978db97Wink Saville            return false;
933071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
934bda761320929f714951c328bfec6a51a1978db97Wink Saville        return true;
935bda761320929f714951c328bfec6a51a1978db97Wink Saville    }
936071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
937bda761320929f714951c328bfec6a51a1978db97Wink Saville    public int getApnPriority(String name) {
938071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        ApnContext apnContext = mApnContexts.get(name);
939071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (apnContext == null) {
940bda761320929f714951c328bfec6a51a1978db97Wink Saville            loge("Request for unsupported mobile name: " + name);
941071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
942bda761320929f714951c328bfec6a51a1978db97Wink Saville        return apnContext.priority;
943071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt    }
944071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
945b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    // Turn telephony radio on or off.
946b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private void setRadio(boolean on) {
947b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        final ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
948b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        try {
949b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            phone.setRadio(on);
950b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        } catch (Exception e) {
951b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            // Ignore.
952b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
953b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    }
954b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
955b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    // Class to handle Intent dispatched with user selects the "Sign-in to network"
956b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    // notification.
957b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private class ProvisionNotificationBroadcastReceiver extends BroadcastReceiver {
9582b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        private final String mNetworkOperator;
959b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        // Mobile provisioning URL.  Valid while provisioning notification is up.
960b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        // Set prior to notification being posted as URL contains ICCID which
961b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        // disappears when radio is off (which is the case when notification is up).
962b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        private final String mProvisionUrl;
963b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
9642b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        public ProvisionNotificationBroadcastReceiver(String provisionUrl, String networkOperator) {
9652b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mNetworkOperator = networkOperator;
966b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            mProvisionUrl = provisionUrl;
967b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
968b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
969b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        private void setEnableFailFastMobileData(int enabled) {
9706395443719ec3ee0257085945e753d02f603886bRobert Greenwalt            sendMessage(obtainMessage(DctConstants.CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA, enabled, 0));
971b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
972b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
973b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        private void enableMobileProvisioning() {
974b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            final Message msg = obtainMessage(DctConstants.CMD_ENABLE_MOBILE_PROVISIONING);
975b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            msg.setData(Bundle.forPair(DctConstants.PROVISIONING_URL_KEY, mProvisionUrl));
976b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            sendMessage(msg);
977b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
978b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
979b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        @Override
980b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        public void onReceive(Context context, Intent intent) {
9812b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // Turning back on the radio can take time on the order of a minute, so show user a
9822b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // spinner so they know something is going on.
983636fbb01fd32e23d1e9ef86497115b2c992b03daSanket Padawe            log("onReceive : ProvisionNotificationBroadcastReceiver");
9842b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner = new ProgressDialog(context);
9852b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setTitle(mNetworkOperator);
9862b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setMessage(
9872b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    // TODO: Don't borrow "Connecting..." i18n string; give Telephony a version.
9882b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    context.getText(com.android.internal.R.string.media_route_status_connecting));
9892b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setIndeterminate(true);
9902b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setCancelable(true);
9912b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // Allow non-Activity Service Context to create a View.
9922b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.getWindow().setType(
9932b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
9942b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.show();
9952b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // After timeout, hide spinner so user can at least use their device.
9962b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // TODO: Indicate to user that it is taking an unusually long time to connect?
9972b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            sendMessageDelayed(obtainMessage(DctConstants.CMD_CLEAR_PROVISIONING_SPINNER,
9982b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner), PROVISIONING_SPINNER_TIMEOUT_MILLIS);
999b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            // This code is almost identical to the old
1000b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            // ConnectivityService.handleMobileProvisioningAction code.
1001b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            setRadio(true);
1002b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            setEnableFailFastMobileData(DctConstants.ENABLED);
1003b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            enableMobileProvisioning();
1004b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
1005b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    }
1006b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
1007cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1008cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void finalize() {
10097e9240253edb59e0aa657de434faa1ccdf17a742Amit Mahajan        if(DBG && mPhone != null) log("finalize");
1010cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1011cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
10124a9b3afeb2ec4d573eca335a3706392ecf9f281eWink Saville    private ApnContext addApnContext(String type, NetworkConfig networkConfig) {
10130e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        ApnContext apnContext = new ApnContext(mPhone, type, LOG_TAG, networkConfig, this);
1014cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mApnContexts.put(type, apnContext);
1015af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mApnContextsById.put(ApnContext.apnIdForApnName(type), apnContext);
10163fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        mPrioritySortedApnContexts.add(apnContext);
1017bce3d2575122929bb27ec8a37d56e96da39a3ca2Robert Greenwalt        return apnContext;
1018cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1019c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
10201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void initApnContexts() {
1021d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        log("initApnContexts: E");
1022d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        // Load device network attributes from resources
1023d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        String[] networkConfigStrings = mPhone.getContext().getResources().getStringArray(
1024d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                com.android.internal.R.array.networkAttributes);
1025d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        for (String networkConfigString : networkConfigStrings) {
1026d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            NetworkConfig networkConfig = new NetworkConfig(networkConfigString);
1027d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            ApnContext apnContext = null;
1028d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
1029d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            switch (networkConfig.type) {
1030d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE:
1031d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_DEFAULT, networkConfig);
1032d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1033d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_MMS:
1034d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_MMS, networkConfig);
1035d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1036d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_SUPL:
1037d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_SUPL, networkConfig);
1038d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1039d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_DUN:
1040d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_DUN, networkConfig);
1041d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1042d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_HIPRI:
1043d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_HIPRI, networkConfig);
1044d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1045d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_FOTA:
1046d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_FOTA, networkConfig);
1047d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1048d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_IMS:
1049d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_IMS, networkConfig);
1050d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1051d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_CBS:
1052d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_CBS, networkConfig);
1053d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1054d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_IA:
1055d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_IA, networkConfig);
1056d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1057cf5205f70eb1eac497164124187a088ecb03fff5Ram            case ConnectivityManager.TYPE_MOBILE_EMERGENCY:
1058cf5205f70eb1eac497164124187a088ecb03fff5Ram                apnContext = addApnContext(PhoneConstants.APN_TYPE_EMERGENCY, networkConfig);
1059cf5205f70eb1eac497164124187a088ecb03fff5Ram                break;
1060d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            default:
1061d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                log("initApnContexts: skipping unknown type=" + networkConfig.type);
1062d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                continue;
1063d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            }
1064d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            log("initApnContexts: apnContext=" + apnContext);
1065d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        }
1066092e6bd60f1a4a3a55fb73ad0efca1122b8e15e2Jack Yu
1067092e6bd60f1a4a3a55fb73ad0efca1122b8e15e2Jack Yu        if (VDBG) log("initApnContexts: X mApnContexts=" + mApnContexts);
1068d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt    }
1069d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
1070cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public LinkProperties getLinkProperties(String apnType) {
1071cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1072cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
1073454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = apnContext.getDcAc();
1074cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac != null) {
1075cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("return link properites for " + apnType);
1076cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return dcac.getLinkPropertiesSync();
1077cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1078cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1079cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("return new LinkProperties");
1080cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return new LinkProperties();
1081cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1082cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1083608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt    public NetworkCapabilities getNetworkCapabilities(String apnType) {
1084608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        ApnContext apnContext = mApnContexts.get(apnType);
1085608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        if (apnContext!=null) {
1086608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            DcAsyncChannel dataConnectionAc = apnContext.getDcAc();
1087608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            if (dataConnectionAc != null) {
1088608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                if (DBG) {
1089608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                    log("get active pdp is not null, return NetworkCapabilities for " + apnType);
1090608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                }
1091608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                return dataConnectionAc.getNetworkCapabilitiesSync();
1092608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            }
1093608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        }
1094608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        if (DBG) log("return new NetworkCapabilities");
1095608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        return new NetworkCapabilities();
1096608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt    }
1097cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1098cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return all active apn types
1099cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public String[] getActiveApnTypes() {
1100cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("get all active apn types");
1101cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ArrayList<String> result = new ArrayList<String>();
1102cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1103cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1104187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (mAttached.get() && apnContext.isReady()) {
1105cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                result.add(apnContext.getApnType());
1106cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
1107cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1108c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1109cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result.toArray(new String[0]);
1110cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1111cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1112cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return active apn of specific apn type
1113cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public String getActiveApnString(String apnType) {
1114ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (VDBG) log( "get active apn string for type:" + apnType);
1115cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1116cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
1117cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ApnSetting apnSetting = apnContext.getApnSetting();
1118cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnSetting != null) {
1119cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return apnSetting.apn;
1120cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1121cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1122cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
1123cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1124cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1125cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return state of specific apn type
1126cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public DctConstants.State getState(String apnType) {
1127cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1128cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
1129cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return apnContext.getState();
1130c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1131cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return DctConstants.State.FAILED;
1132cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1133c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1134c9b81a0c05128694c617fcdd67e73821895822feWink Saville    // Return if apn type is a provisioning apn.
11351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean isProvisioningApn(String apnType) {
1136c9b81a0c05128694c617fcdd67e73821895822feWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1137c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (apnContext != null) {
1138c9b81a0c05128694c617fcdd67e73821895822feWink Saville            return apnContext.isProvisioningApn();
1139c9b81a0c05128694c617fcdd67e73821895822feWink Saville        }
1140c9b81a0c05128694c617fcdd67e73821895822feWink Saville        return false;
1141c9b81a0c05128694c617fcdd67e73821895822feWink Saville    }
1142c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1143cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return state of overall
1144cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public DctConstants.State getOverallState() {
1145cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isConnecting = false;
1146cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isFailed = true; // All enabled Apns should be FAILED.
1147cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isAnyEnabled = false;
1148cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1149cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1150cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.isEnabled()) {
1151cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                isAnyEnabled = true;
1152cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                switch (apnContext.getState()) {
1153cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case CONNECTED:
1154cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case DISCONNECTING:
11551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (VDBG) log("overall state is CONNECTED");
1156cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return DctConstants.State.CONNECTED;
1157ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                case RETRYING:
1158cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case CONNECTING:
1159cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isConnecting = true;
1160cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isFailed = false;
1161cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
1162cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case IDLE:
1163cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case SCANNING:
1164cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isFailed = false;
1165cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
1166cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                default:
1167cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isAnyEnabled = true;
1168cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
1169cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1170cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1171c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1172c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1173cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (!isAnyEnabled) { // Nothing enabled. return IDLE.
11741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is IDLE");
1175cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.IDLE;
1176c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1177c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1178cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnecting) {
11791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is CONNECTING");
1180cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.CONNECTING;
1181cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (!isFailed) {
11821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is IDLE");
1183cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.IDLE;
1184cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
11851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is FAILED");
1186cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.FAILED;
1187c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1188c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1189c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
11900b03bcd1eccc833d5cac5ecf937cf0e037375561Jack Yu    @VisibleForTesting
1191120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu    public boolean isDataEnabled() {
1192120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        return mDataEnabledSettings.isDataEnabled();
1193a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1194a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1195cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //****** Called from ServiceStateTracker
1196c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1197cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Invoked when ServiceStateTracker observes a transition from GPRS
1198cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * attach to detach.
1199c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
12001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataConnectionDetached() {
1201cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        /*
1202cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * We presently believe it is unnecessary to tear down the PDP context
1203cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * when GPRS detaches, but we should stop the network polling.
1204cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         */
1205cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log ("onDataConnectionDetached: stop polling and notify detached");
1206cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopNetStatPoll();
1207cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopDataStallAlarm();
1208cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyDataConnection(Phone.REASON_DATA_DETACHED);
1209187a39f896f88eb6c5e4306d9595546654825976Wink Saville        mAttached.set(false);
1210cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1211c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1212cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onDataConnectionAttached() {
1213cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onDataConnectionAttached");
12147ab10e4710bdb54c6d9a5ee01cd443a42a2689f5Sungmin Choi        mAttached.set(true);
1215cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getOverallState() == DctConstants.State.CONNECTED) {
1216cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onDataConnectionAttached: start polling notify attached");
1217cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            startNetStatPoll();
1218cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
1219cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_DATA_ATTACHED);
1220cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1221cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // update APN availability so that APN can be enabled.
1222cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_DATA_ATTACHED);
1223cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
122412fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        if (mAutoAttachOnCreationConfig) {
1225aacc11b299ac047e73e1e712aa396ea0a6a80158Robert Greenwalt            mAutoAttachOnCreation.set(true);
122612fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        }
1227ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(Phone.REASON_DATA_ATTACHED);
1228cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1229c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
123099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu    /**
123199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * Check if it is allowed to make a data connection (without checking APN context specific
123299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * conditions).
123399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *
123499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @param dataConnectionReasons Data connection allowed or disallowed reasons as the output
123599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *                              param. It's okay to pass null here and no reasons will be
123699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *                              provided.
123799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @return True if data connection is allowed, otherwise false.
123899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     */
123999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu    public boolean isDataAllowed(DataConnectionReasons dataConnectionReasons) {
124099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        return isDataAllowed(null, dataConnectionReasons);
124199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu    }
124299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
124399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu    /**
124499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * Check if it is allowed to make a data connection for a given APN type.
124599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *
124699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @param apnContext APN context. If passing null, then will only check general but not APN
124799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *                   specific conditions (e.g. APN state, metered/unmetered APN).
124899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @param dataConnectionReasons Data connection allowed or disallowed reasons as the output
124999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *                              param. It's okay to pass null here and no reasons will be
125099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *                              provided.
125199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @return True if data connection is allowed, otherwise false.
125299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     */
125399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu    boolean isDataAllowed(ApnContext apnContext, DataConnectionReasons dataConnectionReasons) {
125499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 1: Get all environment conditions.
125599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 2: Special handling for emergency APN.
125699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 3. Build disallowed reasons.
125799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 4: Determine if data should be allowed in some special conditions.
125899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
125999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        DataConnectionReasons reasons = new DataConnectionReasons();
1260cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
126199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 1: Get all environment conditions.
126299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        final boolean internalDataEnabled = mDataEnabledSettings.isInternalDataEnabled();
12639894b3fb2f35e21d9cfd45f233ed093589e14c26sy.yun        boolean attachedState = mAttached.get();
1264cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
12650d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu        boolean radioStateFromCarrier = mPhone.getServiceStateTracker().getPowerStateFromCarrier();
126699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // TODO: Remove this hack added by ag/641832.
12670e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
12680e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        if (radioTech == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN) {
12690e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            desiredPowerState = true;
12700d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu            radioStateFromCarrier = true;
12710e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        }
12720e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh
127399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        boolean recordsLoaded = mIccRecords.get() != null && mIccRecords.get().getRecordsLoaded();
127499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
127599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        boolean defaultDataSelected = SubscriptionManager.isValidSubscriptionId(
127699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                SubscriptionManager.getDefaultDataSubscriptionId());
1277cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
127899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        boolean isMeteredApnType = apnContext == null
127950734be549285702de00295778b8c2a4360215a0Jack Yu                || ApnSetting.isMeteredApnType(apnContext.getApnType(), mPhone);
12803d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
128199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        PhoneConstants.State phoneState = PhoneConstants.State.IDLE;
12820710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // Note this is explicitly not using mPhone.getState.  See b/19090488.
12830710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // mPhone.getState reports the merge of CS and PS (volte) voice call state
12840710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // but we only care about CS calls here for data/voice concurrency issues.
12850710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // Calling getCallTracker currently gives you just the CS side where the
12860710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // ImsCallTracker is held internally where applicable.
12870710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // This should be redesigned to ask explicitly what we want:
12880710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // voiceCallStateAllowDataCall, or dataCallAllowed or something similar.
1289b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com        if (mPhone.getCallTracker() != null) {
129099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            phoneState = mPhone.getCallTracker().getState();
129199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
129299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
129399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 2: Special handling for emergency APN.
129499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (apnContext != null
129599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                && apnContext.getApnType().equals(PhoneConstants.APN_TYPE_EMERGENCY)
129699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                && apnContext.isConnectable()) {
129799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            // If this is an emergency APN, as long as the APN is connectable, we
129899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            // should allow it.
129999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            if (dataConnectionReasons != null) {
130099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                dataConnectionReasons.add(DataAllowedReasonType.EMERGENCY_APN);
130199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            }
130299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            // Bail out without further checks.
130399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            return true;
130499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
130599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
130699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 3. Build disallowed reasons.
130799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (apnContext != null && !apnContext.isConnectable()) {
130899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.APN_NOT_CONNECTABLE);
130999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
131099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
131199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // If RAT is IWLAN then don't allow default/IA PDP at all.
131299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Rest of APN types can be evaluated for remaining conditions.
131399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if ((apnContext != null && (apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
131499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                || apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IA)))
131599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                && (radioTech == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN)) {
131699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.ON_IWLAN);
131799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
131899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
131999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (isEmergency()) {
132099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.IN_ECBM);
1321b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com        }
13221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
13233d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!(attachedState || mAutoAttachOnCreation.get())) {
132499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.NOT_ATTACHED);
13253d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13263d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!recordsLoaded) {
132799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.RECORD_NOT_LOADED);
13283d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
132999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (phoneState != PhoneConstants.State.IDLE
133099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                && !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
133199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.INVALID_PHONE_STATE);
133299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.CONCURRENT_VOICE_DATA_NOT_ALLOWED);
13333d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13343d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!internalDataEnabled) {
133599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.INTERNAL_DATA_DISABLED);
13363d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13373d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!defaultDataSelected) {
133899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.DEFAULT_DATA_UNSELECTED);
13393d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13405b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (mPhone.getServiceState().getDataRoaming() && !getDataRoamingEnabled()) {
134199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.ROAMING_DISABLED);
1342c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
13433d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (mIsPsRestricted) {
134499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.PS_RESTRICTED);
13453d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13463d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!desiredPowerState) {
134799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.UNDESIRED_POWER_STATE);
13483d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13490d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu        if (!radioStateFromCarrier) {
135099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.RADIO_DISABLED_BY_CARRIER);
135199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
135299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (!mDataEnabledSettings.isDataEnabled()) {
135399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataDisallowedReasonType.DATA_DISABLED);
13540d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu        }
13553d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
135699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // If there are hard disallowed reasons, we should not allow data connection no matter what.
135799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (reasons.containsHardDisallowedReasons()) {
135899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            if (dataConnectionReasons != null) {
135999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                dataConnectionReasons.copyFrom(reasons);
136099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            }
136199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            return false;
136299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
136399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
136499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // Step 4: Determine if data should be allowed in some special conditions.
136599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
136699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // At this point, if data is not allowed, it must be because of the soft reasons. We
136799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // should start to check some special conditions that data will be allowed.
136899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
136999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // If the request APN type is unmetered and there are soft disallowed reasons (e.g. data
137099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // disabled, data roaming disabled) existing, we should allow the data because the user
137199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // won't be charged anyway.
137299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (!isMeteredApnType && !reasons.allowed()) {
137399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataAllowedReasonType.UNMETERED_APN);
137499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
137599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
137699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // If the request is restricted and there are only soft disallowed reasons (e.g. data
137799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // disabled, data roaming disabled) existing, we should allow the data.
137899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (apnContext != null
137999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                && !apnContext.hasNoRestrictedRequests(true)
138099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                && !reasons.allowed()) {
138199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataAllowedReasonType.RESTRICTED_REQUEST);
138299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
138399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
138499e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        // If at this point, we still haven't built any disallowed reasons, we should allow data.
138599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (reasons.allowed()) {
138699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            reasons.add(DataAllowedReasonType.NORMAL);
138799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
138899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
138999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (dataConnectionReasons != null) {
139099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            dataConnectionReasons.copyFrom(reasons);
139199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        }
139299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu
139399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        return reasons.allowed();
1394cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1395c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1396c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    // arg for setupDataOnConnectableApns
1397c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    private enum RetryFailures {
1398c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        // retry failed networks always (the old default)
1399c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        ALWAYS,
14000e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        // retry only when a substantial change has occurred.  Either:
1401c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        // 1) we were restricted by voice/data concurrency and aren't anymore
1402c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        // 2) our apn list has change
1403c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        ONLY_ON_CHANGE
1404c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    };
1405c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt
1406ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void setupDataOnConnectableApns(String reason) {
1407c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        setupDataOnConnectableApns(reason, RetryFailures.ALWAYS);
1408c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    }
1409c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt
1410c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    private void setupDataOnConnectableApns(String reason, RetryFailures retryFailures) {
14119c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        if (VDBG) log("setupDataOnConnectableApns: " + reason);
14123fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
1413c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu        if (DBG && !VDBG) {
1414c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            StringBuilder sb = new StringBuilder(120);
1415c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            for (ApnContext apnContext : mPrioritySortedApnContexts) {
1416c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(apnContext.getApnType());
1417c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(":[state=");
1418c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(apnContext.getState());
1419c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(",enabled=");
1420c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(apnContext.isEnabled());
1421c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append("] ");
1422c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            }
14239c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            log("setupDataOnConnectableApns: " + reason + " " + sb);
1424c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu        }
1425c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu
14263fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        for (ApnContext apnContext : mPrioritySortedApnContexts) {
1427c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            if (VDBG) log("setupDataOnConnectableApns: apnContext " + apnContext);
1428c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu
1429735bc2f4524d68155765351912ffae11306c3bd5Chris Manton            if (apnContext.getState() == DctConstants.State.FAILED
14300e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                    || apnContext.getState() == DctConstants.State.SCANNING) {
1431c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                if (retryFailures == RetryFailures.ALWAYS) {
1432ee665b78ad648abd98b019a9c9047f206ed22994Robert Greenwalt                    apnContext.releaseDataConnection(reason);
1433c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                } else if (apnContext.isConcurrentVoiceAndDataAllowed() == false &&
14340e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                        mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
1435c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    // RetryFailures.ONLY_ON_CHANGE - check if voice concurrency has changed
1436ee665b78ad648abd98b019a9c9047f206ed22994Robert Greenwalt                    apnContext.releaseDataConnection(reason);
1437c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                }
1438cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1439ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.isConnectable()) {
14409c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                log("isConnectable() call trySetupData");
1441ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setReason(reason);
1442ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                trySetupData(apnContext);
1443cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1444cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1445c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1446c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
14471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    boolean isEmergency() {
1448a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        final boolean result = mPhone.isInEcm() || mPhone.isInEmergencyCall();
14491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("isEmergency: result=" + result);
14501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return result;
14511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
14521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1453cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean trySetupData(ApnContext apnContext) {
1454cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1455cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
1456cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
1457cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
1458cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setState(DctConstants.State.CONNECTED);
1459cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1460cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1461cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("trySetupData: X We're on the simulator; assuming connected retValue=true");
1462cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return true;
1463cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1464cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
146599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        DataConnectionReasons dataConnectionReasons = new DataConnectionReasons();
146699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        boolean isDataAllowed = isDataAllowed(apnContext, dataConnectionReasons);
146799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        String logStr = "trySetupData for APN type " + apnContext.getApnType() + ", reason: "
146899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                + apnContext.getReason() + ". " + dataConnectionReasons.toString();
146999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        if (DBG) log(logStr);
147099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        apnContext.requestLog(logStr);
1471120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        if (isDataAllowed) {
1472ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getState() == DctConstants.State.FAILED) {
14733d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                String str = "trySetupData: make a FAILED ApnContext IDLE so its reusable";
14742dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                if (DBG) log(str);
14752dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                apnContext.requestLog(str);
1476ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setState(DctConstants.State.IDLE);
1477ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1478203e588e3c42a81aa8a56f595119c181a63b12caWink Saville            int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
147999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            apnContext.setConcurrentVoiceAndDataAllowed(mPhone.getServiceStateTracker()
148099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                    .isConcurrentVoiceAndDataAllowed());
1481cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.getState() == DctConstants.State.IDLE) {
1482ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                ArrayList<ApnSetting> waitingApns =
1483ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                        buildWaitingApns(apnContext.getApnType(), radioTech);
1484cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (waitingApns.isEmpty()) {
1485ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    notifyNoData(DcFailCause.MISSING_UNKNOWN_APN, apnContext);
1486cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    notifyOffApnsOfAvailability(apnContext.getReason());
14872dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    String str = "trySetupData: X No APN found retValue=false";
14882dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    if (DBG) log(str);
14892dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    apnContext.requestLog(str);
1490cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return false;
1491cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1492cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setWaitingApns(waitingApns);
1493cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) {
1494ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        log ("trySetupData: Create from mAllApnSettings : "
1495ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                    + apnListToString(mAllApnSettings));
1496cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1497cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1498cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1499cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
150099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            boolean retValue = setupData(apnContext, radioTech, dataConnectionReasons.contains(
150199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                    DataAllowedReasonType.UNMETERED_APN));
1502cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(apnContext.getReason());
1503cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1504cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("trySetupData: X retValue=" + retValue);
1505cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return retValue;
1506cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1507cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
1508ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    && apnContext.isConnectable()) {
1509cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
1510ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1511cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(apnContext.getReason());
15122e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
15132e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            StringBuilder str = new StringBuilder();
15142e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
151599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            str.append("trySetupData failed. apnContext = [type=" + apnContext.getApnType()
151699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                    + ", mState=" + apnContext.getState() + ", apnEnabled="
151799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                    + apnContext.isEnabled() + ", mDependencyMet="
151899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                    + apnContext.getDependencyMet() + "] ");
15192e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
1520120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu            if (!mDataEnabledSettings.isDataEnabled()) {
152199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                str.append("isDataEnabled() = false. " + mDataEnabledSettings);
15222e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            }
15232e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
15249d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu            // If this is a data retry, we should set the APN state to FAILED so it won't stay
15259d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu            // in SCANNING forever.
15269d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu            if (apnContext.getState() == DctConstants.State.SCANNING) {
15279d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu                apnContext.setState(DctConstants.State.FAILED);
15289d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu                str.append(" Stop retrying.");
15299d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu            }
15309d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu
15312e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            if (DBG) log(str.toString());
15322e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            apnContext.requestLog(str.toString());
1533cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
1534cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1535c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1536c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
15370e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    // Disabled apn's still need avail/unavail notifications - send them out
15381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyOffApnsOfAvailability(String reason) {
1539cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1540187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (!mAttached.get() || !apnContext.isReady()) {
1541ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) log("notifyOffApnOfAvailability type:" + apnContext.getApnType());
1542cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
1543cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                            apnContext.getApnType(),
1544cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                            PhoneConstants.DataState.DISCONNECTED);
1545cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1546ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) {
1547187a39f896f88eb6c5e4306d9595546654825976Wink Saville                    log("notifyOffApnsOfAvailability skipped apn due to attached && isReady " +
1548cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            apnContext.toString());
1549cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1550c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1551c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1552c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1553c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1554cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1555cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * If tearDown is true, this only tears down a CONNECTED session. Presently,
1556cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * there is no mechanism for abandoning an CONNECTING session,
1557cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * but would likely involve cancelling pending async requests or
1558cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * setting a flag or new state to ignore them when they came in
1559cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param tearDown true if the underlying DataConnection should be
1560cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * disconnected.
1561cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param reason reason for the clean up.
15623fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return boolean - true if we did cleanup any connections, false if they
15633fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     *                   were already all disconnected.
1564cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
15651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean cleanUpAllConnections(boolean tearDown, String reason) {
1566cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("cleanUpAllConnections: tearDown=" + tearDown + " reason=" + reason);
15673fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        boolean didDisconnect = false;
15684c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu        boolean disableMeteredOnly = false;
1569a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
15704c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu        // reasons that only metered apn will be torn down
1571a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (!TextUtils.isEmpty(reason)) {
15724c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            disableMeteredOnly = reason.equals(Phone.REASON_DATA_SPECIFIC_DISABLED) ||
15734c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                    reason.equals(Phone.REASON_ROAMING_ON) ||
15744c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                    reason.equals(Phone.REASON_CARRIER_ACTION_DISABLE_METERED_APN);
1575a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1576cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1577cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
15783fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (apnContext.isDisconnected() == false) didDisconnect = true;
15794c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            if (disableMeteredOnly) {
1580783061ca03572618c01ce244d70d82fa4328d45ffionaxu                // Use ApnSetting to decide metered or non-metered.
1581783061ca03572618c01ce244d70d82fa4328d45ffionaxu                // Tear down all metered data connections.
1582783061ca03572618c01ce244d70d82fa4328d45ffionaxu                ApnSetting apnSetting = apnContext.getApnSetting();
158350734be549285702de00295778b8c2a4360215a0Jack Yu                if (apnSetting != null && apnSetting.isMetered(mPhone)) {
1584783061ca03572618c01ce244d70d82fa4328d45ffionaxu                    if (DBG) log("clean up metered ApnContext Type: " + apnContext.getApnType());
1585a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    apnContext.setReason(reason);
1586a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    cleanUpConnection(tearDown, apnContext);
1587a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1588a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
1589a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // TODO - only do cleanup if not disconnected
1590a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                apnContext.setReason(reason);
1591a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                cleanUpConnection(tearDown, apnContext);
1592a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1593c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1594cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1595cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopNetStatPoll();
1596cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopDataStallAlarm();
1597cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1598cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: Do we need mRequestedApnType?
1599cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
1600a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1601a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("cleanUpConnection: mDisconnectPendingCount = " + mDisconnectPendingCount);
1602a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (tearDown && mDisconnectPendingCount == 0) {
1603a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyDataDisconnectComplete();
1604a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
1605a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1606a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
16073fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return didDisconnect;
1608cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1609cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1610cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1611cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Cleanup all connections.
1612cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1613cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * TODO: Cleanup only a specified connection passed as a parameter.
1614cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *       Also, make sure when you clean up a conn, if it is last apply
1615cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *       logic as though it is cleanupAllConnections
1616cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1617cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param cause for the clean up.
1618cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
16191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onCleanUpAllConnections(String cause) {
1620cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, cause);
1621cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1622cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
16231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    void sendCleanUpConnection(boolean tearDown, ApnContext apnContext) {
16241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("sendCleanUpConnection: tearDown=" + tearDown + " apnContext=" + apnContext);
16251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_CLEAN_UP_CONNECTION);
16261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = tearDown ? 1 : 0;
16271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg2 = 0;
16281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.obj = apnContext;
16291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
16301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
1631cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
16321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void cleanUpConnection(boolean tearDown, ApnContext apnContext) {
1633cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
1634cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("cleanUpConnection: apn context is null");
1635cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
1636cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1637cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1638454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac = apnContext.getDcAc();
16392dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        String str = "cleanUpConnection: tearDown=" + tearDown + " reason=" +
16402dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                apnContext.getReason();
16419c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        if (VDBG) log(str + " apnContext=" + apnContext);
16422dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog(str);
1643cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (tearDown) {
1644cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.isDisconnected()) {
1645cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // The request is tearDown and but ApnContext is not connected.
1646cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // If apnContext is not enabled anymore, break the linkage to the DCAC/DC.
1647cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setState(DctConstants.State.IDLE);
1648cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (!apnContext.isReady()) {
16494750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                    if (dcac != null) {
16500e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                        str = "cleanUpConnection: teardown, disconnected, !ready";
16512dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        if (DBG) log(str + " apnContext=" + apnContext);
16522dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        apnContext.requestLog(str);
16534750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                        dcac.tearDown(apnContext, "", null);
16544750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                    }
1655cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setDataConnectionAc(null);
1656cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1657cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1658cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Connection is still there. Try to clean up.
1659cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (dcac != null) {
1660cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (apnContext.getState() != DctConstants.State.DISCONNECTING) {
1661cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        boolean disconnectAll = false;
1662cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (PhoneConstants.APN_TYPE_DUN.equals(apnContext.getApnType())) {
1663a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            // CAF_MSIM is this below condition required.
1664a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            // if (PhoneConstants.APN_TYPE_DUN.equals(PhoneConstants.APN_TYPE_DEFAULT)) {
16651484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                            if (teardownForDun()) {
166645eaa2335e64a8ff1ad8d5e8224c580ef996f370Wink Saville                                if (DBG) {
166745eaa2335e64a8ff1ad8d5e8224c580ef996f370Wink Saville                                    log("cleanUpConnection: disconnectAll DUN connection");
166845eaa2335e64a8ff1ad8d5e8224c580ef996f370Wink Saville                                }
1669cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // we need to tear it down - we brought it up just for dun and
1670cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // other people are camped on it and now dun is done.  We need
1671cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // to stop using it and let the normal apn list get used to find
1672cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // connections for the remaining desired connections
1673cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                disconnectAll = true;
1674cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            }
1675cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
16761a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                        final int generation = apnContext.getConnectionGeneration();
16771a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                        str = "cleanUpConnection: tearing down" + (disconnectAll ? " all" : "") +
16781a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                                " using gen#" + generation;
16792dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        if (DBG) log(str + "apnContext=" + apnContext);
16802dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        apnContext.requestLog(str);
168137cacdfe7ed079d89fb9e80317b5dfd2acb975e5Robert Greenwalt                        Pair<ApnContext, Integer> pair =
16821a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                                new Pair<ApnContext, Integer>(apnContext, generation);
168337cacdfe7ed079d89fb9e80317b5dfd2acb975e5Robert Greenwalt                        Message msg = obtainMessage(DctConstants.EVENT_DISCONNECT_DONE, pair);
1684cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (disconnectAll) {
1685ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            apnContext.getDcAc().tearDownAll(apnContext.getReason(), msg);
1686cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        } else {
1687ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            apnContext.getDcAc()
1688cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                .tearDown(apnContext, apnContext.getReason(), msg);
1689cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
1690cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.setState(DctConstants.State.DISCONNECTING);
1691a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        mDisconnectPendingCount++;
1692cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1693cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1694cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // apn is connected but no reference to dcac.
1695cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // Should not be happen, but reset the state in case.
1696cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setState(DctConstants.State.IDLE);
16972dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    apnContext.requestLog("cleanUpConnection: connected, bug no DCAC");
1698cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mPhone.notifyDataConnection(apnContext.getReason(),
1699cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                                apnContext.getApnType());
1700cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1701cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1702cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1703cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // force clean up the data connection.
1704ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac != null) dcac.reqReset();
1705cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setState(DctConstants.State.IDLE);
1706cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1707cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setDataConnectionAc(null);
1708cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1709cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1710ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // Make sure reconnection alarm is cleaned up if there is no ApnContext
1711cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // associated to the connection.
1712cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (dcac != null) {
1713ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            cancelReconnectAlarm(apnContext);
1714c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
17152dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        str = "cleanUpConnection: X tearDown=" + tearDown + " reason=" + apnContext.getReason();
17162dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        if (DBG) log(str + " apnContext=" + apnContext + " dcac=" + apnContext.getDcAc());
17172dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog(str);
1718cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1719c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
17205fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan    /**
17215fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan     * Fetch dun apn
17225fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan     * @return ApnSetting to be used for dun
17235fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan     */
17245fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan    @VisibleForTesting
17255fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan    public ApnSetting fetchDunApn() {
17261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (SystemProperties.getBoolean("net.tethering.noprovisioning", false)) {
17271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("fetchDunApn: net.tethering.noprovisioning=true ret: null");
17281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return null;
17291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
17301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int bearer = mPhone.getServiceState().getRilDataRadioTechnology();
1731d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        IccRecords r = mIccRecords.get();
1732d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        String operator = (r != null) ? r.getOperatorNumeric() : "";
1733d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        ArrayList<ApnSetting> dunCandidates = new ArrayList<ApnSetting>();
17341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting retDunSetting = null;
1735d92c67aa965200385acf3182ffb0af25297a366fJunda Liu
17365fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan        // Places to look for tether APN in order: TETHER_DUN_APN setting (to be deprecated soon),
17375fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan        // APN database, and config_tether_apndata resource (to be deprecated soon).
17381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        String apnData = Settings.Global.getString(mResolver, Settings.Global.TETHER_DUN_APN);
1739d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        if (!TextUtils.isEmpty(apnData)) {
1740d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            dunCandidates.addAll(ApnSetting.arrayFromString(apnData));
1741d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            if (VDBG) log("fetchDunApn: dunCandidates from Setting: " + dunCandidates);
1742d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        }
17435fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan
17445fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan        // todo: remove this and config_tether_apndata after APNs are moved from overlay to apns xml
17455fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan        // If TETHER_DUN_APN isn't set or APN database doesn't have dun APN,
1746d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        // try the resource as last resort.
1747d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        if (dunCandidates.isEmpty()) {
1748d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            String[] apnArrayData = mPhone.getContext().getResources()
1749d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                .getStringArray(R.array.config_tether_apndata);
1750ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu            if (!ArrayUtils.isEmpty(apnArrayData)) {
1751ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                for (String apnString : apnArrayData) {
1752ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                    ApnSetting apn = ApnSetting.fromString(apnString);
1753ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                    // apn may be null if apnString isn't valid or has error parsing
1754ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                    if (apn != null) dunCandidates.add(apn);
1755ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                }
1756ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                if (VDBG) log("fetchDunApn: dunCandidates from resource: " + dunCandidates);
1757d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            }
17581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
17591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
17605fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan        if (dunCandidates.isEmpty()) {
17615fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan            if (!ArrayUtils.isEmpty(mAllApnSettings)) {
17625fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan                for (ApnSetting apn : mAllApnSettings) {
17635fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan                    if (apn.canHandleType(PhoneConstants.APN_TYPE_DUN)) {
17645fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan                        dunCandidates.add(apn);
17655fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan                    }
17665fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan                }
17675fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan                if (VDBG) log("fetchDunApn: dunCandidates from database: " + dunCandidates);
17685fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan            }
17695fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan        }
17705fd5bb14cf73b74120041e4cc317684c5a43a67cAmit Mahajan
1771d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        for (ApnSetting dunSetting : dunCandidates) {
1772d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            if (!ServiceState.bitmaskHasTech(dunSetting.bearerBitmask, bearer)) continue;
1773d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            if (dunSetting.numeric.equals(operator)) {
17741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (dunSetting.hasMvnoParams()) {
17751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (r != null && ApnSetting.mvnoMatches(r, dunSetting.mvnoType,
17761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            dunSetting.mvnoMatchData)) {
1777d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                        retDunSetting = dunSetting;
1778d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                        break;
17791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
17801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else if (mMvnoMatched == false) {
17811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    retDunSetting = dunSetting;
1782d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                    break;
17831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
17841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
17851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
17861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1787d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        if (VDBG) log("fetchDunApn: dunSetting=" + retDunSetting);
17881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return retDunSetting;
17891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
17901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
17911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public boolean hasMatchedTetherApnSetting() {
17921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting matched = fetchDunApn();
17931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("hasMatchedTetherApnSetting: APN=" + matched);
17941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return matched != null;
17951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
17961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1797cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
17981484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt     * Determine if DUN connection is special and we need to teardown on start/stop
17991484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt     */
18001484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt    private boolean teardownForDun() {
18011484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // CDMA always needs to do this the profile id is correct
18021484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        final int rilRat = mPhone.getServiceState().getRilDataRadioTechnology();
18031484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        if (ServiceState.isCdma(rilRat)) return true;
18041484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt
18051484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        return (fetchDunApn() != null);
18061484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt    }
18071484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt
18081484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt    /**
1809ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Cancels the alarm associated with apnContext.
1810cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1811ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * @param apnContext on which the alarm should be stopped.
1812cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1813ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void cancelReconnectAlarm(ApnContext apnContext) {
1814ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnContext == null) return;
1815cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1816ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        PendingIntent intent = apnContext.getReconnectIntent();
1817cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1818cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (intent != null) {
1819cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                AlarmManager am =
1820cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
1821cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                am.cancel(intent);
1822ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setReconnectIntent(null);
1823cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1824c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1825c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1826cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1827cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param types comma delimited list of APN types
1828cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return array of APN types
1829cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1830cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private String[] parseTypes(String types) {
1831c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String[] result;
1832cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // If unset, set to DEFAULT.
1833cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (types == null || types.equals("")) {
1834c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            result = new String[1];
1835cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result[0] = PhoneConstants.APN_TYPE_ALL;
1836cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1837cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result = types.split(",");
1838c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1839c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
1840c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1841c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1842ccfe5ebaf81c1378e8dbe44e45df26b0dc462a21Jack Yu    boolean isPermanentFailure(DcFailCause dcFailCause) {
1843ccfe5ebaf81c1378e8dbe44e45df26b0dc462a21Jack Yu        return (dcFailCause.isPermanentFailure(mPhone.getContext(), mPhone.getSubId()) &&
1844796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan                (mAttached.get() == false || dcFailCause != DcFailCause.SIGNAL_LOST));
1845796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan    }
1846796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan
1847fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    private ApnSetting makeApnSetting(Cursor cursor) {
1848fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        String[] types = parseTypes(
1849fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.TYPE)));
1850fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        ApnSetting apn = new ApnSetting(
1851fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID)),
1852fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NUMERIC)),
1853fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NAME)),
1854fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN)),
1855fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1856fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1857fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY))),
1858fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PORT)),
1859fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1860fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1861fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC))),
1862fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1863fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1864fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY))),
1865fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPORT)),
1866fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)),
1867fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)),
18681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.AUTH_TYPE)),
1869fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                types,
1870fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROTOCOL)),
1871fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(
1872fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        Telephony.Carriers.ROAMING_PROTOCOL)),
1873fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(
1874fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        Telephony.Carriers.CARRIER_ENABLED)) == 1,
18759d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.BEARER)),
1876aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.BEARER_BITMASK)),
18779d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROFILE_ID)),
18789d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(
18799d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                        Telephony.Carriers.MODEM_COGNITIVE)) == 1,
18809d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MAX_CONNS)),
18819d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(
18829d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                        Telephony.Carriers.WAIT_TIME)),
1883e9701717e43cc5aacbcf624f77a53be92350662cw                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MAX_CONNS_TIME)),
18843262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MTU)),
18853262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_TYPE)),
18863262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_MATCH_DATA)));
1887fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        return apn;
1888fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    }
1889fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
1890cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ArrayList<ApnSetting> createApnList(Cursor cursor) {
18913262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        ArrayList<ApnSetting> mnoApns = new ArrayList<ApnSetting>();
18923262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        ArrayList<ApnSetting> mvnoApns = new ArrayList<ApnSetting>();
1893fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        IccRecords r = mIccRecords.get();
1894fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
1895cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor.moveToFirst()) {
1896cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            do {
18973262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                ApnSetting apn = makeApnSetting(cursor);
18983262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                if (apn == null) {
18993262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                    continue;
19003262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                }
19013262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
19023262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                if (apn.hasMvnoParams()) {
190363913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan                    if (r != null && ApnSetting.mvnoMatches(r, apn.mvnoType, apn.mvnoMatchData)) {
19043262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                        mvnoApns.add(apn);
1905fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    }
1906fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                } else {
19073262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                    mnoApns.add(apn);
1908fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                }
1909cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } while (cursor.moveToNext());
1910cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
19113262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
19121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ArrayList<ApnSetting> result;
19131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mvnoApns.isEmpty()) {
19141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            result = mnoApns;
19151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mMvnoMatched = false;
19161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
19171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            result = mvnoApns;
19181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mMvnoMatched = true;
19191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
1920cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createApnList: X result=" + result);
1921c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
1922c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1923c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1924454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private boolean dataConnectionNotInUse(DcAsyncChannel dcac) {
1925ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("dataConnectionNotInUse: check if dcac is inuse dcac=" + dcac);
1926cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1927ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getDcAc() == dcac) {
1928cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("dataConnectionNotInUse: in use by apnContext=" + apnContext);
1929cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
1930cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1931cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1932cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: Fix retry handling so free DataConnections have empty apnlists.
1933cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Probably move retry handling into DataConnections and reduce complexity
1934cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // of DCT.
1935cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("dataConnectionNotInUse: tearDownAll");
1936ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        dcac.tearDownAll("No connection", null);
1937cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("dataConnectionNotInUse: not in use return true");
1938cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
1939cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1940cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1941454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel findFreeDataConnection() {
1942454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
1943cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac.isInactiveSync() && dataConnectionNotInUse(dcac)) {
1944cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
1945cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("findFreeDataConnection: found free DataConnection=" +
1946ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        " dcac=" + dcac);
1947cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1948ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                return dcac;
1949cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1950cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1951cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("findFreeDataConnection: NO free DataConnection");
1952cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
1953cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1954cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
195599e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu    /**
195699e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * Setup a data connection based on given APN type.
195799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *
195899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @param apnContext APN context
195999e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @param radioTech RAT of the data connection
196099e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @param unmeteredUseOnly True if this data connection should be only used for unmetered
196199e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     *                         purposes only.
196299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     * @return True if successful, otherwise false.
196399e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu     */
1964120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu    private boolean setupData(ApnContext apnContext, int radioTech, boolean unmeteredUseOnly) {
1965cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setupData: apnContext=" + apnContext);
19662dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog("setupData");
1967ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnSetting apnSetting;
19681484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        DcAsyncChannel dcac = null;
1969cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
19700e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        apnSetting = apnContext.getNextApnSetting();
19710e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
1972ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnSetting == null) {
1973cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("setupData: return for no apn found!");
1974cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
1975cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1976cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1977231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        int profileId = apnSetting.profileId;
1978231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        if (profileId == 0) {
1979231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen            profileId = getApnProfileID(apnContext.getApnType());
1980231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        }
1981231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen
19821484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // On CDMA, if we're explicitly asking for DUN, we need have
19831484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // a dun-profiled connection so we can't share an existing one
19841484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // On GSM/LTE we can share existing apn connections provided they support
19851484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // this type.
19861484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        if (apnContext.getApnType() != PhoneConstants.APN_TYPE_DUN ||
19871484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                teardownForDun() == false) {
19881484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt            dcac = checkForCompatibleConnectedApnContext(apnContext);
19891484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt            if (dcac != null) {
19901484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // Get the dcacApnSetting for the connection we want to share.
19911484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                ApnSetting dcacApnSetting = dcac.getApnSettingSync();
19921484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                if (dcacApnSetting != null) {
19931484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    // Setting is good, so use it.
19941484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    apnSetting = dcacApnSetting;
19951484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                }
1996ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1997ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
1998ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (dcac == null) {
19993fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (isOnlySingleDcAllowed(radioTech)) {
20003fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (isHigherPriorityApnContextActive(apnContext)) {
20013fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (DBG) {
20023fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        log("setupData: Higher priority ApnContext active.  Ignoring call");
20033fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    }
20043fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    return false;
20053fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                }
20063fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
20073fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // Only lower priority calls left.  Disconnect them all in this single PDP case
20083fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // so that we can bring up the requested higher priority call (once we receive
20090e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                // response for deactivate request for the calls we are about to disconnect
20103fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (cleanUpAllConnections(true, Phone.REASON_SINGLE_PDN_ARBITRATION)) {
20113fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // If any call actually requested to be disconnected, means we can't
20123fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // bring up this connection yet as we need to wait for those data calls
20133fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // to be disconnected.
20143fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (DBG) log("setupData: Some calls are disconnecting first.  Wait and retry");
20153fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    return false;
20163fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                }
20173fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
20183fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // No other calls are active, so proceed
20193fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (DBG) log("setupData: Single pdp. Continue setting up data call.");
20203fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
20213fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
2022ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            dcac = findFreeDataConnection();
2023cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2024ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac == null) {
2025ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                dcac = createDataConnection();
2026cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2027cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2028ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac == null) {
2029ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) log("setupData: No free DataConnection and couldn't create one, WEIRD");
2030cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
2031cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2032cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
20331a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        final int generation = apnContext.incAndGetConnectionGeneration();
20341a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        if (DBG) {
20351a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt            log("setupData: dcac=" + dcac + " apnSetting=" + apnSetting + " gen#=" + generation);
20361a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        }
2037cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2038cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setDataConnectionAc(dcac);
2039ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setApnSetting(apnSetting);
2040cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setState(DctConstants.State.CONNECTING);
2041cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
2042cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2043cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Message msg = obtainMessage();
2044cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        msg.what = DctConstants.EVENT_DATA_SETUP_COMPLETE;
20451a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        msg.obj = new Pair<ApnContext, Integer>(apnContext, generation);
2046120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        dcac.bringUp(apnContext, profileId, radioTech, unmeteredUseOnly, msg, generation);
2047cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2048cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setupData: initing!");
2049cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
2050cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2051cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
20521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void setInitialAttachApn() {
20531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting iaApnSetting = null;
20541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting defaultApnSetting = null;
20551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting firstApnSetting = null;
20561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
20571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("setInitialApn: E mPreferredApn=" + mPreferredApn);
20581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
205940b0e247a4a79e83f10b6410025ef1d7cc537692Robert Greenwalt        if (mPreferredApn != null && mPreferredApn.canHandleType(PhoneConstants.APN_TYPE_IA)) {
206040b0e247a4a79e83f10b6410025ef1d7cc537692Robert Greenwalt              iaApnSetting = mPreferredApn;
206140b0e247a4a79e83f10b6410025ef1d7cc537692Robert Greenwalt        } else if (mAllApnSettings != null && !mAllApnSettings.isEmpty()) {
20621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            firstApnSetting = mAllApnSettings.get(0);
20631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("setInitialApn: firstApnSetting=" + firstApnSetting);
20641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
20651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Search for Initial APN setting and the first apn that can handle default
20661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (ApnSetting apn : mAllApnSettings) {
206740b0e247a4a79e83f10b6410025ef1d7cc537692Robert Greenwalt                if (apn.canHandleType(PhoneConstants.APN_TYPE_IA)) {
20681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // The Initial Attach APN is highest priority so use it if there is one
20691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("setInitialApn: iaApnSetting=" + apn);
20701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    iaApnSetting = apn;
20711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    break;
20721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else if ((defaultApnSetting == null)
20731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        && (apn.canHandleType(PhoneConstants.APN_TYPE_DEFAULT))) {
20741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // Use the first default apn if no better choice
20751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("setInitialApn: defaultApnSetting=" + apn);
20761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    defaultApnSetting = apn;
20771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
20781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
20791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
20801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
20811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // The priority of apn candidates from highest to lowest is:
20820e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        //   1) APN_TYPE_IA (Initial Attach)
20831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        //   2) mPreferredApn, i.e. the current preferred apn
20841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        //   3) The first apn that than handle APN_TYPE_DEFAULT
20851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        //   4) The first APN we can find.
20861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
20871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting initialAttachApnSetting = null;
20881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (iaApnSetting != null) {
20891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using iaApnSetting");
20901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = iaApnSetting;
20911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (mPreferredApn != null) {
20921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using mPreferredApn");
20931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = mPreferredApn;
20941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (defaultApnSetting != null) {
20951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using defaultApnSetting");
20961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = defaultApnSetting;
20971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (firstApnSetting != null) {
20981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using firstApnSetting");
20991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = firstApnSetting;
21001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
21011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
21021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (initialAttachApnSetting == null) {
21031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: X There in no available apn");
21041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
21051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: X selected Apn=" + initialAttachApnSetting);
21061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
21078e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu            mPhone.mCi.setInitialAttachApn(new DataProfile(initialAttachApnSetting),
2108cc40713c49908aeaac0070bf4ea796247f9066b5Jack Yu                    mPhone.getServiceState().getDataRoamingFromRegistration(), null);
21091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
21101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
21111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
2113cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Handles changes to the APN database.
2114c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
2115cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onApnChanged() {
2116cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        DctConstants.State overallState = getOverallState();
2117cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isDisconnected = (overallState == DctConstants.State.IDLE ||
2118cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                overallState == DctConstants.State.FAILED);
2119cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
21201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mPhone instanceof GsmCdmaPhone) {
2121cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // The "current" may no longer be valid.  MMS depends on this to send properly. TBD
21221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            ((GsmCdmaPhone)mPhone).updateCurrentCarrierInProvider();
2123cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2124cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2125cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: It'd be nice to only do this if the changed entrie(s)
2126cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // match the current operator.
2127cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onApnChanged: createAllApnList and cleanUpAllConnections");
2128cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        createAllApnList();
21295d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi        setInitialAttachApn();
2130ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu        cleanUpConnectionsOnUpdatedApns(!isDisconnected, Phone.REASON_APN_CHANGED);
2131bda761320929f714951c328bfec6a51a1978db97Wink Saville
21328f6f52e4f7598e44cea1f9e5f4781291f9060d1dWink Saville        // FIXME: See bug 17426028 maybe no conditional is needed.
213338ca51d0f643405df51e78fce6c546424e9f410dShishir Agrawal        if (mPhone.getSubId() == SubscriptionManager.getDefaultDataSubscriptionId()) {
2134ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_APN_CHANGED);
2135c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2136c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2137c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2138c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
2139cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param cid Connection id provided from RIL.
2140cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return DataConnectionAc associated with specified cid.
2141c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
2142454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel findDataConnectionAcByCid(int cid) {
2143454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
2144cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac.getCidSync() == cid) {
2145cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return dcac;
2146cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2147c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2148cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
2149c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2150c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2151cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // TODO: For multiple Active APNs not exactly sure how to do this.
21521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void gotoIdleAndNotifyDataConnection(String reason) {
2153cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("gotoIdleAndNotifyDataConnection: reason=" + reason);
2154cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyDataConnection(reason);
2155cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2156cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
21573fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    /**
21583fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * "Active" here means ApnContext isEnabled() and not in FAILED state
21593fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @param apnContext to compare with
21603fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return true if higher priority active apn found
21613fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     */
21623fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean isHigherPriorityApnContextActive(ApnContext apnContext) {
21633fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        for (ApnContext otherContext : mPrioritySortedApnContexts) {
21643fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (apnContext.getApnType().equalsIgnoreCase(otherContext.getApnType())) return false;
21653fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (otherContext.isEnabled() && otherContext.getState() != DctConstants.State.FAILED) {
21663fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                return true;
21673fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
21683fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
21693fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return false;
21703fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    }
21713fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
21723fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    /**
21733fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * Reports if we support multiple connections or not.
21743fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * This is a combination of factors, based on carrier and RAT.
21753fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @param rilRadioTech the RIL Radio Tech currently in use
21763fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return true if only single DataConnection is allowed
21773fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     */
21783fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean isOnlySingleDcAllowed(int rilRadioTech) {
2179bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        // Default single dc rats with no knowledge of carrier
2180bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        int[] singleDcRats = null;
2181bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        // get the carrier specific value, if it exists, from CarrierConfigManager.
2182bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        // generally configManager and bundle should not be null, but if they are it should be okay
2183bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        // to leave singleDcRats null as well
2184bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        CarrierConfigManager configManager = (CarrierConfigManager)
2185bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu                mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
2186bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        if (configManager != null) {
2187bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu            PersistableBundle bundle = configManager.getConfig();
2188bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu            if (bundle != null) {
2189bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu                singleDcRats = bundle.getIntArray(
2190bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu                        CarrierConfigManager.KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY);
2191bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu            }
2192bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        }
21933fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        boolean onlySingleDcAllowed = false;
21943fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (Build.IS_DEBUGGABLE &&
21953fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                SystemProperties.getBoolean("persist.telephony.test.singleDc", false)) {
21963fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            onlySingleDcAllowed = true;
21973fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
21983fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (singleDcRats != null) {
21993fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            for (int i=0; i < singleDcRats.length && onlySingleDcAllowed == false; i++) {
22003fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (rilRadioTech == singleDcRats[i]) onlySingleDcAllowed = true;
22013fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
22023fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
22033fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
22043fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (DBG) log("isOnlySingleDcAllowed(" + rilRadioTech + "): " + onlySingleDcAllowed);
22053fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return onlySingleDcAllowed;
22063fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    }
22073fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
22081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    void sendRestartRadio() {
22091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG)log("sendRestartRadio:");
22101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_RESTART_RADIO);
22111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
22121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
22131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
22141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void restartRadio() {
2215cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("restartRadio: ************TURN OFF RADIO**************");
2216cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, Phone.REASON_RADIO_TURNED_OFF);
2217cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().powerOffRadioSafely(this);
2218cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        /* Note: no need to call setRadioPower(true).  Assuming the desired
2219cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * radio power state is still ON (as tracked by ServiceStateTracker),
2220cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * ServiceStateTracker will call setRadioPower when it receives the
2221cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * RADIO_STATE_CHANGED notification for the power off.  And if the
2222cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * desired power state has changed in the interim, we don't want to
2223cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * override it with an unconditional power on.
2224cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         */
2225cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2226cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int reset = Integer.parseInt(SystemProperties.get("net.ppp.reset-by-timeout", "0"));
22270e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        SystemProperties.set("net.ppp.reset-by-timeout", String.valueOf(reset + 1));
2228cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2229cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2230cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
2231cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Return true if data connection need to be setup after disconnected due to
2232cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * reason.
2233cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
22340e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu     * @param apnContext APN context
2235cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return true if try setup data connection is need for this reason
2236cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
22373fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean retryAfterDisconnected(ApnContext apnContext) {
2238cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean retry = true;
22393fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        String reason = apnContext.getReason();
2240cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
22413fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) ||
22423fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())
22433fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                 && isHigherPriorityApnContextActive(apnContext))) {
2244cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            retry = false;
2245cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2246cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return retry;
2247cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2248cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
22490e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    private void startAlarmForReconnect(long delay, ApnContext apnContext) {
2250cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String apnType = apnContext.getApnType();
225174672e8ee972f12406b72551261b4cc7e0651933Wink Saville
225274672e8ee972f12406b72551261b4cc7e0651933Wink Saville        Intent intent = new Intent(INTENT_RECONNECT_ALARM + "." + apnType);
225374672e8ee972f12406b72551261b4cc7e0651933Wink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, apnContext.getReason());
2254cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, apnType);
225567d43cfed4b996c20780bfec8fde1ae8c1391779Junda Liu        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
2256cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2257a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // Get current sub id.
225838ca51d0f643405df51e78fce6c546424e9f410dShishir Agrawal        int subId = SubscriptionManager.getDefaultDataSubscriptionId();
2259a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
2260a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
226174672e8ee972f12406b72551261b4cc7e0651933Wink Saville        if (DBG) {
226274672e8ee972f12406b72551261b4cc7e0651933Wink Saville            log("startAlarmForReconnect: delay=" + delay + " action=" + intent.getAction()
226374672e8ee972f12406b72551261b4cc7e0651933Wink Saville                    + " apn=" + apnContext);
226474672e8ee972f12406b72551261b4cc7e0651933Wink Saville        }
226574672e8ee972f12406b72551261b4cc7e0651933Wink Saville
22660e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        PendingIntent alarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0,
2267cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                        intent, PendingIntent.FLAG_UPDATE_CURRENT);
2268ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setReconnectIntent(alarmIntent);
22697d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu
22707d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu        // Use the exact timer instead of the inexact one to provide better user experience.
22717d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu        // In some extreme cases, we saw the retry was delayed for few minutes.
22720852a954be5937a1b0bca94df0c2007d7ee3c0c7Jack Yu        // Note that if the stated trigger time is in the past, the alarm will be triggered
22730852a954be5937a1b0bca94df0c2007d7ee3c0c7Jack Yu        // immediately.
22747d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu        mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
2275cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                SystemClock.elapsedRealtime() + delay, alarmIntent);
2276cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2277cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2278ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void notifyNoData(DcFailCause lastFailCauseCode,
2279cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                              ApnContext apnContext) {
2280cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log( "notifyNoData: type=" + apnContext.getApnType());
2281ccfe5ebaf81c1378e8dbe44e45df26b0dc462a21Jack Yu        if (isPermanentFailure(lastFailCauseCode)
2282cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            && (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT))) {
2283cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
2284cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2285cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2286cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
22871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public boolean getAutoAttachOnCreation() {
22881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mAutoAttachOnCreation.get();
22891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
22901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
22911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRecordsLoadedOrSubIdChanged() {
22921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("onRecordsLoadedOrSubIdChanged: createAllApnList");
229312fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        mAutoAttachOnCreationConfig = mPhone.getContext().getResources()
229412fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao                .getBoolean(com.android.internal.R.bool.config_auto_attach_data_on_creation);
2295bda761320929f714951c328bfec6a51a1978db97Wink Saville
2296cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        createAllApnList();
22975d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi        setInitialAttachApn();
229822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPhone.mCi.getRadioState().isOn()) {
22991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("onRecordsLoadedOrSubIdChanged: notifying data availability");
2300cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_SIM_LOADED);
2301cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2302bda761320929f714951c328bfec6a51a1978db97Wink Saville        setupDataOnConnectableApns(Phone.REASON_SIM_LOADED);
2303cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2304cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
23054c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu    /**
23064c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu     * Action set from carrier signalling broadcast receivers to enable/disable metered apns.
23074c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu     */
23086a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu    private void onSetCarrierDataEnabled(AsyncResult ar) {
23096a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu        if (ar.exception != null) {
23106a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu            Rlog.e(LOG_TAG, "CarrierDataEnable exception: " + ar.exception);
23116a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu            return;
23126a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu        }
2313a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        synchronized (mDataEnabledSettings) {
23146a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu            boolean enabled = (boolean) ar.result;
2315a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            if (enabled != mDataEnabledSettings.isCarrierDataEnabled()) {
2316a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                if (DBG) {
2317a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                    log("carrier Action: set metered apns enabled: " + enabled);
2318a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                }
2319a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
2320a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                // Disable/enable all metered apns
2321a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                mDataEnabledSettings.setCarrierDataEnabled(enabled);
2322a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
2323a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                if (!enabled) {
2324a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                    // Send otasp_sim_unprovisioned so that SuW is able to proceed and notify users
23256432c2f4a4f438b72fa0d4b51d5098b179935868Nathan Harold                    mPhone.notifyOtaspChanged(TelephonyManager.OTASP_SIM_UNPROVISIONED);
2326a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                    // Tear down all metered apns
2327a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                    cleanUpAllConnections(true, Phone.REASON_CARRIER_ACTION_DISABLE_METERED_APN);
2328a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                } else {
2329120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    // Re-evaluate Otasp state
23304839eb565b4294443a34a93ee2ca93ac70b72b87fionaxu                    int otaspState = mPhone.getServiceStateTracker().getOtasp();
23314839eb565b4294443a34a93ee2ca93ac70b72b87fionaxu                    mPhone.notifyOtaspChanged(otaspState);
23324839eb565b4294443a34a93ee2ca93ac70b72b87fionaxu
2333120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    reevaluateDataConnections();
2334a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                    setupDataOnConnectableApns(Phone.REASON_DATA_ENABLED);
2335a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                }
233668f4f4a0bc8d4060b5775e7a24a97ea5b485989efionaxu            }
2337a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        }
2338a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    }
2339a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
23400469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal    private void onSimNotReady() {
23410469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        if (DBG) log("onSimNotReady");
23420469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal
23430469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        cleanUpAllConnections(true, Phone.REASON_SIM_NOT_READY);
23440469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        mAllApnSettings = null;
23450469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        mAutoAttachOnCreationConfig = false;
23467e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C        // Clear auto attach as modem is expected to do a new attach once SIM is ready
23477e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C        mAutoAttachOnCreation.set(false);
23480469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal    }
23490469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal
23501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetDependencyMet(String apnType, boolean met) {
2351cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // don't allow users to tweak hipri to work around default dependency not met
2352cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_HIPRI.equals(apnType)) return;
2353cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2354cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
2355cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
2356cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onSetDependencyMet: ApnContext not found in onSetDependencyMet(" +
2357cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnType + ", " + met + ")");
2358cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
2359cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2360cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        applyNewState(apnContext, apnContext.isEnabled(), met);
2361cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_DEFAULT.equals(apnType)) {
2362cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // tie actions on default to similar actions on HIPRI regarding dependencyMet
2363cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext = mApnContexts.get(PhoneConstants.APN_TYPE_HIPRI);
2364cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext != null) applyNewState(apnContext, apnContext.isEnabled(), met);
2365cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2366cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2367c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2368a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    public void setPolicyDataEnabled(boolean enabled) {
2369a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        if (DBG) log("setPolicyDataEnabled: " + enabled);
2370a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        Message msg = obtainMessage(DctConstants.CMD_SET_POLICY_DATA_ENABLE);
2371a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        msg.arg1 = (enabled ? DctConstants.ENABLED : DctConstants.DISABLED);
2372a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        sendMessage(msg);
2373a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    }
2374a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
23751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetPolicyDataEnabled(boolean enabled) {
2376a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        synchronized (mDataEnabledSettings) {
237799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu            final boolean prevEnabled = isDataEnabled();
2378a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            if (mDataEnabledSettings.isPolicyDataEnabled() != enabled) {
2379a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                mDataEnabledSettings.setPolicyDataEnabled(enabled);
2380a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                // TODO: We should register for DataEnabledSetting's data enabled/disabled event and
2381a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                // handle the rest from there.
238299e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu                if (prevEnabled != isDataEnabled()) {
23831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (!prevEnabled) {
2384120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                        reevaluateDataConnections();
23851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onTrySetupData(Phone.REASON_DATA_ENABLED);
23861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
23871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);
23881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
23891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
23901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
23911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
23921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
23931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2394cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void applyNewState(ApnContext apnContext, boolean enabled, boolean met) {
2395cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean cleanup = false;
2396cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean trySetup = false;
23972dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        String str ="applyNewState(" + apnContext.getApnType() + ", " + enabled +
23982dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                "(" + apnContext.isEnabled() + "), " + met + "(" +
23992dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                apnContext.getDependencyMet() +"))";
24002dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        if (DBG) log(str);
24012dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog(str);
24022dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt
2403cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext.isReady()) {
2404305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt            cleanup = true;
24052428693913ae731d4ace3414429f5e91af24ea36Wink Saville            if (enabled && met) {
24062428693913ae731d4ace3414429f5e91af24ea36Wink Saville                DctConstants.State state = apnContext.getState();
24072428693913ae731d4ace3414429f5e91af24ea36Wink Saville                switch(state) {
24082428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case CONNECTING:
24092428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case CONNECTED:
24102428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case DISCONNECTING:
24112428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // We're "READY" and active so just return
24122428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        if (DBG) log("applyNewState: 'ready' so return");
24132dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        apnContext.requestLog("applyNewState state=" + state + ", so return");
24142428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        return;
24152428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case IDLE:
24162428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // fall through: this is unexpected but if it happens cleanup and try setup
24172428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case FAILED:
24189d05263529e0aa7fd68f118ca19aecffa6963844Jack Yu                    case SCANNING:
24192428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case RETRYING: {
24202428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // We're "READY" but not active so disconnect (cleanup = true) and
24212428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // connect (trySetup = true) to be sure we retry the connection.
24222428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        trySetup = true;
24232428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        apnContext.setReason(Phone.REASON_DATA_ENABLED);
24242428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        break;
24252428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    }
24262428693913ae731d4ace3414429f5e91af24ea36Wink Saville                }
2427305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt            } else if (met) {
2428cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setReason(Phone.REASON_DATA_DISABLED);
2429305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // If ConnectivityService has disabled this network, stop trying to bring
2430305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // it up, but do not tear it down - ConnectivityService will do that
2431305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // directly by talking with the DataConnection.
24321484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                //
24331484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // This doesn't apply to DUN, however.  Those connections have special
24341484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // requirements from carriers and we need stop using them when the dun
24351484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // request goes away.  This applies to both CDMA and GSM because they both
24361484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // can declare the DUN APN sharable by default traffic, thus still satisfying
24371484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // those requests and not torn down organically.
24389db4884401d436d0796138f9190079df310cee95Sukanya Rajkhowa                if ((apnContext.getApnType() == PhoneConstants.APN_TYPE_DUN && teardownForDun())
24399db4884401d436d0796138f9190079df310cee95Sukanya Rajkhowa                        || apnContext.getState() != DctConstants.State.CONNECTED) {
24409db4884401d436d0796138f9190079df310cee95Sukanya Rajkhowa                    str = "Clean up the connection. Apn type = " + apnContext.getApnType()
24419db4884401d436d0796138f9190079df310cee95Sukanya Rajkhowa                            + ", state = " + apnContext.getState();
24429db4884401d436d0796138f9190079df310cee95Sukanya Rajkhowa                    if (DBG) log(str);
24439db4884401d436d0796138f9190079df310cee95Sukanya Rajkhowa                    apnContext.requestLog(str);
24441484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    cleanup = true;
24451484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                } else {
24461484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    cleanup = false;
24471484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                }
2448cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
2449cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_UNMET);
2450cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2451cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2452cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (enabled && met) {
2453cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apnContext.isEnabled()) {
2454cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_MET);
2455cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2456cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setReason(Phone.REASON_DATA_ENABLED);
2457c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
2458cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apnContext.getState() == DctConstants.State.FAILED) {
2459cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setState(DctConstants.State.IDLE);
2460cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2461cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                trySetup = true;
2462cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2463cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2464cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setEnabled(enabled);
2465cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setDependencyMet(met);
2466cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cleanup) cleanUpConnection(true, apnContext);
24670d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt        if (trySetup) {
24680d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt            apnContext.resetErrorCodeRetries();
24690d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt            trySetupData(apnContext);
24700d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt        }
2471cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2472c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2473454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel checkForCompatibleConnectedApnContext(ApnContext apnContext) {
2474cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String apnType = apnContext.getApnType();
2475cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnSetting dunSetting = null;
2476cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2477cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_DUN.equals(apnType)) {
2478cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            dunSetting = fetchDunApn();
2479cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2480ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) {
2481ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            log("checkForCompatibleConnectedApnContext: apnContext=" + apnContext );
2482ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
2483cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2484454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel potentialDcac = null;
2485ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnContext potentialApnCtx = null;
2486ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        for (ApnContext curApnCtx : mApnContexts.values()) {
2487454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel curDcac = curApnCtx.getDcAc();
2488ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (curDcac != null) {
2489ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                ApnSetting apnSetting = curApnCtx.getApnSetting();
2490a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("apnSetting: " + apnSetting);
2491cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (dunSetting != null) {
2492cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (dunSetting.equals(apnSetting)) {
2493ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        switch (curApnCtx.getState()) {
2494cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            case CONNECTED:
2495cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                if (DBG) {
2496ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                    log("checkForCompatibleConnectedApnContext:"
2497ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                            + " found dun conn=" + curDcac
2498ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                            + " curApnCtx=" + curApnCtx);
2499cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                }
2500ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                return curDcac;
2501ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            case RETRYING:
2502cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            case CONNECTING:
2503ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                potentialDcac = curDcac;
2504ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                potentialApnCtx = curApnCtx;
2505cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            default:
2506cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // Not connected, potential unchanged
2507cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                break;
2508cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
2509cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2510cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else if (apnSetting != null && apnSetting.canHandleType(apnType)) {
2511ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    switch (curApnCtx.getState()) {
2512cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        case CONNECTED:
2513cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            if (DBG) {
2514ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                log("checkForCompatibleConnectedApnContext:"
2515ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        + " found canHandle conn=" + curDcac
2516ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        + " curApnCtx=" + curApnCtx);
2517cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            }
2518ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            return curDcac;
2519ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        case RETRYING:
2520cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        case CONNECTING:
2521ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            potentialDcac = curDcac;
2522ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            potentialApnCtx = curApnCtx;
2523cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        default:
2524cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            // Not connected, potential unchanged
2525cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            break;
2526cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2527cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2528ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            } else {
2529ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) {
2530ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    log("checkForCompatibleConnectedApnContext: not conn curApnCtx=" + curApnCtx);
2531ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                }
2532cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2533cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2534ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (potentialDcac != null) {
2535cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
2536ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                log("checkForCompatibleConnectedApnContext: found potential conn=" + potentialDcac
2537ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        + " curApnCtx=" + potentialApnCtx);
2538cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2539ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            return potentialDcac;
2540cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2541c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2542ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("checkForCompatibleConnectedApnContext: NO conn apnContext=" + apnContext);
2543cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
2544cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2545c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
254627b650c406018355a88a41528db7859e232728a0Jack Yu    public void setEnabled(int id, boolean enable) {
25471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_ENABLE_NEW_APN);
25481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = id;
25491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg2 = (enable ? DctConstants.ENABLED : DctConstants.DISABLED);
25501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
25511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
25521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
25531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onEnableApn(int apnId, int enabled) {
2554af5593594070f825032be46dced573cd195956e1Robert Greenwalt        ApnContext apnContext = mApnContextsById.get(apnId);
2555cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
2556cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onEnableApn(" + apnId + ", " + enabled + "): NO ApnContext");
2557cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
2558cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2559cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO change our retry manager to use the appropriate numbers for the new APN
2560cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onEnableApn: apnContext=" + apnContext + " call applyNewState");
2561cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        applyNewState(apnContext, enabled == DctConstants.ENABLED, apnContext.getDependencyMet());
2562af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla
2563af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla        if ((enabled == DctConstants.DISABLED) &&
2564af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology()) &&
2565af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            !isHigherPriorityApnContextActive(apnContext)) {
2566af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla
2567af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            if(DBG) log("onEnableApn: isOnlySingleDcAllowed true & higher priority APN disabled");
2568af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            // If the highest priority APN is disabled and only single
2569af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            // data call is allowed, try to setup data call on other connectable APN.
2570af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            setupDataOnConnectableApns(Phone.REASON_SINGLE_PDN_ARBITRATION);
2571af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla        }
2572cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2573c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2574cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // TODO: We shouldnt need this.
25751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean onTrySetupData(String reason) {
2576cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onTrySetupData: reason=" + reason);
2577ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(reason);
2578cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
2579cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2580c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
25811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean onTrySetupData(ApnContext apnContext) {
2582cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onTrySetupData: apnContext=" + apnContext);
2583cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return trySetupData(apnContext);
2584cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2585c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
25861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
25871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Return current {@link android.provider.Settings.Global#MOBILE_DATA} value.
25881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
2589a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    //TODO: Merge this into DataSettings. And probably should rename to getUserDataEnabled().
25901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public boolean getDataEnabled() {
2591f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        final int device_provisioned =
2592f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                Settings.Global.getInt(mResolver, Settings.Global.DEVICE_PROVISIONED, 0);
2593f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
25941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        boolean retVal = "true".equalsIgnoreCase(SystemProperties.get(
25951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                "ro.com.android.mobiledata", "true"));
2596f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        if (TelephonyManager.getDefault().getSimCount() == 1) {
2597f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            retVal = Settings.Global.getInt(mResolver, Settings.Global.MOBILE_DATA,
2598f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                    retVal ? 1 : 0) != 0;
2599f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        } else {
2600f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            int phoneSubId = mPhone.getSubId();
2601f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            try {
2602f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                retVal = TelephonyManager.getIntWithSubId(mResolver,
2603f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                        Settings.Global.MOBILE_DATA, phoneSubId) != 0;
2604f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            } catch (SettingNotFoundException e) {
2605f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                // use existing retVal
2606f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            }
2607f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        }
2608f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        if (VDBG) log("getDataEnabled: retVal=" + retVal);
2609f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        if (device_provisioned == 0) {
2610f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            // device is still getting provisioned - use whatever setting they
2611f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            // want during this process
2612f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            //
2613f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            // use the normal data_enabled setting (retVal, determined above)
2614f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            // as the default if nothing else is set
2615f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            final String prov_property = SystemProperties.get("ro.com.android.prov_mobiledata",
2616f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                  retVal ? "true" : "false");
2617f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            retVal = "true".equalsIgnoreCase(prov_property);
2618f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
2619f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            final int prov_mobile_data = Settings.Global.getInt(mResolver,
2620f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                    Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED,
2621f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                    retVal ? 1 : 0);
2622f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            retVal = prov_mobile_data != 0;
2623f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            log("getDataEnabled during provisioning retVal=" + retVal + " - (" + prov_property +
2624f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                    ", " + prov_mobile_data + ")");
26251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
2626f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
26271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return retVal;
26281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
26291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
26301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
263121e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * Modify {@link android.provider.Settings.Global#DATA_ROAMING} value for user modification only
26321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
263321e6af8d6197a071d025733fffeffc157d0085bcfionaxu    public void setDataRoamingEnabledByUser(boolean enabled) {
26341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        final int phoneSubId = mPhone.getSubId();
26355b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (getDataRoamingEnabled() != enabled) {
26361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            int roaming = enabled ? 1 : 0;
26371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
26381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // For single SIM phones, this is a per phone property.
26391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (TelephonyManager.getDefault().getSimCount() == 1) {
26401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Settings.Global.putInt(mResolver, Settings.Global.DATA_ROAMING, roaming);
264121e6af8d6197a071d025733fffeffc157d0085bcfionaxu                setDataRoamingFromUserAction(true);
26421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
26431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Settings.Global.putInt(mResolver, Settings.Global.DATA_ROAMING +
26441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                         phoneSubId, roaming);
26451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
26461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
26471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSubscriptionManager.setDataRoaming(roaming, phoneSubId);
26481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // will trigger handleDataOnRoamingChange() through observer
26491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
265021e6af8d6197a071d025733fffeffc157d0085bcfionaxu                log("setDataRoamingEnabledByUser: set phoneSubId=" + phoneSubId
26515b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu                        + " isRoaming=" + enabled);
26521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
26531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
26541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
265521e6af8d6197a071d025733fffeffc157d0085bcfionaxu                log("setDataRoamingEnabledByUser: unchanged phoneSubId=" + phoneSubId
26561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        + " isRoaming=" + enabled);
26571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu             }
26581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
26591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
26601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
26611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
26621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Return current {@link android.provider.Settings.Global#DATA_ROAMING} value.
26631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
26645b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    public boolean getDataRoamingEnabled() {
266521e6af8d6197a071d025733fffeffc157d0085bcfionaxu        boolean isDataRoamingEnabled;
26661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        final int phoneSubId = mPhone.getSubId();
26671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
26681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        try {
26691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // For single SIM phones, this is a per phone property.
26701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (TelephonyManager.getDefault().getSimCount() == 1) {
26711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                isDataRoamingEnabled = Settings.Global.getInt(mResolver,
267221e6af8d6197a071d025733fffeffc157d0085bcfionaxu                        Settings.Global.DATA_ROAMING, getDefaultDataRoamingEnabled() ? 1 : 0) != 0;
26731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
26741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                isDataRoamingEnabled = TelephonyManager.getIntWithSubId(mResolver,
26751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.DATA_ROAMING, phoneSubId) != 0;
26761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
26771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } catch (SettingNotFoundException snfe) {
26785b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            if (DBG) log("getDataRoamingEnabled: SettingNofFoundException snfe=" + snfe);
267921e6af8d6197a071d025733fffeffc157d0085bcfionaxu            isDataRoamingEnabled = getDefaultDataRoamingEnabled();
26801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
26811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) {
26825b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            log("getDataRoamingEnabled: phoneSubId=" + phoneSubId
26835b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu                    + " isDataRoamingEnabled=" + isDataRoamingEnabled);
26841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
26851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return isDataRoamingEnabled;
26861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
26871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
268821e6af8d6197a071d025733fffeffc157d0085bcfionaxu    /**
268921e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * get default values for {@link Settings.Global#DATA_ROAMING}
269021e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * return {@code true} if either
269121e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} or
269221e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * system property ro.com.android.dataroaming is set to true. otherwise return {@code false}
269321e6af8d6197a071d025733fffeffc157d0085bcfionaxu     */
269421e6af8d6197a071d025733fffeffc157d0085bcfionaxu    private boolean getDefaultDataRoamingEnabled() {
269521e6af8d6197a071d025733fffeffc157d0085bcfionaxu        final CarrierConfigManager configMgr = (CarrierConfigManager)
269621e6af8d6197a071d025733fffeffc157d0085bcfionaxu                mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
269721e6af8d6197a071d025733fffeffc157d0085bcfionaxu        boolean isDataRoamingEnabled = "true".equalsIgnoreCase(SystemProperties.get(
269821e6af8d6197a071d025733fffeffc157d0085bcfionaxu                "ro.com.android.dataroaming", "false"));
269921e6af8d6197a071d025733fffeffc157d0085bcfionaxu        isDataRoamingEnabled |= configMgr.getConfigForSubId(mPhone.getSubId()).getBoolean(
270021e6af8d6197a071d025733fffeffc157d0085bcfionaxu                CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
270121e6af8d6197a071d025733fffeffc157d0085bcfionaxu        return isDataRoamingEnabled;
270221e6af8d6197a071d025733fffeffc157d0085bcfionaxu    }
270321e6af8d6197a071d025733fffeffc157d0085bcfionaxu
270421e6af8d6197a071d025733fffeffc157d0085bcfionaxu    /**
270521e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * Set default value for {@link android.provider.Settings.Global#DATA_ROAMING}
270621e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * if the setting is not from user actions. default value is based on carrier config and system
270721e6af8d6197a071d025733fffeffc157d0085bcfionaxu     * properties.
270821e6af8d6197a071d025733fffeffc157d0085bcfionaxu     */
270921e6af8d6197a071d025733fffeffc157d0085bcfionaxu    private void setDefaultDataRoamingEnabled() {
271021e6af8d6197a071d025733fffeffc157d0085bcfionaxu        // For single SIM phones, this is a per phone property.
271121e6af8d6197a071d025733fffeffc157d0085bcfionaxu        String setting = Settings.Global.DATA_ROAMING;
271221e6af8d6197a071d025733fffeffc157d0085bcfionaxu        boolean useCarrierSpecificDefault = false;
271321e6af8d6197a071d025733fffeffc157d0085bcfionaxu        if (TelephonyManager.getDefault().getSimCount() != 1) {
271421e6af8d6197a071d025733fffeffc157d0085bcfionaxu            setting = setting + mPhone.getSubId();
271521e6af8d6197a071d025733fffeffc157d0085bcfionaxu            try {
271621e6af8d6197a071d025733fffeffc157d0085bcfionaxu                Settings.Global.getInt(mResolver, setting);
271721e6af8d6197a071d025733fffeffc157d0085bcfionaxu            } catch (SettingNotFoundException ex) {
271821e6af8d6197a071d025733fffeffc157d0085bcfionaxu                // For msim, update to carrier default if uninitialized.
271921e6af8d6197a071d025733fffeffc157d0085bcfionaxu                useCarrierSpecificDefault = true;
272021e6af8d6197a071d025733fffeffc157d0085bcfionaxu            }
272121e6af8d6197a071d025733fffeffc157d0085bcfionaxu        } else if (!isDataRoamingFromUserAction()) {
272221e6af8d6197a071d025733fffeffc157d0085bcfionaxu            // for single sim device, update to carrier default if user action is not set
272321e6af8d6197a071d025733fffeffc157d0085bcfionaxu            useCarrierSpecificDefault = true;
272421e6af8d6197a071d025733fffeffc157d0085bcfionaxu        }
272521e6af8d6197a071d025733fffeffc157d0085bcfionaxu        if (useCarrierSpecificDefault) {
272621e6af8d6197a071d025733fffeffc157d0085bcfionaxu            boolean defaultVal = getDefaultDataRoamingEnabled();
272721e6af8d6197a071d025733fffeffc157d0085bcfionaxu            log("setDefaultDataRoamingEnabled: " + setting + "default value: " + defaultVal);
272821e6af8d6197a071d025733fffeffc157d0085bcfionaxu            Settings.Global.putInt(mResolver, setting, defaultVal ? 1 : 0);
272921e6af8d6197a071d025733fffeffc157d0085bcfionaxu            mSubscriptionManager.setDataRoaming(defaultVal ? 1 : 0, mPhone.getSubId());
273021e6af8d6197a071d025733fffeffc157d0085bcfionaxu        }
273121e6af8d6197a071d025733fffeffc157d0085bcfionaxu    }
273221e6af8d6197a071d025733fffeffc157d0085bcfionaxu
273321e6af8d6197a071d025733fffeffc157d0085bcfionaxu    private boolean isDataRoamingFromUserAction() {
273421e6af8d6197a071d025733fffeffc157d0085bcfionaxu        final SharedPreferences sp = PreferenceManager
273521e6af8d6197a071d025733fffeffc157d0085bcfionaxu                .getDefaultSharedPreferences(mPhone.getContext());
273621e6af8d6197a071d025733fffeffc157d0085bcfionaxu        // since we don't want to unset user preference from system update, pass true as the default
273721e6af8d6197a071d025733fffeffc157d0085bcfionaxu        // value if shared pref does not exist and set shared pref to false explicitly from factory
273821e6af8d6197a071d025733fffeffc157d0085bcfionaxu        // reset.
273921e6af8d6197a071d025733fffeffc157d0085bcfionaxu        if (!sp.contains(Phone.DATA_ROAMING_IS_USER_SETTING_KEY)
274021e6af8d6197a071d025733fffeffc157d0085bcfionaxu                && Settings.Global.getInt(mResolver, Settings.Global.DEVICE_PROVISIONED, 0) == 0) {
274121e6af8d6197a071d025733fffeffc157d0085bcfionaxu            sp.edit().putBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, false).commit();
274221e6af8d6197a071d025733fffeffc157d0085bcfionaxu        }
274321e6af8d6197a071d025733fffeffc157d0085bcfionaxu        return sp.getBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, true);
274421e6af8d6197a071d025733fffeffc157d0085bcfionaxu    }
274521e6af8d6197a071d025733fffeffc157d0085bcfionaxu
274621e6af8d6197a071d025733fffeffc157d0085bcfionaxu    private void setDataRoamingFromUserAction(boolean isUserAction) {
274721e6af8d6197a071d025733fffeffc157d0085bcfionaxu        final SharedPreferences.Editor sp = PreferenceManager
274821e6af8d6197a071d025733fffeffc157d0085bcfionaxu                .getDefaultSharedPreferences(mPhone.getContext()).edit();
274921e6af8d6197a071d025733fffeffc157d0085bcfionaxu        sp.putBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, isUserAction).commit();
275021e6af8d6197a071d025733fffeffc157d0085bcfionaxu    }
275121e6af8d6197a071d025733fffeffc157d0085bcfionaxu
27525b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    // When the data roaming status changes from roaming to non-roaming.
27535b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    private void onDataRoamingOff() {
27545b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (DBG) log("onDataRoamingOff");
2755c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
27565b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (!getDataRoamingEnabled()) {
27575b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // TODO: Remove this once all old vendor RILs are gone. We don't need to set initial apn
27585b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // attach and send the data profile again as the modem should have both roaming and
27595b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // non-roaming protocol in place. Modem should choose the right protocol based on the
27605b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // roaming condition.
27615b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            setInitialAttachApn();
27625b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            setDataProfilesAsNeeded();
27638e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu
27645b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // If the user did not enable data roaming, now when we transit from roaming to
27655b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // non-roaming, we should try to reestablish the data connection.
2766c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2767cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_OFF);
2768bda761320929f714951c328bfec6a51a1978db97Wink Saville            setupDataOnConnectableApns(Phone.REASON_ROAMING_OFF);
2769cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2770cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_ROAMING_OFF);
2771cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2772cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2773cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
27745b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    // This method is called
27755b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    // 1. When the data roaming status changes from non-roaming to roaming.
27765b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    // 2. When allowed data roaming settings is changed by the user.
27775b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    private void onDataRoamingOnOrSettingsChanged() {
27785b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (DBG) log("onDataRoamingOnOrSettingsChanged");
2779f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu
2780f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu        // Check if the device is actually data roaming
2781f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu        if (!mPhone.getServiceState().getDataRoaming()) {
2782f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu            if (DBG) log("device is not roaming. ignored the request.");
2783f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu            return;
2784f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu        }
2785cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
27865b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (getDataRoamingEnabled()) {
27875b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            if (DBG) log("onDataRoamingOnOrSettingsChanged: setup data on roaming");
27885b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu
2789ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_ROAMING_ON);
2790cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_ROAMING_ON);
2791cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
27925b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // If the user does not turn on data roaming, when we transit from non-roaming to
27935b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // roaming, we need to tear down the data connection otherwise the user might be
27945b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // charged for data roaming usage.
27955b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            if (DBG) log("onDataRoamingOnOrSettingsChanged: Tear down data connection on roaming.");
2796cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpAllConnections(true, Phone.REASON_ROAMING_ON);
2797cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
2798cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2799cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2800cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
28011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRadioAvailable() {
2802cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onRadioAvailable");
2803cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
2804cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
2805cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
2806cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // setState(DctConstants.State.CONNECTED);
2807cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(null);
2808cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2809cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("onRadioAvailable: We're on the simulator; assuming data is connected");
2810cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2811cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2812cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
2813cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (r != null && r.getRecordsLoaded()) {
2814cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(null);
2815cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2816cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2817cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getOverallState() != DctConstants.State.IDLE) {
2818cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpConnection(true, null);
2819cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2820cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2821cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
28221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRadioOffOrNotAvailable() {
2823cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Make sure our reconnect delay starts at the initial value
2824cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // next time the radio comes on
2825cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2826cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mReregisterOnReconnectFailure = false;
2827cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
28287e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C        // Clear auto attach as modem is expected to do a new attach
28297e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C        mAutoAttachOnCreation.set(false);
28307e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C
2831cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
2832cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
2833cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
2834cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("We're on the simulator; assuming radio off is meaningless");
2835cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2836cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRadioOffOrNotAvailable: is off and clean up all connections");
2837cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpAllConnections(false, Phone.REASON_RADIO_TURNED_OFF);
2838cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2839cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyOffApnsOfAvailability(null);
2840cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2841cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
28421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void completeConnection(ApnContext apnContext) {
2843c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2844c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (DBG) log("completeConnection: successful, notify the world apnContext=" + apnContext);
2845c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2846c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (mIsProvisioning && !TextUtils.isEmpty(mProvisioningUrl)) {
2847c9b81a0c05128694c617fcdd67e73821895822feWink Saville            if (DBG) {
2848c9b81a0c05128694c617fcdd67e73821895822feWink Saville                log("completeConnection: MOBILE_PROVISIONING_ACTION url="
2849c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        + mProvisioningUrl);
2850c9b81a0c05128694c617fcdd67e73821895822feWink Saville            }
2851c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt            Intent newIntent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN,
2852c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt                    Intent.CATEGORY_APP_BROWSER);
2853c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt            newIntent.setData(Uri.parse(mProvisioningUrl));
2854c9b81a0c05128694c617fcdd67e73821895822feWink Saville            newIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
2855c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    Intent.FLAG_ACTIVITY_NEW_TASK);
2856c9b81a0c05128694c617fcdd67e73821895822feWink Saville            try {
2857c9b81a0c05128694c617fcdd67e73821895822feWink Saville                mPhone.getContext().startActivity(newIntent);
2858c9b81a0c05128694c617fcdd67e73821895822feWink Saville            } catch (ActivityNotFoundException e) {
2859c9b81a0c05128694c617fcdd67e73821895822feWink Saville                loge("completeConnection: startActivityAsUser failed" + e);
2860c9b81a0c05128694c617fcdd67e73821895822feWink Saville            }
2861c9b81a0c05128694c617fcdd67e73821895822feWink Saville        }
2862c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mIsProvisioning = false;
2863c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mProvisioningUrl = null;
28642b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        if (mProvisioningSpinner != null) {
28652b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            sendMessage(obtainMessage(DctConstants.CMD_CLEAR_PROVISIONING_SPINNER,
28662b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner));
28672b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        }
2868c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2869c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
2870c9b81a0c05128694c617fcdd67e73821895822feWink Saville        startNetStatPoll();
2871c9b81a0c05128694c617fcdd67e73821895822feWink Saville        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
2872c9b81a0c05128694c617fcdd67e73821895822feWink Saville    }
2873c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2874ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
2875ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * A SETUP (aka bringUp) has completed, possibly with an error. If
2876ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * there is an error this method will call {@link #onDataSetupCompleteError}.
2877ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
28781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataSetupComplete(AsyncResult ar) {
2879608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt
2880ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        DcFailCause cause = DcFailCause.UNKNOWN;
2881cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean handleError = false;
2882ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDataSetupComplete");
2883cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2884ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
2885cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2886cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (ar.exception == null) {
2887454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = apnContext.getDcAc();
2888cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2889cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (RADIO_TESTS) {
2890cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Note: To change radio.test.onDSC.null.dcac from command line you need to
2891cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // adb root and adb remount and from the command line you can only change the
2892cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // value to 1 once. To change it a second time you can reboot or execute
2893cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // adb shell stop and then adb shell start. The command line to set the value is:
2894ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink 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');"
2895cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ContentResolver cr = mPhone.getContext().getContentResolver();
2896cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                String radioTestProperty = "radio.test.onDSC.null.dcac";
2897cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (Settings.System.getInt(cr, radioTestProperty, 0) == 1) {
2898cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: " + radioTestProperty +
2899cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            " is true, set dcac to null and reset property to false");
2900cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    dcac = null;
2901cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    Settings.System.putInt(cr, radioTestProperty, 0);
2902cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: " + radioTestProperty + "=" +
2903cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            Settings.System.getInt(mPhone.getContext().getContentResolver(),
2904cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                    radioTestProperty, -1));
2905cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2906c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2907cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac == null) {
2908cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("onDataSetupComplete: no connection to DC, handle as error");
2909ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                cause = DcFailCause.CONNECTION_TO_DATACONNECTIONAC_BROKEN;
2910cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                handleError = true;
2911cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
2912cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ApnSetting apn = apnContext.getApnSetting();
2913cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
2914cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: success apn=" + (apn == null ? "unknown" : apn.apn));
2915cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2916cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn != null && apn.proxy != null && apn.proxy.length() != 0) {
2917cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    try {
2918cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        String port = apn.port;
2919cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (TextUtils.isEmpty(port)) port = "8080";
29209c180aedfc9f0d20525c0128487d3500e6c0a715Jason Monk                        ProxyInfo proxy = new ProxyInfo(apn.proxy,
2921cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                Integer.parseInt(port), null);
2922cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        dcac.setLinkPropertiesHttpProxySync(proxy);
2923cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    } catch (NumberFormatException e) {
2924cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        loge("onDataSetupComplete: NumberFormatException making ProxyProperties (" +
2925cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                apn.port + "): " + e);
2926cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2927cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2928cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2929cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // everything is setup
2930cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if(TextUtils.equals(apnContext.getApnType(),PhoneConstants.APN_TYPE_DEFAULT)) {
293127b650c406018355a88a41528db7859e232728a0Jack Yu                    try {
293227b650c406018355a88a41528db7859e232728a0Jack Yu                        SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "true");
293327b650c406018355a88a41528db7859e232728a0Jack Yu                    } catch (RuntimeException ex) {
293427b650c406018355a88a41528db7859e232728a0Jack Yu                        log("Failed to set PUPPET_MASTER_RADIO_STRESS_TEST to true");
293527b650c406018355a88a41528db7859e232728a0Jack Yu                    }
293622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mCanSetPreferApn && mPreferredApn == null) {
29370e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                        if (DBG) log("onDataSetupComplete: PREFERRED APN is null");
2938cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mPreferredApn = apn;
2939cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (mPreferredApn != null) {
2940cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            setPreferredApn(mPreferredApn.id);
2941cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
2942cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2943cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
294427b650c406018355a88a41528db7859e232728a0Jack Yu                    try {
294527b650c406018355a88a41528db7859e232728a0Jack Yu                        SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
294627b650c406018355a88a41528db7859e232728a0Jack Yu                    } catch (RuntimeException ex) {
294727b650c406018355a88a41528db7859e232728a0Jack Yu                        log("Failed to set PUPPET_MASTER_RADIO_STRESS_TEST to false");
294827b650c406018355a88a41528db7859e232728a0Jack Yu                    }
2949cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2950c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2951c9b81a0c05128694c617fcdd67e73821895822feWink Saville                // A connection is setup
2952c9b81a0c05128694c617fcdd67e73821895822feWink Saville                apnContext.setState(DctConstants.State.CONNECTED);
29530e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
2954c9b81a0c05128694c617fcdd67e73821895822feWink Saville                boolean isProvApn = apnContext.isProvisioningApn();
2955b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                final ConnectivityManager cm = ConnectivityManager.from(mPhone.getContext());
2956b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                if (mProvisionBroadcastReceiver != null) {
2957b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mPhone.getContext().unregisterReceiver(mProvisionBroadcastReceiver);
2958b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mProvisionBroadcastReceiver = null;
2959b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                }
2960c9b81a0c05128694c617fcdd67e73821895822feWink Saville                if ((!isProvApn) || mIsProvisioning) {
2961b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // Hide any provisioning notification.
2962b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    cm.setProvisioningNotificationVisible(false, ConnectivityManager.TYPE_MOBILE,
2963b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                            mProvisionActionName);
2964c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // Complete the connection normally notifying the world we're connected.
2965c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // We do this if this isn't a special provisioning apn or if we've been
2966c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // told its time to provision.
2967c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    completeConnection(apnContext);
2968c9b81a0c05128694c617fcdd67e73821895822feWink Saville                } else {
2969c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // This is a provisioning APN that we're reporting as connected. Later
2970c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // when the user desires to upgrade this to a "default" connection,
2971c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // mIsProvisioning == true, we'll go through the code path above.
2972c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // mIsProvisioning becomes true when CMD_ENABLE_MOBILE_PROVISIONING
2973c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // is sent to the DCT.
2974c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    if (DBG) {
2975c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        log("onDataSetupComplete: successful, BUT send connected to prov apn as"
2976c9b81a0c05128694c617fcdd67e73821895822feWink Saville                                + " mIsProvisioning:" + mIsProvisioning + " == false"
2977c9b81a0c05128694c617fcdd67e73821895822feWink Saville                                + " && (isProvisioningApn:" + isProvApn + " == true");
2978c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    }
2979c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2980b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // While radio is up, grab provisioning URL.  The URL contains ICCID which
2981b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // disappears when radio is off.
2982b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mProvisionBroadcastReceiver = new ProvisionNotificationBroadcastReceiver(
29832b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                            cm.getMobileProvisioningUrl(),
29842b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                            TelephonyManager.getDefault().getNetworkOperatorName());
2985b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mPhone.getContext().registerReceiver(mProvisionBroadcastReceiver,
2986b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                            new IntentFilter(mProvisionActionName));
2987b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // Put up user notification that sign-in is required.
2988b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    cm.setProvisioningNotificationVisible(true, ConnectivityManager.TYPE_MOBILE,
2989b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                            mProvisionActionName);
2990b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // Turn off radio to save battery and avoid wasting carrier resources.
2991b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // The network isn't usable and network validation will just fail anyhow.
2992b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    setRadio(false);
2993c9b81a0c05128694c617fcdd67e73821895822feWink Saville                }
2994c9b81a0c05128694c617fcdd67e73821895822feWink Saville                if (DBG) {
2995c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    log("onDataSetupComplete: SETUP complete type=" + apnContext.getApnType()
2996c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        + ", reason:" + apnContext.getReason());
2997c9b81a0c05128694c617fcdd67e73821895822feWink Saville                }
29984c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                if (Build.IS_DEBUGGABLE) {
29994c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                    // adb shell setprop persist.radio.test.pco [pco_val]
30004c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                    String radioTestProperty = "persist.radio.test.pco";
3001cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    int pcoVal = SystemProperties.getInt(radioTestProperty, -1);
3002cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    if (pcoVal != -1) {
3003cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        log("PCO testing: read pco value from persist.radio.test.pco " + pcoVal);
3004cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        final byte[] value = new byte[1];
3005cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        value[0] = (byte) pcoVal;
3006cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        final Intent intent =
3007cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                                new Intent(TelephonyIntents.ACTION_CARRIER_SIGNAL_PCO_VALUE);
3008cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        intent.putExtra(TelephonyIntents.EXTRA_APN_TYPE_KEY, "default");
3009cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        intent.putExtra(TelephonyIntents.EXTRA_APN_PROTO_KEY, "IPV4V6");
3010cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        intent.putExtra(TelephonyIntents.EXTRA_PCO_ID_KEY, 0xFF00);
3011cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        intent.putExtra(TelephonyIntents.EXTRA_PCO_VALUE_KEY, value);
3012cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
3013cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    }
30144c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                }
3015c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3016cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
3017ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            cause = (DcFailCause) (ar.result);
3018cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
3019cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ApnSetting apn = apnContext.getApnSetting();
3020cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log(String.format("onDataSetupComplete: error apn=%s cause=%s",
3021cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        (apn == null ? "unknown" : apn.apn), cause));
3022c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3023cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cause.isEventLoggable()) {
3024cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Log this failure to the Event Logs.
3025cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                int cid = getCellLocationId();
3026cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                EventLog.writeEvent(EventLogTags.PDP_SETUP_FAIL,
3027cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        cause.ordinal(), cid, TelephonyManager.getDefault().getNetworkType());
3028c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
30290742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela            ApnSetting apn = apnContext.getApnSetting();
30300742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela            mPhone.notifyPreciseDataConnectionFailed(apnContext.getReason(),
30310742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela                    apnContext.getApnType(), apn != null ? apn.apn : "unknown", cause.toString());
3032cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
30334c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            // Compose broadcast intent send to the specific carrier signaling receivers
30344c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            Intent intent = new Intent(TelephonyIntents
30354c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                    .ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED);
30364c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            intent.putExtra(TelephonyIntents.EXTRA_ERROR_CODE_KEY, cause.getErrorCode());
30374c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            intent.putExtra(TelephonyIntents.EXTRA_APN_TYPE_KEY, apnContext.getApnType());
30384c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
3039a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
304031f84bf1a4f1c945f7ca4646095ef4717a261c98Jordan Liu            if (cause.isRestartRadioFail(mPhone.getContext(), mPhone.getSubId()) ||
304131f84bf1a4f1c945f7ca4646095ef4717a261c98Jordan Liu                    apnContext.restartOnError(cause.getErrorCode())) {
30420e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                if (DBG) log("Modem restarted.");
30430e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                sendRestartRadio();
30440e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            }
3045cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
30460e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // If the data call failure cause is a permanent failure, we mark the APN as permanent
30470e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // failed.
3048ccfe5ebaf81c1378e8dbe44e45df26b0dc462a21Jack Yu            if (isPermanentFailure(cause)) {
30490e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                log("cause = " + cause + ", mark apn as permanent failed. apn = " + apn);
30500e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                apnContext.markApnPermanentFailed(apn);
3051c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
30520e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
3053cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            handleError = true;
3054cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3055cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3056cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (handleError) {
3057ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            onDataSetupCompleteError(ar);
3058ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
3059a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3060a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        /* If flag is set to false after SETUP_DATA_CALL is invoked, we need
3061a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         * to clean data connections.
3062a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         */
3063a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        if (!mDataEnabledSettings.isInternalDataEnabled()) {
30644fdc57b9bf223c908474c4545cc6f63456117a3bSanket Padawe            cleanUpAllConnections(Phone.REASON_DATA_DISABLED);
3065a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
3066a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3067ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
3068cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3069ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
3070ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt     * check for obsolete messages.  Return ApnContext if valid, null if not
3071ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt     */
3072ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt    private ApnContext getValidApnContext(AsyncResult ar, String logString) {
3073ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (ar != null && ar.userObj instanceof Pair) {
3074ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            Pair<ApnContext, Integer>pair = (Pair<ApnContext, Integer>)ar.userObj;
3075ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            ApnContext apnContext = pair.first;
3076ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            if (apnContext != null) {
30771a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                final int generation = apnContext.getConnectionGeneration();
30781a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                if (DBG) {
30791a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                    log("getValidApnContext (" + logString + ") on " + apnContext + " got " +
30801a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                            generation + " vs " + pair.second);
30811a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                }
30821a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                if (generation == pair.second) {
3083ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                    return apnContext;
3084ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                } else {
3085ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                    log("ignoring obsolete " + logString);
3086ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                    return null;
3087ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                }
3088ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            }
3089ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        }
3090ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        throw new RuntimeException(logString + ": No apnContext");
3091ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt    }
3092ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt
3093ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt    /**
3094ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Error has occurred during the SETUP {aka bringUP} request and the DCT
3095ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * should either try the next waiting APN or start over from the
3096ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * beginning if the list is empty. Between each SETUP request there will
3097ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville     * be a delay defined by {@link #getApnDelay()}.
3098ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
30991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataSetupCompleteError(AsyncResult ar) {
31000e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
3101ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDataSetupCompleteError");
3102ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3103ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
3104ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
31050e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        long delay = apnContext.getDelayForNextApn(mFailFast);
3106ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
31070e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        // Check if we need to retry or not.
31080852a954be5937a1b0bca94df0c2007d7ee3c0c7Jack Yu        if (delay >= 0) {
31090e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (DBG) log("onDataSetupCompleteError: Try next APN. delay = " + delay);
3110ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext.setState(DctConstants.State.SCANNING);
3111ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // Wait a bit before trying the next APN, so that
3112ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // we're not tying up the RIL command channel
31130e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            startAlarmForReconnect(delay, apnContext);
31140e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        } else {
31150e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // If we are not going to retry any APN, set this APN context to failed state.
31160e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // This would be the final state of a data connection.
31170e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            apnContext.setState(DctConstants.State.FAILED);
31180e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType());
31190e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            apnContext.setDataConnectionAc(null);
31200e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            log("onDataSetupCompleteError: Stop retrying APNs.");
3121c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3122c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3123c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3124c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
3125a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu     * Called when EVENT_REDIRECTION_DETECTED is received.
3126a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu     */
31274c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu    private void onDataConnectionRedirected(String redirectUrl) {
3128a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        if (!TextUtils.isEmpty(redirectUrl)) {
31294c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            Intent intent = new Intent(TelephonyIntents.ACTION_CARRIER_SIGNAL_REDIRECTED);
31304c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            intent.putExtra(TelephonyIntents.EXTRA_REDIRECTION_URL_KEY, redirectUrl);
31316a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu            mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
31326a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu            log("Notify carrier signal receivers with redirectUrl: " + redirectUrl);
3133a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        }
3134a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    }
3135a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
3136a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    /**
3137cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Called when EVENT_DISCONNECT_DONE is received.
3138c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
31391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDisconnectDone(AsyncResult ar) {
3140ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDisconnectDone");
3141ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
3142c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3143cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE apnContext=" + apnContext);
3144cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setState(DctConstants.State.IDLE);
3145cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3146cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
3147cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3148cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // if all data connection are gone, check whether Airplane mode request was
3149cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // pending.
3150cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isDisconnected()) {
3151cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPhone.getServiceStateTracker().processPendingRadioPowerOffAfterDataOff()) {
3152a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                if (DBG) log("onDisconnectDone: radio will be turned off, no retries");
3153cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Radio will be turned off. No need to retry data setup
3154cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setApnSetting(null);
3155cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setDataConnectionAc(null);
3156a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3157a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // Need to notify disconnect as well, in the case of switching Airplane mode.
3158a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // Otherwise, it would cause 30s delayed to turn on Airplane mode.
31590e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                if (mDisconnectPendingCount > 0) {
3160a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mDisconnectPendingCount--;
31610e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                }
3162a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3163a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mDisconnectPendingCount == 0) {
3164a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    notifyDataDisconnectComplete();
3165a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    notifyAllDataDisconnected();
3166a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
3167cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return;
3168cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3169c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3170cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // If APN is still enabled, try to bring it back up automatically
31713fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (mAttached.get() && apnContext.isReady() && retryAfterDisconnected(apnContext)) {
317227b650c406018355a88a41528db7859e232728a0Jack Yu            try {
317327b650c406018355a88a41528db7859e232728a0Jack Yu                SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
317427b650c406018355a88a41528db7859e232728a0Jack Yu            } catch (RuntimeException ex) {
317527b650c406018355a88a41528db7859e232728a0Jack Yu                log("Failed to set PUPPET_MASTER_RADIO_STRESS_TEST to false");
317627b650c406018355a88a41528db7859e232728a0Jack Yu            }
3177cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Wait a bit before trying the next APN, so that
3178cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // we're not tying up the RIL command channel.
3179cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // This also helps in any external dependency to turn off the context.
31800e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (DBG) log("onDisconnectDone: attached, ready and retry after disconnect");
3181da21f0de2087657b20b18817b33d59778720bffbJack Yu            long delay = apnContext.getRetryAfterDisconnectDelay();
31820e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (delay > 0) {
31830e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                // Data connection is in IDLE state, so when we reconnect later, we'll rebuild
31840e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                // the waiting APN list, which will also reset/reconfigure the retry manager.
31850e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                startAlarmForReconnect(delay, apnContext);
31860e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            }
3187c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
3188449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            boolean restartRadioAfterProvisioning = mPhone.getContext().getResources().getBoolean(
3189449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                    com.android.internal.R.bool.config_restartRadioAfterProvisioning);
3190449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville
3191449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            if (apnContext.isProvisioningApn() && restartRadioAfterProvisioning) {
3192449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                log("onDisconnectDone: restartRadio after provisioning");
3193449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                restartRadio();
3194449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            }
3195cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setApnSetting(null);
3196cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setDataConnectionAc(null);
31973fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())) {
3198449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                if(DBG) log("onDisconnectDone: isOnlySigneDcAllowed true so setup single apn");
31993fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                setupDataOnConnectableApns(Phone.REASON_SINGLE_PDN_ARBITRATION);
3200449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            } else {
3201449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                if(DBG) log("onDisconnectDone: not retrying");
32023fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
3203c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3204a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3205a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mDisconnectPendingCount > 0)
3206a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mDisconnectPendingCount--;
3207a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3208a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mDisconnectPendingCount == 0) {
3209c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt            apnContext.setConcurrentVoiceAndDataAllowed(
3210c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed());
3211a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyDataDisconnectComplete();
3212a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
3213a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
3214a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3215c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3216c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3217ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
3218ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Called when EVENT_DISCONNECT_DC_RETRYING is received.
3219ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
32201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDisconnectDcRetrying(AsyncResult ar) {
3221ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // We could just do this in DC!!!
3222ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDisconnectDcRetrying");
3223ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
3224ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3225ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setState(DctConstants.State.RETRYING);
3226ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if(DBG) log("onDisconnectDcRetrying: apnContext=" + apnContext);
3227ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3228ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
3229ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
3230ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
32311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onVoiceCallStarted() {
3232cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onVoiceCallStarted");
3233ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        mInVoiceCall = true;
3234cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnected() && ! mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
3235cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onVoiceCallStarted stop polling");
3236cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            stopNetStatPoll();
3237cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            stopDataStallAlarm();
3238cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
3239c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3240c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3241c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onVoiceCallEnded() {
3243cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onVoiceCallEnded");
3244ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        mInVoiceCall = false;
3245cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnected()) {
3246cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
3247cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                startNetStatPoll();
3248cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
3249cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
3250cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
3251cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // clean slate after call end.
3252cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                resetPollStats();
3253c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3254c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3255bda761320929f714951c328bfec6a51a1978db97Wink Saville        // reset reconnect timer
3256bda761320929f714951c328bfec6a51a1978db97Wink Saville        setupDataOnConnectableApns(Phone.REASON_VOICE_CALL_ENDED);
3257c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3258c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onCleanUpConnection(boolean tearDown, int apnId, String reason) {
3260cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onCleanUpConnection");
3261af5593594070f825032be46dced573cd195956e1Robert Greenwalt        ApnContext apnContext = mApnContextsById.get(apnId);
3262cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
3263cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setReason(reason);
3264cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpConnection(tearDown, apnContext);
3265c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3266c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3267c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean isConnected() {
3269cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
3270ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getState() == DctConstants.State.CONNECTED) {
3271cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // At least one context is connected, return true
3272cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return true;
3273c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3274c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3275cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // There are not any contexts connected, return false
3276cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return false;
3277c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3278c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3279cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isDisconnected() {
3280cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
3281cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!apnContext.isDisconnected()) {
3282cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // At least one context was not disconnected return false
3283cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
3284cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3285c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3286cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // All contexts were disconnected so return true
3287cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
3288c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3289c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyDataConnection(String reason) {
3291cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("notifyDataConnection: reason=" + reason);
3292cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
3293187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (mAttached.get() && apnContext.isReady()) {
3294187a39f896f88eb6c5e4306d9595546654825976Wink Saville                if (DBG) log("notifyDataConnection: type:" + apnContext.getApnType());
3295cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
3296cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.getApnType());
3297cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3298c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3299cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyOffApnsOfAvailability(reason);
3300c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3301c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
33021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void setDataProfilesAsNeeded() {
33031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("setDataProfilesAsNeeded");
33041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mAllApnSettings != null && !mAllApnSettings.isEmpty()) {
33051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            ArrayList<DataProfile> dps = new ArrayList<DataProfile>();
33061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (ApnSetting apn : mAllApnSettings) {
33071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (apn.modemCognitive) {
33088e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                    DataProfile dp = new DataProfile(apn);
33098e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                    if (!dps.contains(dp)) {
33101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        dps.add(dp);
33111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
33121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
33131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
33148e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu            if (dps.size() > 0) {
33158e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                mPhone.mCi.setDataProfile(dps.toArray(new DataProfile[0]),
3316cc40713c49908aeaac0070bf4ea796247f9066b5Jack Yu                        mPhone.getServiceState().getDataRoamingFromRegistration(), null);
33171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
33181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
33191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
33201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3321c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
3322cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Based on the sim operator numeric, create a list for all possible
3323cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Data Connections and setup the preferredApn.
3324c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
3325cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void createAllApnList() {
33261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mMvnoMatched = false;
33278e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu        mAllApnSettings = new ArrayList<>();
3328cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
3329cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String operator = (r != null) ? r.getOperatorNumeric() : "";
3330cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (operator != null) {
33313c89e23cf33c3c7f795554b29cd926219f28fe34Sungmin Choi            String selection = Telephony.Carriers.NUMERIC + " = '" + operator + "'";
3332cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // query only enabled apn.
3333cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // carrier_enabled : 1 means enabled apn, 0 disabled apn.
33349d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan            // selection += " and carrier_enabled = 1";
3335cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: selection=" + selection);
3336cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
33373c89e23cf33c3c7f795554b29cd926219f28fe34Sungmin Choi            // ORDER BY Telephony.Carriers._ID ("_id")
3338cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            Cursor cursor = mPhone.getContext().getContentResolver().query(
33393c89e23cf33c3c7f795554b29cd926219f28fe34Sungmin Choi                    Telephony.Carriers.CONTENT_URI, null, selection, null, Telephony.Carriers._ID);
3340cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3341cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cursor != null) {
3342cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (cursor.getCount() > 0) {
3343ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    mAllApnSettings = createApnList(cursor);
3344cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3345cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cursor.close();
3346cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3347c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3348c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
334976f43316a5a6082d601bffd4b6898d0bd81e11fcram        addEmergencyApnSetting();
335076f43316a5a6082d601bffd4b6898d0bd81e11fcram
335129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        dedupeApnSettings();
335229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
3353ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings.isEmpty()) {
3354cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: No APN found for carrier: " + operator);
3355cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPreferredApn = null;
3356ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // TODO: What is the right behavior?
3357cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            //notifyNoData(DataConnection.FailCause.MISSING_UNKNOWN_APN);
3358c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
3359cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPreferredApn = getPreferredApn();
3360cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator)) {
3361cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn = null;
3362cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                setPreferredApn(-1);
3363cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3364cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: mPreferredApn=" + mPreferredApn);
3365c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3366ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("createAllApnList: X mAllApnSettings=" + mAllApnSettings);
33679d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan
33689d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        setDataProfilesAsNeeded();
3369c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3370c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
337129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    private void dedupeApnSettings() {
337229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        ArrayList<ApnSetting> resultApns = new ArrayList<ApnSetting>();
337329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
337429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        // coalesce APNs if they are similar enough to prevent
337529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        // us from bringing up two data calls with the same interface
337629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        int i = 0;
337729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        while (i < mAllApnSettings.size() - 1) {
337829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            ApnSetting first = mAllApnSettings.get(i);
337929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            ApnSetting second = null;
338029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            int j = i + 1;
338129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            while (j < mAllApnSettings.size()) {
338229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                second = mAllApnSettings.get(j);
33839fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                if (first.similar(second)) {
338429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    ApnSetting newApn = mergeApns(first, second);
338529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    mAllApnSettings.set(i, newApn);
338629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    first = newApn;
338729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    mAllApnSettings.remove(j);
338829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                } else {
338929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    j++;
339029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                }
339129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            }
339229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            i++;
339329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        }
339429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    }
339529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
339629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    private ApnSetting mergeApns(ApnSetting dest, ApnSetting src) {
3397bca51fc3a191d3ca30df627b75374db0941571c5Sungmin Choi        int id = dest.id;
339829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        ArrayList<String> resultTypes = new ArrayList<String>();
339929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        resultTypes.addAll(Arrays.asList(dest.types));
340029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        for (String srcType : src.types) {
340129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            if (resultTypes.contains(srcType) == false) resultTypes.add(srcType);
3402bca51fc3a191d3ca30df627b75374db0941571c5Sungmin Choi            if (srcType.equals(PhoneConstants.APN_TYPE_DEFAULT)) id = src.id;
340329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        }
340429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        String mmsc = (TextUtils.isEmpty(dest.mmsc) ? src.mmsc : dest.mmsc);
340529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        String mmsProxy = (TextUtils.isEmpty(dest.mmsProxy) ? src.mmsProxy : dest.mmsProxy);
340629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        String mmsPort = (TextUtils.isEmpty(dest.mmsPort) ? src.mmsPort : dest.mmsPort);
340761cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String proxy = (TextUtils.isEmpty(dest.proxy) ? src.proxy : dest.proxy);
340861cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String port = (TextUtils.isEmpty(dest.port) ? src.port : dest.port);
340961cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String protocol = src.protocol.equals("IPV4V6") ? src.protocol : dest.protocol;
341061cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String roamingProtocol = src.roamingProtocol.equals("IPV4V6") ? src.roamingProtocol :
341161cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                dest.roamingProtocol;
3412aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan        int bearerBitmask = (dest.bearerBitmask == 0 || src.bearerBitmask == 0) ?
3413aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                0 : (dest.bearerBitmask | src.bearerBitmask);
341429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
3415bca51fc3a191d3ca30df627b75374db0941571c5Sungmin Choi        return new ApnSetting(id, dest.numeric, dest.carrier, dest.apn,
341661cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                proxy, port, mmsc, mmsProxy, mmsPort, dest.user, dest.password,
341761cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                dest.authType, resultTypes.toArray(new String[0]), protocol,
3418aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                roamingProtocol, dest.carrierEnabled, 0, bearerBitmask, dest.profileId,
341929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                (dest.modemCognitive || src.modemCognitive), dest.maxConns, dest.waitTime,
342029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                dest.maxConnsTime, dest.mtu, dest.mvnoType, dest.mvnoMatchData);
342129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    }
342229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
3423ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /** Return the DC AsyncChannel for the new data connection */
3424454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel createDataConnection() {
3425cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createDataConnection E");
3426cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3427cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int id = mUniqueIdGenerator.getAndIncrement();
3428ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        DataConnection conn = DataConnection.makeDataConnection(mPhone, id,
3429ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                                this, mDcTesterFailBringUpAll, mDcc);
3430cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mDataConnections.put(id, conn);
3431454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac = new DcAsyncChannel(conn, LOG_TAG);
3432cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int status = dcac.fullyConnectSync(mPhone.getContext(), this, conn.getHandler());
3433cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (status == AsyncChannel.STATUS_SUCCESSFUL) {
3434ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            mDataConnectionAcHashMap.put(dcac.getDataConnectionIdSync(), dcac);
3435c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
3436ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            loge("createDataConnection: Could not connect to dcac=" + dcac + " status=" + status);
3437c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3438cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3439cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createDataConnection() X id=" + id + " dc=" + conn);
3440ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        return dcac;
3441c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3442c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3443cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void destroyDataConnections() {
3444cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(mDataConnections != null) {
3445cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("destroyDataConnections: clear mDataConnectionList");
3446cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mDataConnections.clear();
3447cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
3448cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("destroyDataConnections: mDataConnecitonList is empty, ignore");
3449c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3450c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3451c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3452c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
3453cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Build a list of APNs to be used to create PDP's.
3454c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
3455cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param requestedApnType
3456cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return waitingApns list to be used to create PDP
3457cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *          error when waitingApns.isEmpty()
3458c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
3459203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    private ArrayList<ApnSetting> buildWaitingApns(String requestedApnType, int radioTech) {
3460cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("buildWaitingApns: E requestedApnType=" + requestedApnType);
3461cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ArrayList<ApnSetting> apnList = new ArrayList<ApnSetting>();
3462cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3463cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (requestedApnType.equals(PhoneConstants.APN_TYPE_DUN)) {
3464cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ApnSetting dun = fetchDunApn();
3465cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dun != null) {
3466cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnList.add(dun);
3467cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: X added APN_TYPE_DUN apnList=" + apnList);
3468cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return apnList;
3469c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3470c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3471c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3472cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
3473cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String operator = (r != null) ? r.getOperatorNumeric() : "";
3474c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3475cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // This is a workaround for a bug (7305641) where we don't failover to other
3476cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // suitable APNs if our preferred APN fails.  On prepaid ATT sims we need to
3477cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // failover to a provisioning APN, but once we've used their default data
3478cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // connection we are locked to it for life.  This change allows ATT devices
3479cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // to say they don't want to use preferred at all.
3480cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean usePreferred = true;
3481cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        try {
3482cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            usePreferred = ! mPhone.getContext().getResources().getBoolean(com.android.
3483cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    internal.R.bool.config_dontPreferApn);
3484cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } catch (Resources.NotFoundException e) {
3485cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("buildWaitingApns: usePreferred NotFoundException set to true");
3486cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            usePreferred = true;
3487cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3488bf660a4647db8151609cdfa0ecc4c96e1518947fSungmin Choi        if (usePreferred) {
3489bf660a4647db8151609cdfa0ecc4c96e1518947fSungmin Choi            mPreferredApn = getPreferredApn();
3490bf660a4647db8151609cdfa0ecc4c96e1518947fSungmin Choi        }
3491cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
3492cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("buildWaitingApns: usePreferred=" + usePreferred
349322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    + " canSetPreferApn=" + mCanSetPreferApn
3494cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " mPreferredApn=" + mPreferredApn
3495cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " operator=" + operator + " radioTech=" + radioTech
3496cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " IccRecords r=" + r);
3497cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3498c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
349922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (usePreferred && mCanSetPreferApn && mPreferredApn != null &&
3500cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn.canHandleType(requestedApnType)) {
3501cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
3502cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("buildWaitingApns: Preferred APN:" + operator + ":"
3503cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        + mPreferredApn.numeric + ":" + mPreferredApn);
3504cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3505cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPreferredApn.numeric.equals(operator)) {
3506aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                if (ServiceState.bitmaskHasTech(mPreferredApn.bearerBitmask, radioTech)) {
3507cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnList.add(mPreferredApn);
3508cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
3509cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return apnList;
3510cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
3511cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("buildWaitingApns: no preferred APN");
3512cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    setPreferredApn(-1);
3513cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mPreferredApn = null;
3514c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
3515cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
3516cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: no preferred APN");
3517cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                setPreferredApn(-1);
3518cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn = null;
3519c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3520c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3521ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings != null) {
3522ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (DBG) log("buildWaitingApns: mAllApnSettings=" + mAllApnSettings);
3523ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for (ApnSetting apn : mAllApnSettings) {
3524cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn.canHandleType(requestedApnType)) {
3525aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                    if (ServiceState.bitmaskHasTech(apn.bearerBitmask, radioTech)) {
35269232dafa7ea833fc0b3a6024d6c7e23fc8e961eaRobert Greenwalt                        if (DBG) log("buildWaitingApns: adding apn=" + apn);
3527cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnList.add(apn);
3528c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else {
3529cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (DBG) {
3530aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                            log("buildWaitingApns: bearerBitmask:" + apn.bearerBitmask + " does " +
3531aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                                    "not include radioTech:" + radioTech);
3532cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
3533c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
35349232dafa7ea833fc0b3a6024d6c7e23fc8e961eaRobert Greenwalt                } else if (DBG) {
353527b650c406018355a88a41528db7859e232728a0Jack Yu                    log("buildWaitingApns: couldn't handle requested ApnType="
3536cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            + requestedApnType);
3537c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
3538c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3539cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
35404bd0ae43eb0cb9969dee4f30cddc18a71da68190Jack Yu            loge("mAllApnSettings is null!");
3541c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
35420e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        if (DBG) log("buildWaitingApns: " + apnList.size() + " APNs in the list: " + apnList);
3543cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return apnList;
3544c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3545c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3546cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private String apnListToString (ArrayList<ApnSetting> apns) {
3547cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        StringBuilder result = new StringBuilder();
3548cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (int i = 0, size = apns.size(); i < size; i++) {
3549cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result.append('[')
3550cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                  .append(apns.get(i).toString())
3551cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                  .append(']');
3552c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3553cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result.toString();
3554c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3555c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3556cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void setPreferredApn(int pos) {
355722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (!mCanSetPreferApn) {
3558cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("setPreferredApn: X !canSEtPreferApn");
3559cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
3560cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3561cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
35626bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        String subId = Long.toString(mPhone.getSubId());
35636bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        Uri uri = Uri.withAppendedPath(PREFERAPN_NO_UPDATE_URI_USING_SUBID, subId);
3564cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("setPreferredApn: delete");
3565cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ContentResolver resolver = mPhone.getContext().getContentResolver();
35666bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        resolver.delete(uri, null, null);
3567cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3568cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (pos >= 0) {
3569cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("setPreferredApn: insert");
3570cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ContentValues values = new ContentValues();
3571cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            values.put(APN_ID, pos);
35726bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville            resolver.insert(uri, values);
3573cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3574cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
3575cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3576cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ApnSetting getPreferredApn() {
35774bd0ae43eb0cb9969dee4f30cddc18a71da68190Jack Yu        if (mAllApnSettings == null || mAllApnSettings.isEmpty()) {
35784bd0ae43eb0cb9969dee4f30cddc18a71da68190Jack Yu            log("getPreferredApn: mAllApnSettings is " + ((mAllApnSettings == null)?"null":"empty"));
3579cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return null;
3580cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3581cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
35826bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        String subId = Long.toString(mPhone.getSubId());
35836bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        Uri uri = Uri.withAppendedPath(PREFERAPN_NO_UPDATE_URI_USING_SUBID, subId);
3584cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Cursor cursor = mPhone.getContext().getContentResolver().query(
35856bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville                uri, new String[] { "_id", "name", "apn" },
3586cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
3587cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3588cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor != null) {
358922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCanSetPreferApn = true;
3590cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
359122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCanSetPreferApn = false;
3592cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3593cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("getPreferredApn: mRequestedApnType=" + mRequestedApnType + " cursor=" + cursor
3594cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                + " cursor.count=" + ((cursor != null) ? cursor.getCount() : 0));
3595cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
359622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mCanSetPreferApn && cursor.getCount() > 0) {
3597cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            int pos;
3598cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cursor.moveToFirst();
3599cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            pos = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID));
3600ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for(ApnSetting p : mAllApnSettings) {
3601cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("getPreferredApn: apnSetting=" + p);
3602cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (p.id == pos && p.canHandleType(mRequestedApnType)) {
3603cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("getPreferredApn: X found apnSetting" + p);
3604cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    cursor.close();
3605cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return p;
3606cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3607cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
3608cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3609cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3610cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor != null) {
3611cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cursor.close();
3612cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3613cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3614cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("getPreferredApn: X not found");
3615cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
3616cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
3617cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3618cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
3619cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void handleMessage (Message msg) {
36201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) log("handleMessage msg=" + msg);
3621cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3622cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        switch (msg.what) {
3623cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_RECORDS_LOADED:
36241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // If onRecordsLoadedOrSubIdChanged() is not called here, it should be called on
36251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // onSubscriptionsChanged() when a valid subId is available.
36261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                int subId = mPhone.getSubId();
36271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (SubscriptionManager.isValidSubscriptionId(subId)) {
36281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onRecordsLoadedOrSubIdChanged();
36291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
36301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("Ignoring EVENT_RECORDS_LOADED as subId is not valid: " + subId);
36311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
3632cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3633cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3634cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_CONNECTION_DETACHED:
3635cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onDataConnectionDetached();
3636cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3637cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3638cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_CONNECTION_ATTACHED:
3639bda761320929f714951c328bfec6a51a1978db97Wink Saville                onDataConnectionAttached();
3640cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3641cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3642cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DO_RECOVERY:
3643cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                doRecovery();
3644cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3645cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3646cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_APN_CHANGED:
3647cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onApnChanged();
3648cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3649cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3650cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_PS_RESTRICT_ENABLED:
3651cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                /**
3652cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * We don't need to explicitly to tear down the PDP context
3653cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * when PS restricted is enabled. The base band will deactive
3654cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * PDP context and notify us with PDP_CONTEXT_CHANGED.
3655cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * But we should stop the network polling and prevent reset PDP.
3656cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 */
3657cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
3658cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                stopNetStatPoll();
3659cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                stopDataStallAlarm();
3660cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsPsRestricted = true;
3661cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
3662cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3663cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_PS_RESTRICT_DISABLED:
3664cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                /**
3665cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * When PS restrict is removed, we need setup PDP connection if
3666cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * PDP connection is down.
3667cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 */
3668cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_PS_RESTRICT_DISABLED " + mIsPsRestricted);
3669cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsPsRestricted  = false;
3670cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (isConnected()) {
3671cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    startNetStatPoll();
3672cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
3673cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
3674cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // TODO: Should all PDN states be checked to fail?
3675ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    if (mState == DctConstants.State.FAILED) {
3676cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        cleanUpAllConnections(false, Phone.REASON_PS_RESTRICT_ENABLED);
3677cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mReregisterOnReconnectFailure = false;
3678cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
3679af5593594070f825032be46dced573cd195956e1Robert Greenwalt                    ApnContext apnContext = mApnContextsById.get(DctConstants.APN_DEFAULT_ID);
36803fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (apnContext != null) {
36813fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        apnContext.setReason(Phone.REASON_PS_RESTRICT_ENABLED);
36823fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        trySetupData(apnContext);
36833fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    } else {
36843fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        loge("**** Default ApnContext not found ****");
36853fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        if (Build.IS_DEBUGGABLE) {
36863fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                            throw new RuntimeException("Default ApnContext not found");
36873fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        }
36883fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    }
3689cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3690cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
3691ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3692cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_TRY_SETUP_DATA:
3693cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (msg.obj instanceof ApnContext) {
3694cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    onTrySetupData((ApnContext)msg.obj);
3695cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else if (msg.obj instanceof String) {
3696cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    onTrySetupData((String)msg.obj);
3697cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
3698cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    loge("EVENT_TRY_SETUP request w/o apnContext or String");
3699cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3700cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
3701cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3702cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_CLEAN_UP_CONNECTION:
3703cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                boolean tearDown = (msg.arg1 == 0) ? false : true;
3704cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_CLEAN_UP_CONNECTION tearDown=" + tearDown);
3705cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (msg.obj instanceof ApnContext) {
3706cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    cleanUpConnection(tearDown, (ApnContext)msg.obj);
3707cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
37081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onCleanUpConnection(tearDown, msg.arg2, (String) msg.obj);
3709cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3710cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
37111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE: {
37121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
3713a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                onSetInternalDataEnabled(enabled, (Message) msg.obj);
3714a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
37151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
3716a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS:
37171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if ((msg.obj != null) && (msg.obj instanceof String == false)) {
37181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    msg.obj = null;
3719a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
37201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onCleanUpAllConnections((String) msg.obj);
3721a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
3722ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3723220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville            case DctConstants.EVENT_DATA_RAT_CHANGED:
3724b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                if (mPhone.getServiceState().getRilDataRadioTechnology()
3725b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                        == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
3726b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                    // unknown rat is an exception for data rat change. It's only received when out
3727b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                    // of service and is not applicable for apn bearer bitmask. We should bypass the
3728b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                    // check of waiting apn list and keep the data connection on, and no need to
3729b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                    // setup a new one.
3730b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                    break;
3731b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                }
3732ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                cleanUpConnectionsOnUpdatedApns(false, Phone.REASON_NW_TYPE_CHANGED);
3733220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville                //May new Network allow setupData, so try it here
3734c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                setupDataOnConnectableApns(Phone.REASON_NW_TYPE_CHANGED,
3735c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                        RetryFailures.ONLY_ON_CHANGE);
3736220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville                break;
3737220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville
37382b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            case DctConstants.CMD_CLEAR_PROVISIONING_SPINNER:
37392b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                // Check message sender intended to clear the current spinner.
37402b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                if (mProvisioningSpinner == msg.obj) {
37412b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner.dismiss();
37422b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner = null;
37432b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                }
37442b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                break;
37451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
37461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("DISCONNECTED_CONNECTED: msg=" + msg);
37471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DcAsyncChannel dcac = (DcAsyncChannel) msg.obj;
37481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mDataConnectionAcHashMap.remove(dcac.getDataConnectionIdSync());
37491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                dcac.disconnected();
37501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
37521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ENABLE_NEW_APN:
37531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onEnableApn(msg.arg1, msg.arg2);
37541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_STALL_ALARM:
37571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDataStallAlarm(msg.arg1);
37581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ROAMING_OFF:
37615b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu                onDataRoamingOff();
37621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ROAMING_ON:
37655b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu                onDataRoamingOnOrSettingsChanged();
37661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3768f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            case DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE:
3769f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                onDeviceProvisionedChange();
3770f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                break;
3771f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
3772a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            case DctConstants.EVENT_REDIRECTION_DETECTED:
37734c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                String url = (String) msg.obj;
377468f4f4a0bc8d4060b5775e7a24a97ea5b485989efionaxu                log("dataConnectionTracker.handleMessage: EVENT_REDIRECTION_DETECTED=" + url);
37754c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                onDataConnectionRedirected(url);
3776a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
37771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RADIO_AVAILABLE:
37781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onRadioAvailable();
37791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
37821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onRadioOffOrNotAvailable();
37831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_SETUP_COMPLETE:
37861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDataSetupComplete((AsyncResult) msg.obj);
37871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_SETUP_COMPLETE_ERROR:
37901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDataSetupCompleteError((AsyncResult) msg.obj);
37911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
3792a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
37931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DISCONNECT_DONE:
37941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("DataConnectionTracker.handleMessage: EVENT_DISCONNECT_DONE msg=" + msg);
37951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDisconnectDone((AsyncResult) msg.obj);
37961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DISCONNECT_DC_RETRYING:
37991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("DataConnectionTracker.handleMessage: EVENT_DISCONNECT_DC_RETRYING msg=" + msg);
38001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDisconnectDcRetrying((AsyncResult) msg.obj);
38011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
38031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_VOICE_CALL_STARTED:
38041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onVoiceCallStarted();
38051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
38071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_VOICE_CALL_ENDED:
38081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onVoiceCallEnded();
38091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
38111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RESET_DONE: {
38121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("EVENT_RESET_DONE");
38131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onResetDone((AsyncResult) msg.obj);
38141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
38161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_USER_DATA_ENABLE: {
38171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
38181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_SET_USER_DATA_ENABLE enabled=" + enabled);
38191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onSetUserDataEnabled(enabled);
38201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
38221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // TODO - remove
38231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_DEPENDENCY_MET: {
38241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                boolean met = (msg.arg1 == DctConstants.ENABLED) ? true : false;
38251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_SET_DEPENDENCY_MET met=" + met);
38261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Bundle bundle = msg.getData();
38271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (bundle != null) {
38281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    String apnType = (String)bundle.get(DctConstants.APN_TYPE_KEY);
38291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (apnType != null) {
38301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onSetDependencyMet(apnType, met);
38311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
38321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
38351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_POLICY_DATA_ENABLE: {
38361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
38371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onSetPolicyDataEnabled(enabled);
38381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
38401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: {
38411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                sEnableFailFastRefCounter += (msg.arg1 == DctConstants.ENABLED) ? 1 : -1;
38421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
38431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: "
38441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + " sEnableFailFastRefCounter=" + sEnableFailFastRefCounter);
38451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (sEnableFailFastRefCounter < 0) {
38471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    final String s = "CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: "
38481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + "sEnableFailFastRefCounter:" + sEnableFailFastRefCounter + " < 0";
38491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge(s);
38501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    sEnableFailFastRefCounter = 0;
38511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = sEnableFailFastRefCounter > 0;
38531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
38541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: enabled=" + enabled
38551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + " sEnableFailFastRefCounter=" + sEnableFailFastRefCounter);
38561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (mFailFast != enabled) {
38581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mFailFast = enabled;
38590e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
38601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mDataStallDetectionEnabled = !enabled;
38611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mDataStallDetectionEnabled
38621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            && (getOverallState() == DctConstants.State.CONNECTED)
38631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            && (!mInVoiceCall ||
38641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    mPhone.getServiceStateTracker()
38651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                        .isConcurrentVoiceAndDataAllowed())) {
38661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: start data stall");
38671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        stopDataStallAlarm();
38681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
38691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
38701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: stop data stall");
38711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        stopDataStallAlarm();
38721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
38731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38742b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen
38751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
38771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_ENABLE_MOBILE_PROVISIONING: {
38781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Bundle bundle = msg.getData();
38791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (bundle != null) {
38801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    try {
38811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mProvisioningUrl = (String)bundle.get(DctConstants.PROVISIONING_URL_KEY);
38821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } catch(ClassCastException e) {
38831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioning url not a string" + e);
38841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mProvisioningUrl = null;
38851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
38861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (TextUtils.isEmpty(mProvisioningUrl)) {
38881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioning url is empty, ignoring");
38891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mIsProvisioning = false;
38901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mProvisioningUrl = null;
38911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
38921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioningUrl=" + mProvisioningUrl);
38931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mIsProvisioning = true;
38941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    startProvisioningApnAlarm();
38951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
38981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_PROVISIONING_APN_ALARM: {
38991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("EVENT_PROVISIONING_APN_ALARM");
3900af5593594070f825032be46dced573cd195956e1Robert Greenwalt                ApnContext apnCtx = mApnContextsById.get(DctConstants.APN_DEFAULT_ID);
39011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (apnCtx.isProvisioningApn() && apnCtx.isConnectedOrConnecting()) {
39021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mProvisioningApnAlarmTag == msg.arg1) {
39031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) log("EVENT_PROVISIONING_APN_ALARM: Disconnecting");
39041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mIsProvisioning = false;
39051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mProvisioningUrl = null;
39061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        stopProvisioningApnAlarm();
39071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        sendCleanUpConnection(true, apnCtx);
39081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
39091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) {
39101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            log("EVENT_PROVISIONING_APN_ALARM: ignore stale tag,"
39111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    + " mProvisioningApnAlarmTag:" + mProvisioningApnAlarmTag
39121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    + " != arg1:" + msg.arg1);
39131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        }
39141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
39151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
39161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (DBG) log("EVENT_PROVISIONING_APN_ALARM: Not connected ignore");
39171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
39181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_IS_PROVISIONING_APN: {
39211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_IS_PROVISIONING_APN");
39221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                boolean isProvApn;
39231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                try {
39241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    String apnType = null;
39251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    Bundle bundle = msg.getData();
39261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (bundle != null) {
39271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        apnType = (String)bundle.get(DctConstants.APN_TYPE_KEY);
39281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
39291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (TextUtils.isEmpty(apnType)) {
39301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        loge("CMD_IS_PROVISIONING_APN: apnType is empty");
39311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        isProvApn = false;
39321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
39331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        isProvApn = isProvisioningApn(apnType);
39341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
39351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } catch (ClassCastException e) {
39361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge("CMD_IS_PROVISIONING_APN: NO provisioning url ignoring");
39371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    isProvApn = false;
39381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
39391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_IS_PROVISIONING_APN: ret=" + isProvApn);
39401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mReplyAc.replyToMessage(msg, DctConstants.CMD_IS_PROVISIONING_APN,
39411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        isProvApn ? DctConstants.ENABLED : DctConstants.DISABLED);
39421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ICC_CHANGED: {
39451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onUpdateIcc();
39461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RESTART_RADIO: {
39491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartRadio();
39501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_NET_STAT_POLL: {
39531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (msg.arg1 == DctConstants.ENABLED) {
39541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    handleStartNetStatPoll((DctConstants.Activity)msg.obj);
39551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else if (msg.arg1 == DctConstants.DISABLED) {
39561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    handleStopNetStatPoll((DctConstants.Activity)msg.obj);
39571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
39581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_STATE_CHANGED: {
39611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // no longer do anything, but still registered - clean up log
39621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // TODO - why are we still registering?
39631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39652e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            case DctConstants.EVENT_PCO_DATA_RECEIVED: {
39662e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt                handlePcoData((AsyncResult)msg.obj);
39672e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt                break;
39682e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            }
3969a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            case DctConstants.EVENT_SET_CARRIER_DATA_ENABLED:
39706a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu                onSetCarrierDataEnabled((AsyncResult) msg.obj);
3971a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                break;
3972e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu            case DctConstants.EVENT_DATA_RECONNECT:
3973e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                onDataReconnect(msg.getData());
3974e10a3af2a3a21ebf0b3de0ba319aaa940fd6d5bbJack Yu                break;
3975cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            default:
39761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Rlog.e("DcTracker", "Unhandled event=" + msg);
3977cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
39781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3979cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3980cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
3981cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
39821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int getApnProfileID(String apnType) {
3983cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IMS)) {
3984cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_IMS;
3985cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_FOTA)) {
3986cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_FOTA;
3987cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_CBS)) {
3988cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_CBS;
39891b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IA)) {
39901b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            return RILConstants.DATA_PROFILE_DEFAULT; // DEFAULT for now
399145df26444864daad60afdd4d121ab4043da3834bSungmin Choi        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_DUN)) {
399245df26444864daad60afdd4d121ab4043da3834bSungmin Choi            return RILConstants.DATA_PROFILE_TETHERED;
3993cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
3994cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_DEFAULT;
3995cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3996cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
3997cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3998cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private int getCellLocationId() {
3999cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int cid = -1;
4000cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        CellLocation loc = mPhone.getCellLocation();
4001cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4002cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (loc != null) {
4003cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (loc instanceof GsmCellLocation) {
4004cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cid = ((GsmCellLocation)loc).getCid();
4005cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else if (loc instanceof CdmaCellLocation) {
4006cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cid = ((CdmaCellLocation)loc).getBaseStationId();
4007cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
4008cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
4009cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return cid;
4010cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
4011cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4012a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private IccRecords getUiccRecords(int appFamily) {
4013a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return mUiccController.getIccRecords(mPhone.getPhoneId(), appFamily);
4014a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4015a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4016a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
40171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onUpdateIcc() {
4018cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mUiccController == null ) {
4019cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            return;
4020cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
4021cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4022a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        IccRecords newIccRecords = getUiccRecords(UiccController.APP_FAM_3GPP);
4023cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4024cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
4025cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (r != newIccRecords) {
4026cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (r != null) {
4027cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("Removing stale icc objects.");
4028cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                r.unregisterForRecordsLoaded(this);
4029cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIccRecords.set(null);
40309aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan            }
4031cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (newIccRecords != null) {
40321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (SubscriptionManager.isValidSubscriptionId(mPhone.getSubId())) {
4033aa863054476b152fe9323defd197fa946a47033fSungmin Choi                    log("New records found.");
4034aa863054476b152fe9323defd197fa946a47033fSungmin Choi                    mIccRecords.set(newIccRecords);
4035aa863054476b152fe9323defd197fa946a47033fSungmin Choi                    newIccRecords.registerForRecordsLoaded(
4036aa863054476b152fe9323defd197fa946a47033fSungmin Choi                            this, DctConstants.EVENT_RECORDS_LOADED, null);
4037aa863054476b152fe9323defd197fa946a47033fSungmin Choi                }
40380469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal            } else {
40390469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal                onSimNotReady();
40409aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan            }
40419aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan        }
4042cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
4043cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4044a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void update() {
4045a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("update sub = " + mPhone.getSubId());
4046bda761320929f714951c328bfec6a51a1978db97Wink Saville        log("update(): Active DDS, register for all events now!");
4047bda761320929f714951c328bfec6a51a1978db97Wink Saville        onUpdateIcc();
4048a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4049a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        mDataEnabledSettings.setUserDataEnabled(getDataEnabled());
40500979b71e48405cab10bdf1d1b4170cfce72838a7Jack Yu        mAutoAttachOnCreation.set(false);
4051bda761320929f714951c328bfec6a51a1978db97Wink Saville
40521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ((GsmCdmaPhone)mPhone).updateCurrentCarrierInProvider();
4053a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4054a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4055a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void cleanUpAllConnections(String cause) {
4056a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cleanUpAllConnections(cause, null);
4057a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4058a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4059a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void updateRecords() {
4060bda761320929f714951c328bfec6a51a1978db97Wink Saville        onUpdateIcc();
4061a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4062a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4063a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void cleanUpAllConnections(String cause, Message disconnectAllCompleteMsg) {
4064a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("cleanUpAllConnections");
4065a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (disconnectAllCompleteMsg != null) {
4066a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mDisconnectAllCompleteMsgList.add(disconnectAllCompleteMsg);
4067a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4068a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4069a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Message msg = obtainMessage(DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS);
4070a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        msg.obj = cause;
4071a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sendMessage(msg);
4072a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4073a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
40741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyDataDisconnectComplete() {
4075a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("notifyDataDisconnectComplete");
4076a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        for (Message m: mDisconnectAllCompleteMsgList) {
4077a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            m.sendToTarget();
4078a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4079a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mDisconnectAllCompleteMsgList.clear();
4080a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4081a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4082a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
40831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyAllDataDisconnected() {
4084a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sEnableFailFastRefCounter = 0;
4085a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mFailFast = false;
4086a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.notifyRegistrants();
4087a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4088a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4089a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void registerForAllDataDisconnected(Handler h, int what, Object obj) {
4090a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.addUnique(h, what, obj);
4091a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4092a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (isDisconnected()) {
4093a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("notify All Data Disconnected");
4094a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
4095a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4096a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4097a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4098a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void unregisterForAllDataDisconnected(Handler h) {
4099a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.remove(h);
4100a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4101a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4102a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    public void registerForDataEnabledChanged(Handler h, int what, Object obj) {
4103a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        mDataEnabledSettings.registerForDataEnabledChanged(h, what, obj);
4104a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    }
4105a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
4106a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    public void unregisterForDataEnabledChanged(Handler h) {
4107a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        mDataEnabledSettings.unregisterForDataEnabledChanged(h);
4108a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    }
4109a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
41101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetInternalDataEnabled(boolean enabled, Message onCompleteMsg) {
4111a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        synchronized (mDataEnabledSettings) {
4112a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            if (DBG) log("onSetInternalDataEnabled: enabled=" + enabled);
4113a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            boolean sendOnComplete = true;
4114a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4115a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            mDataEnabledSettings.setInternalDataEnabled(enabled);
4116a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (enabled) {
4117a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("onSetInternalDataEnabled: changed to enabled, try to setup data call");
4118a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                onTrySetupData(Phone.REASON_DATA_ENABLED);
4119a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
4120a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                sendOnComplete = false;
4121a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("onSetInternalDataEnabled: changed to disabled, cleanUpAllConnections");
41224fdc57b9bf223c908474c4545cc6f63456117a3bSanket Padawe                cleanUpAllConnections(Phone.REASON_DATA_DISABLED, onCompleteMsg);
4123a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
4124a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4125a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            if (sendOnComplete) {
4126a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                if (onCompleteMsg != null) {
4127a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                    onCompleteMsg.sendToTarget();
4128a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                }
4129a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
4130a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4131a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4132a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4133a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean setInternalDataEnabled(boolean enable) {
4134a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return setInternalDataEnabled(enable, null);
4135a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4136a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4137a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean setInternalDataEnabled(boolean enable, Message onCompleteMsg) {
41386bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        if (DBG) log("setInternalDataEnabled(" + enable + ")");
4139a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4140a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Message msg = obtainMessage(DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE, onCompleteMsg);
4141a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        msg.arg1 = (enable ? DctConstants.ENABLED : DctConstants.DISABLED);
4142a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sendMessage(msg);
4143a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return true;
4144a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4145a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
41461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void log(String s) {
4147a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Rlog.d(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s);
4148cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
4149cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
41501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void loge(String s) {
4151a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Rlog.e(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s);
4152cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
4153cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4154c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
41551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println("DcTracker:");
41561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" RADIO_TESTS=" + RADIO_TESTS);
415799e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        pw.println(" mDataEnabledSettings=" + mDataEnabledSettings);
415899e00ea846baea00e54d9d8c61b457a22a282cb7Jack Yu        pw.println(" isDataAllowed=" + isDataAllowed(null));
41591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
41601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mRequestedApnType=" + mRequestedApnType);
41611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mPhone=" + mPhone.getPhoneName());
41621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mActivity=" + mActivity);
41631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mState=" + mState);
41641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mTxPkts=" + mTxPkts);
41651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mRxPkts=" + mRxPkts);
41661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mNetStatPollPeriod=" + mNetStatPollPeriod);
41671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mNetStatPollEnabled=" + mNetStatPollEnabled);
41681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mDataStallTxRxSum=" + mDataStallTxRxSum);
41691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mDataStallAlarmTag=" + mDataStallAlarmTag);
4170a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        pw.println(" mDataStallDetectionEnabled=" + mDataStallDetectionEnabled);
41711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mSentSinceLastRecv=" + mSentSinceLastRecv);
41721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mNoRecvPollCount=" + mNoRecvPollCount);
41731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mResolver=" + mResolver);
41741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsWifiConnected=" + mIsWifiConnected);
41751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mReconnectIntent=" + mReconnectIntent);
41761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mAutoAttachOnCreation=" + mAutoAttachOnCreation.get());
41771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsScreenOn=" + mIsScreenOn);
41781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mUniqueIdGenerator=" + mUniqueIdGenerator);
41791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
41801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
41811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        DcController dcc = mDcc;
41821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (dcc != null) {
41831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            dcc.dump(fd, pw, args);
41841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
41851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mDcc=null");
41861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
41871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
41881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        HashMap<Integer, DataConnection> dcs = mDataConnections;
41891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (dcs != null) {
41901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Set<Entry<Integer, DataConnection> > mDcSet = mDataConnections.entrySet();
41911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mDataConnections: count=" + mDcSet.size());
41921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (Entry<Integer, DataConnection> entry : mDcSet) {
41931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                pw.printf(" *** mDataConnection[%d] \n", entry.getKey());
41941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                entry.getValue().dump(fd, pw, args);
41951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
41961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
41971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println("mDataConnections=null");
41981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
41991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
42001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
42011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        HashMap<String, Integer> apnToDcId = mApnToDataConnectionId;
42021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (apnToDcId != null) {
42031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Set<Entry<String, Integer>> apnToDcIdSet = apnToDcId.entrySet();
42041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mApnToDataConnectonId size=" + apnToDcIdSet.size());
42051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (Entry<String, Integer> entry : apnToDcIdSet) {
42061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                pw.printf(" mApnToDataConnectonId[%s]=%d\n", entry.getKey(), entry.getValue());
42071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
42081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
42091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println("mApnToDataConnectionId=null");
42101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
42111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
42121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
42131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ConcurrentHashMap<String, ApnContext> apnCtxs = mApnContexts;
42141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (apnCtxs != null) {
42151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Set<Entry<String, ApnContext>> apnCtxsSet = apnCtxs.entrySet();
42161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mApnContexts size=" + apnCtxsSet.size());
42171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (Entry<String, ApnContext> entry : apnCtxsSet) {
42181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                entry.getValue().dump(fd, pw, args);
42191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
42201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" ***************************************");
42211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
42221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mApnContexts=null");
42231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
42241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
42251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ArrayList<ApnSetting> apnSettings = mAllApnSettings;
42261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (apnSettings != null) {
42271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mAllApnSettings size=" + apnSettings.size());
42281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (int i=0; i < apnSettings.size(); i++) {
42291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                pw.printf(" mAllApnSettings[%d]: %s\n", i, apnSettings.get(i));
42301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
42311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.flush();
42321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
42331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mAllApnSettings=null");
42341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
42351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mPreferredApn=" + mPreferredApn);
42361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsPsRestricted=" + mIsPsRestricted);
42371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsDisposed=" + mIsDisposed);
42381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIntentReceiver=" + mIntentReceiver);
4239cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mReregisterOnReconnectFailure=" + mReregisterOnReconnectFailure);
424022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" canSetPreferApn=" + mCanSetPreferApn);
4241cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mApnObserver=" + mApnObserver);
4242cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" getOverallState=" + getOverallState());
4243ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        pw.println(" mDataConnectionAsyncChannels=%s\n" + mDataConnectionAcHashMap);
4244187a39f896f88eb6c5e4306d9595546654825976Wink Saville        pw.println(" mAttached=" + mAttached.get());
42451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
4246c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
4247a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4248bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram    public String[] getPcscfAddress(String apnType) {
4249a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("getPcscfAddress()");
4250bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        ApnContext apnContext = null;
4251bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram
4252bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        if(apnType == null){
4253bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            log("apnType is null, return null");
4254bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            return null;
4255bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        }
4256a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4257bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_EMERGENCY)) {
4258af5593594070f825032be46dced573cd195956e1Robert Greenwalt            apnContext = mApnContextsById.get(DctConstants.APN_EMERGENCY_ID);
4259bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IMS)) {
4260af5593594070f825032be46dced573cd195956e1Robert Greenwalt            apnContext = mApnContextsById.get(DctConstants.APN_IMS_ID);
4261bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        } else {
4262bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            log("apnType is invalid, return null");
4263bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            return null;
4264bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        }
4265a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4266a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (apnContext == null) {
4267a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("apnContext is null, return null");
4268a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return null;
4269a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4270a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4271a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        DcAsyncChannel dcac = apnContext.getDcAc();
4272a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        String[] result = null;
4273a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4274a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (dcac != null) {
4275a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            result = dcac.getPcscfAddr();
4276a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4277a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            for (int i = 0; i < result.length; i++) {
4278a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("Pcscf[" + i + "]: " + result[i]);
4279a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
4280a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return result;
4281a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4282a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return null;
4283a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4284a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
428576f43316a5a6082d601bffd4b6898d0bd81e11fcram    /**
428676f43316a5a6082d601bffd4b6898d0bd81e11fcram     * Read APN configuration from Telephony.db for Emergency APN
428776f43316a5a6082d601bffd4b6898d0bd81e11fcram     * All opertors recognize the connection request for EPDN based on APN type
428876f43316a5a6082d601bffd4b6898d0bd81e11fcram     * PLMN name,APN name are not mandatory parameters
428976f43316a5a6082d601bffd4b6898d0bd81e11fcram     */
429076f43316a5a6082d601bffd4b6898d0bd81e11fcram    private void initEmergencyApnSetting() {
429176f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Operator Numeric is not available when sim records are not loaded.
429276f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Query Telephony.db with APN type as EPDN request does not
429376f43316a5a6082d601bffd4b6898d0bd81e11fcram        // require APN name, plmn and all operators support same APN config.
429476f43316a5a6082d601bffd4b6898d0bd81e11fcram        // DB will contain only one entry for Emergency APN
429576f43316a5a6082d601bffd4b6898d0bd81e11fcram        String selection = "type=\"emergency\"";
429676f43316a5a6082d601bffd4b6898d0bd81e11fcram        Cursor cursor = mPhone.getContext().getContentResolver().query(
429776f43316a5a6082d601bffd4b6898d0bd81e11fcram                Telephony.Carriers.CONTENT_URI, null, selection, null, null);
429876f43316a5a6082d601bffd4b6898d0bd81e11fcram
429976f43316a5a6082d601bffd4b6898d0bd81e11fcram        if (cursor != null) {
430076f43316a5a6082d601bffd4b6898d0bd81e11fcram            if (cursor.getCount() > 0) {
430176f43316a5a6082d601bffd4b6898d0bd81e11fcram                if (cursor.moveToFirst()) {
430276f43316a5a6082d601bffd4b6898d0bd81e11fcram                    mEmergencyApn = makeApnSetting(cursor);
430376f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
430476f43316a5a6082d601bffd4b6898d0bd81e11fcram            }
430576f43316a5a6082d601bffd4b6898d0bd81e11fcram            cursor.close();
430676f43316a5a6082d601bffd4b6898d0bd81e11fcram        }
430776f43316a5a6082d601bffd4b6898d0bd81e11fcram    }
430876f43316a5a6082d601bffd4b6898d0bd81e11fcram
430976f43316a5a6082d601bffd4b6898d0bd81e11fcram    /**
431076f43316a5a6082d601bffd4b6898d0bd81e11fcram     * Add the Emergency APN settings to APN settings list
431176f43316a5a6082d601bffd4b6898d0bd81e11fcram     */
431276f43316a5a6082d601bffd4b6898d0bd81e11fcram    private void addEmergencyApnSetting() {
431376f43316a5a6082d601bffd4b6898d0bd81e11fcram        if(mEmergencyApn != null) {
431476f43316a5a6082d601bffd4b6898d0bd81e11fcram            if(mAllApnSettings == null) {
431576f43316a5a6082d601bffd4b6898d0bd81e11fcram                mAllApnSettings = new ArrayList<ApnSetting>();
431676f43316a5a6082d601bffd4b6898d0bd81e11fcram            } else {
431776f43316a5a6082d601bffd4b6898d0bd81e11fcram                boolean hasEmergencyApn = false;
431876f43316a5a6082d601bffd4b6898d0bd81e11fcram                for (ApnSetting apn : mAllApnSettings) {
431976f43316a5a6082d601bffd4b6898d0bd81e11fcram                    if (ArrayUtils.contains(apn.types, PhoneConstants.APN_TYPE_EMERGENCY)) {
432076f43316a5a6082d601bffd4b6898d0bd81e11fcram                        hasEmergencyApn = true;
432176f43316a5a6082d601bffd4b6898d0bd81e11fcram                        break;
432276f43316a5a6082d601bffd4b6898d0bd81e11fcram                    }
432376f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
432476f43316a5a6082d601bffd4b6898d0bd81e11fcram
432576f43316a5a6082d601bffd4b6898d0bd81e11fcram                if(hasEmergencyApn == false) {
432676f43316a5a6082d601bffd4b6898d0bd81e11fcram                    mAllApnSettings.add(mEmergencyApn);
432776f43316a5a6082d601bffd4b6898d0bd81e11fcram                } else {
432876f43316a5a6082d601bffd4b6898d0bd81e11fcram                    log("addEmergencyApnSetting - E-APN setting is already present");
432976f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
433076f43316a5a6082d601bffd4b6898d0bd81e11fcram            }
433176f43316a5a6082d601bffd4b6898d0bd81e11fcram        }
433276f43316a5a6082d601bffd4b6898d0bd81e11fcram    }
43339a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
43349fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu    private boolean containsAllApns(ArrayList<ApnSetting> oldApnList,
43359fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                                    ArrayList<ApnSetting> newApnList) {
43369fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu        for (ApnSetting newApnSetting : newApnList) {
43379fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            boolean canHandle = false;
43389fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            for (ApnSetting oldApnSetting : oldApnList) {
43399fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                // Make sure at least one of the APN from old list can cover the new APN
43409fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                if (oldApnSetting.equals(newApnSetting,
43419fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                        mPhone.getServiceState().getDataRoamingFromRegistration())) {
43429fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                    canHandle = true;
43439fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                    break;
43449fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                }
43459fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            }
43469fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            if (!canHandle) return false;
43479fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu        }
43489fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu        return true;
43499fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu    }
43509fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu
4351ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu    private void cleanUpConnectionsOnUpdatedApns(boolean tearDown, String reason) {
43529a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (DBG) log("cleanUpConnectionsOnUpdatedApns: tearDown=" + tearDown);
4353ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu        if (mAllApnSettings != null && mAllApnSettings.isEmpty()) {
43549a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            cleanUpAllConnections(tearDown, Phone.REASON_APN_CHANGED);
43559a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        } else {
43569a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            for (ApnContext apnContext : mApnContexts.values()) {
43579a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                ArrayList<ApnSetting> currentWaitingApns = apnContext.getWaitingApns();
4358ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                ArrayList<ApnSetting> waitingApns = buildWaitingApns(
4359b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                        apnContext.getApnType(),
4360b5072c6da24adbc4bef8f26e061aee985a014086Jack Yu                        mPhone.getServiceState().getRilDataRadioTechnology());
4361ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                if (VDBG) log("new waitingApns:" + waitingApns);
4362ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                if ((currentWaitingApns != null)
4363ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                        && ((waitingApns.size() != currentWaitingApns.size())
43649fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                        // Check if the existing waiting APN list can cover the newly built APN
43659fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                        // list. If yes, then we don't need to tear down the existing data call.
43669fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                        // TODO: We probably need to rebuild APN list when roaming status changes.
43679fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                        || !containsAllApns(currentWaitingApns, waitingApns))) {
4368ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                    if (VDBG) log("new waiting apn is different for " + apnContext);
4369ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                    apnContext.setWaitingApns(waitingApns);
4370ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                    if (!apnContext.isDisconnected()) {
4371ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                        if (VDBG) log("cleanUpConnectionsOnUpdatedApns for " + apnContext);
4372ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                        apnContext.setReason(reason);
4373ced725ec28e37e37a61bbfa56a931b7f12ab9db7fionaxu                        cleanUpConnection(true, apnContext);
43749a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    }
43759a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                }
43769a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            }
43779a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        }
43789a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
43799a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (!isConnected()) {
43809a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            stopNetStatPoll();
43819a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            stopDataStallAlarm();
43829a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        }
43839a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
43849a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
43859a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
43869a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (DBG) log("mDisconnectPendingCount = " + mDisconnectPendingCount);
43879a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (tearDown && mDisconnectPendingCount == 0) {
43889a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            notifyDataDisconnectComplete();
43899a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            notifyAllDataDisconnected();
43909a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        }
43919a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang    }
43921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
43931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
43941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Polling stuff
43951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
43961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void resetPollStats() {
43971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mTxPkts = -1;
43981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mRxPkts = -1;
43991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mNetStatPollPeriod = POLL_NETSTAT_MILLIS;
44001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void startNetStatPoll() {
44031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (getOverallState() == DctConstants.State.CONNECTED
44041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                && mNetStatPollEnabled == false) {
44051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
44061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("startNetStatPoll");
44071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
44081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            resetPollStats();
44091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mNetStatPollEnabled = true;
44101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPollNetStat.run();
44111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mPhone != null) {
44131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPhone.notifyDataActivity();
44141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void stopNetStatPoll() {
44181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mNetStatPollEnabled = false;
44191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        removeCallbacks(mPollNetStat);
44201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
44211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("stopNetStatPoll");
44221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // To sync data activity icon in the case of switching data connection to send MMS.
44251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mPhone != null) {
44261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPhone.notifyDataActivity();
44271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void sendStartNetStatPoll(DctConstants.Activity activity) {
44311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.CMD_NET_STAT_POLL);
44321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = DctConstants.ENABLED;
44331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.obj = activity;
44341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
44351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void handleStartNetStatPoll(DctConstants.Activity activity) {
44381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startNetStatPoll();
44391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
44401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        setActivity(activity);
44411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void sendStopNetStatPoll(DctConstants.Activity activity) {
44441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.CMD_NET_STAT_POLL);
44451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = DctConstants.DISABLED;
44461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.obj = activity;
44471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
44481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void handleStopNetStatPoll(DctConstants.Activity activity) {
44511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        stopNetStatPoll();
44521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        stopDataStallAlarm();
44531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        setActivity(activity);
44541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void updateDataActivity() {
44571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        long sent, received;
44581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        DctConstants.Activity newActivity;
44601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        TxRxSum preTxRxSum = new TxRxSum(mTxPkts, mRxPkts);
44621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        TxRxSum curTxRxSum = new TxRxSum();
44631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        curTxRxSum.updateTxRxSum();
44641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mTxPkts = curTxRxSum.txPkts;
44651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mRxPkts = curTxRxSum.rxPkts;
44661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) {
44681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("updateDataActivity: curTxRxSum=" + curTxRxSum + " preTxRxSum=" + preTxRxSum);
44691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mNetStatPollEnabled && (preTxRxSum.txPkts > 0 || preTxRxSum.rxPkts > 0)) {
44721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            sent = mTxPkts - preTxRxSum.txPkts;
44731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            received = mRxPkts - preTxRxSum.rxPkts;
44741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG)
44761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("updateDataActivity: sent=" + sent + " received=" + received);
44771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (sent > 0 && received > 0) {
44781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = DctConstants.Activity.DATAINANDOUT;
44791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (sent > 0 && received == 0) {
44801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = DctConstants.Activity.DATAOUT;
44811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (sent == 0 && received > 0) {
44821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = DctConstants.Activity.DATAIN;
44831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
44841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = (mActivity == DctConstants.Activity.DORMANT) ?
44851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mActivity : DctConstants.Activity.NONE;
44861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
44871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mActivity != newActivity && mIsScreenOn) {
44891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (VDBG)
44901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("updateDataActivity: newActivity=" + newActivity);
44911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mActivity = newActivity;
44921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mPhone.notifyDataActivity();
44931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
44941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44972e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt    private void handlePcoData(AsyncResult ar) {
44982e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        if (ar.exception != null) {
44992e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            Rlog.e(LOG_TAG, "PCO_DATA exception: " + ar.exception);
45002e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            return;
45012e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        }
45022e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        PcoData pcoData = (PcoData)(ar.result);
4503cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        ArrayList<DataConnection> dcList = new ArrayList<>();
4504cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        DataConnection temp = mDcc.getActiveDcByCid(pcoData.cid);
4505cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        if (temp != null) {
4506cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            dcList.add(temp);
4507cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        }
4508cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        if (dcList.size() == 0) {
4509cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            Rlog.e(LOG_TAG, "PCO_DATA for unknown cid: " + pcoData.cid + ", inferring");
4510cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            for (DataConnection dc : mDataConnections.values()) {
4511cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                final int cid = dc.getCid();
4512cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                if (cid == pcoData.cid) {
4513cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    if (VDBG) Rlog.d(LOG_TAG, "  found " + dc);
4514cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    dcList.clear();
4515cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    dcList.add(dc);
4516cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    break;
4517cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                }
4518cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                // check if this dc is still connecting
4519cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                if (cid == -1) {
4520cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    for (ApnContext apnContext : dc.mApnContexts.keySet()) {
4521cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        if (apnContext.getState() == DctConstants.State.CONNECTING) {
4522cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                            if (VDBG) Rlog.d(LOG_TAG, "  found potential " + dc);
4523cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                            dcList.add(dc);
4524cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                            break;
4525cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        }
4526cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    }
4527cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                }
4528cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            }
4529cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        }
4530cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        if (dcList.size() == 0) {
4531cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            Rlog.e(LOG_TAG, "PCO_DATA - couldn't infer cid");
45322e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            return;
45332e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        }
4534cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        for (DataConnection dc : dcList) {
4535cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            if (dc.mApnContexts.size() == 0) {
4536cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                break;
4537cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            }
4538cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            // send one out for each apn type in play
4539cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            for (ApnContext apnContext : dc.mApnContexts.keySet()) {
4540cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                String apnType = apnContext.getApnType();
4541cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt
4542cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                final Intent intent = new Intent(TelephonyIntents.ACTION_CARRIER_SIGNAL_PCO_VALUE);
4543cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                intent.putExtra(TelephonyIntents.EXTRA_APN_TYPE_KEY, apnType);
4544cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                intent.putExtra(TelephonyIntents.EXTRA_APN_PROTO_KEY, pcoData.bearerProto);
4545cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                intent.putExtra(TelephonyIntents.EXTRA_PCO_ID_KEY, pcoData.pcoId);
4546cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                intent.putExtra(TelephonyIntents.EXTRA_PCO_VALUE_KEY, pcoData.contents);
4547cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
4548cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            }
45492e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        }
45502e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt    }
45512e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt
45521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
45531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Data-Stall
45541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
45551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Recovery action taken in case of data stall
45561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static class RecoveryAction {
45571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int GET_DATA_CALL_LIST      = 0;
45581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int CLEANUP                 = 1;
45591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int REREGISTER              = 2;
45601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int RADIO_RESTART           = 3;
45611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int RADIO_RESTART_WITH_PROP = 4;
45621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        private static boolean isAggressiveRecovery(int value) {
45641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return ((value == RecoveryAction.CLEANUP) ||
45651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    (value == RecoveryAction.REREGISTER) ||
45661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    (value == RecoveryAction.RADIO_RESTART) ||
45671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    (value == RecoveryAction.RADIO_RESTART_WITH_PROP));
45681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
45691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int getRecoveryAction() {
45721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int action = Settings.System.getInt(mResolver,
45731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                "radio.data.stall.recovery.action", RecoveryAction.GET_DATA_CALL_LIST);
45741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("getRecoveryAction: " + action);
45751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return action;
45761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void putRecoveryAction(int action) {
45791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Settings.System.putInt(mResolver, "radio.data.stall.recovery.action", action);
45801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("putRecoveryAction: " + action);
45811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void doRecovery() {
45841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (getOverallState() == DctConstants.State.CONNECTED) {
45851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Go through a series of recovery steps, each action transitions to the next action
45860a39f581e11eb7b040a5412229164ef72044279fRobert Greenwalt            final int recoveryAction = getRecoveryAction();
4587f2d0fa64860a12423fb8709766d6af90fba5e6cfJack Yu            TelephonyMetrics.getInstance().writeDataStallEvent(mPhone.getPhoneId(), recoveryAction);
45881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            switch (recoveryAction) {
45891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case RecoveryAction.GET_DATA_CALL_LIST:
45901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_GET_DATA_CALL_LIST,
45911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mSentSinceLastRecv);
45921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("doRecovery() get data call list");
45931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mPhone.mCi.getDataCallList(obtainMessage(DctConstants.EVENT_DATA_STATE_CHANGED));
45941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                putRecoveryAction(RecoveryAction.CLEANUP);
45951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
45961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case RecoveryAction.CLEANUP:
45971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_CLEANUP, mSentSinceLastRecv);
45981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("doRecovery() cleanup all connections");
45991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                cleanUpAllConnections(Phone.REASON_PDP_RESET);
46001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                putRecoveryAction(RecoveryAction.REREGISTER);
46011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
46021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case RecoveryAction.REREGISTER:
46031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_REREGISTER,
46041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mSentSinceLastRecv);
46051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("doRecovery() re-register");
46061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mPhone.getServiceStateTracker().reRegisterNetwork(null);
46071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                putRecoveryAction(RecoveryAction.RADIO_RESTART);
46081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
46091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case RecoveryAction.RADIO_RESTART:
46101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART,
46111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mSentSinceLastRecv);
46121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("restarting radio");
46131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                putRecoveryAction(RecoveryAction.RADIO_RESTART_WITH_PROP);
46141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartRadio();
46151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
46161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case RecoveryAction.RADIO_RESTART_WITH_PROP:
46171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // This is in case radio restart has not recovered the data.
46181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // It will set an additional "gsm.radioreset" property to tell
46191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // RIL or system to take further action.
46201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // The implementation of hard reset recovery action is up to OEM product.
46211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // Once RADIO_RESET property is consumed, it is expected to set back
46221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // to false by RIL.
46231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART_WITH_PROP, -1);
46241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("restarting radio with gsm.radioreset to true");
46251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                SystemProperties.set(RADIO_RESET_PROPERTY, "true");
46261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // give 1 sec so property change can be notified.
46271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                try {
46281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    Thread.sleep(1000);
46291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } catch (InterruptedException e) {}
46301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartRadio();
46311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
46321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
46331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            default:
46341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                throw new RuntimeException("doRecovery: Invalid recoveryAction=" +
46351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    recoveryAction);
46361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSentSinceLastRecv = 0;
46381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
46401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void updateDataStallInfo() {
46421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        long sent, received;
46431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        TxRxSum preTxRxSum = new TxRxSum(mDataStallTxRxSum);
46451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDataStallTxRxSum.updateTxRxSum();
46461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) {
46481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("updateDataStallInfo: mDataStallTxRxSum=" + mDataStallTxRxSum +
46491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " preTxRxSum=" + preTxRxSum);
46501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sent = mDataStallTxRxSum.txPkts - preTxRxSum.txPkts;
46531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        received = mDataStallTxRxSum.rxPkts - preTxRxSum.rxPkts;
46541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (RADIO_TESTS) {
46561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (SystemProperties.getBoolean("radio.test.data.stall", false)) {
46571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("updateDataStallInfo: radio.test.data.stall true received = 0;");
46581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                received = 0;
46591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if ( sent > 0 && received > 0 ) {
46621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) log("updateDataStallInfo: IN/OUT");
46631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSentSinceLastRecv = 0;
46641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
46651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (sent > 0 && received == 0) {
46666a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta            if (isPhoneStateIdle()) {
46671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mSentSinceLastRecv += sent;
46681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
46691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mSentSinceLastRecv = 0;
46701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
46721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("updateDataStallInfo: OUT sent=" + sent +
46731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        " mSentSinceLastRecv=" + mSentSinceLastRecv);
46741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (sent == 0 && received > 0) {
46761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) log("updateDataStallInfo: IN");
46771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSentSinceLastRecv = 0;
46781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
46791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
46801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) log("updateDataStallInfo: NONE");
46811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
46831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46846a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta    private boolean isPhoneStateIdle() {
46856a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta        for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
46866a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta            Phone phone = PhoneFactory.getPhone(i);
46876a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta            if (phone != null && phone.getState() != PhoneConstants.State.IDLE) {
46886a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta                log("isPhoneStateIdle false: Voice call active on phone " + i);
46896a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta                return false;
46906a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta            }
46916a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta        }
46926a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta        return true;
46936a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta    }
46946a2a21bfafb716f2eebdef6eb32d30c3df845bf3Sandeep Gutta
46951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataStallAlarm(int tag) {
46961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mDataStallAlarmTag != tag) {
46971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
46981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("onDataStallAlarm: ignore, tag=" + tag + " expecting " + mDataStallAlarmTag);
46991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return;
47011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        updateDataStallInfo();
47031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int hangWatchdogTrigger = Settings.Global.getInt(mResolver,
47051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Settings.Global.PDP_WATCHDOG_TRIGGER_PACKET_COUNT,
47061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                NUMBER_SENT_PACKETS_OF_HANG);
47071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        boolean suspectedStall = DATA_STALL_NOT_SUSPECTED;
47091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mSentSinceLastRecv >= hangWatchdogTrigger) {
47101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
47111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("onDataStallAlarm: tag=" + tag + " do recovery action=" + getRecoveryAction());
47121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            suspectedStall = DATA_STALL_SUSPECTED;
47141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            sendMessage(obtainMessage(DctConstants.EVENT_DO_RECOVERY));
47151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
47161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) {
47171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("onDataStallAlarm: tag=" + tag + " Sent " + String.valueOf(mSentSinceLastRecv) +
47181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " pkts since last received, < watchdogTrigger=" + hangWatchdogTrigger);
47191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startDataStallAlarm(suspectedStall);
47221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void startDataStallAlarm(boolean suspectedStall) {
47251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int nextAction = getRecoveryAction();
47261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int delayInMs;
47271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mDataStallDetectionEnabled && getOverallState() == DctConstants.State.CONNECTED) {
47291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // If screen is on or data stall is currently suspected, set the alarm
47300e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // with an aggressive timeout.
47311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mIsScreenOn || suspectedStall || RecoveryAction.isAggressiveRecovery(nextAction)) {
47321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                delayInMs = Settings.Global.getInt(mResolver,
47331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS,
47341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
47351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
47361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                delayInMs = Settings.Global.getInt(mResolver,
47371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS,
47381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
47391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mDataStallAlarmTag += 1;
47421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) {
47431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("startDataStallAlarm: tag=" + mDataStallAlarmTag +
47441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        " delay=" + (delayInMs / 1000) + "s");
47451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Intent intent = new Intent(INTENT_DATA_STALL_ALARM);
47471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            intent.putExtra(DATA_STALL_ALARM_TAG_EXTRA, mDataStallAlarmTag);
47481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mDataStallAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
47491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    PendingIntent.FLAG_UPDATE_CURRENT);
4750128f3f36854fe183a6dd4d9917906b4723dd234fAjay Dudani            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME,
47511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    SystemClock.elapsedRealtime() + delayInMs, mDataStallAlarmIntent);
47521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
47531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) {
47541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("startDataStallAlarm: NOT started, no connection tag=" + mDataStallAlarmTag);
47551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void stopDataStallAlarm() {
47601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) {
47611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("stopDataStallAlarm: current tag=" + mDataStallAlarmTag +
47621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " mDataStallAlarmIntent=" + mDataStallAlarmIntent);
47631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDataStallAlarmTag += 1;
47651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mDataStallAlarmIntent != null) {
47661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mAlarmManager.cancel(mDataStallAlarmIntent);
47671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mDataStallAlarmIntent = null;
47681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void restartDataStallAlarm() {
47721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (isConnected() == false) return;
47731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // To be called on screen status change.
47741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // Do not cancel the alarm if it is set with aggressive timeout.
47751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int nextAction = getRecoveryAction();
47761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (RecoveryAction.isAggressiveRecovery(nextAction)) {
47781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("restartDataStallAlarm: action is pending. not resetting the alarm.");
47791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return;
47801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("restartDataStallAlarm: stop then start.");
47821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        stopDataStallAlarm();
47831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
47841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
47871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Provisioning APN
47881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
47891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onActionIntentProvisioningApnAlarm(Intent intent) {
47901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("onActionIntentProvisioningApnAlarm: action=" + intent.getAction());
47911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_PROVISIONING_APN_ALARM,
47921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                intent.getAction());
47931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = intent.getIntExtra(PROVISIONING_APN_ALARM_TAG_EXTRA, 0);
47941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
47951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void startProvisioningApnAlarm() {
47981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int delayInMs = Settings.Global.getInt(mResolver,
47991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                Settings.Global.PROVISIONING_APN_ALARM_DELAY_IN_MS,
48001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                PROVISIONING_APN_ALARM_DELAY_IN_MS_DEFAULT);
48011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (Build.IS_DEBUGGABLE) {
48021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Allow debug code to use a system property to provide another value
48031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            String delayInMsStrg = Integer.toString(delayInMs);
48041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            delayInMsStrg = System.getProperty(DEBUG_PROV_APN_ALARM, delayInMsStrg);
48051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            try {
48061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                delayInMs = Integer.parseInt(delayInMsStrg);
48071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } catch (NumberFormatException e) {
48081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                loge("startProvisioningApnAlarm: e=" + e);
48091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
48101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
48111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisioningApnAlarmTag += 1;
48121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
48131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("startProvisioningApnAlarm: tag=" + mProvisioningApnAlarmTag +
48141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " delay=" + (delayInMs / 1000) + "s");
48151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
48161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Intent intent = new Intent(INTENT_PROVISIONING_APN_ALARM);
48171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        intent.putExtra(PROVISIONING_APN_ALARM_TAG_EXTRA, mProvisioningApnAlarmTag);
48181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisioningApnAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
48191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                PendingIntent.FLAG_UPDATE_CURRENT);
48201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
48211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                SystemClock.elapsedRealtime() + delayInMs, mProvisioningApnAlarmIntent);
48221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
48231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
48241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void stopProvisioningApnAlarm() {
48251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
48261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("stopProvisioningApnAlarm: current tag=" + mProvisioningApnAlarmTag +
48271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " mProvsioningApnAlarmIntent=" + mProvisioningApnAlarmIntent);
48281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
48291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisioningApnAlarmTag += 1;
48301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mProvisioningApnAlarmIntent != null) {
48311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mAlarmManager.cancel(mProvisioningApnAlarmIntent);
48321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mProvisioningApnAlarmIntent = null;
48331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
48341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
48351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4836c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville}
4837