DcTracker.java revision 128f3f36854fe183a6dd4d9917906b4723dd234f
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;
85828a110000eca870560ead99186d5727e96e64f8Sandeep Guttaimport com.android.internal.telephony.PhoneFactory;
86cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.RILConstants;
874c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport com.android.internal.telephony.ServiceStateTracker;
88a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxuimport com.android.internal.telephony.TelephonyIntents;
89f2d0fa64860a12423fb8709766d6af90fba5e6cfJack Yuimport com.android.internal.telephony.metrics.TelephonyMetrics;
90d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccRecords;
91bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenkaimport com.android.internal.telephony.uicc.UiccController;
9276f43316a5a6082d601bffd4b6898d0bd81e11fcramimport com.android.internal.util.ArrayUtils;
934c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport com.android.internal.util.AsyncChannel;
94c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
95c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.io.FileDescriptor;
96c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.io.PrintWriter;
97c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.ArrayList;
9829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwaltimport java.util.Arrays;
991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.Comparator;
1001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.HashMap;
10168f4f4a0bc8d4060b5775e7a24a97ea5b485989efionaxuimport java.util.HashSet;
1021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.Map.Entry;
10329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwaltimport java.util.Objects;
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
1633d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu    @VisibleForTesting
1643d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu    public static class DataAllowFailReason {
1653d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        private HashSet<DataAllowFailReasonType> mDataAllowFailReasonSet = new HashSet<>();
1663d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
1673d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        public void addDataAllowFailReason(DataAllowFailReasonType type) {
1683d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            mDataAllowFailReasonSet.add(type);
1693d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
1703d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
1713d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        public String getDataAllowFailReason() {
1723d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            StringBuilder failureReason = new StringBuilder();
1733d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            failureReason.append("isDataAllowed: No");
1743d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            for(DataAllowFailReasonType reason : mDataAllowFailReasonSet) {
1753d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                failureReason.append(reason.mFailReasonStr);
1763d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            }
1773d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            return failureReason.toString();
1783d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
1793d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
1803d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        public boolean isFailForSingleReason(DataAllowFailReasonType failReasonType) {
1813d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            return (mDataAllowFailReasonSet.size() == 1) &&
1823d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                    (mDataAllowFailReasonSet.contains(failReasonType));
1833d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
1843d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
1853d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        public void clearAllReasons() {
1863d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            mDataAllowFailReasonSet.clear();
1873d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
1883d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
1893d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        public boolean isFailed() {
1903d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            return mDataAllowFailReasonSet.size() > 0;
1913d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
1923d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu    }
1933d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
1943d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu    @VisibleForTesting
1953d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu    public enum DataAllowFailReasonType {
1963d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        NOT_ATTACHED(" - Not attached"),
1973d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        RECORD_NOT_LOADED(" - SIM not loaded"),
1983d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        ROAMING_DISABLED(" - Roaming and data roaming not enabled"),
1993d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        INVALID_PHONE_STATE(" - PhoneState is not idle"),
2003d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        CONCURRENT_VOICE_DATA_NOT_ALLOWED(" - Concurrent voice and data not allowed"),
2013d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        PS_RESTRICTED(" - mIsPsRestricted= true"),
2023d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        UNDESIRED_POWER_STATE(" - desiredPowerState= false"),
2033d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        INTERNAL_DATA_DISABLED(" - mInternalDataEnabled= false"),
2040d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu        DEFAULT_DATA_UNSELECTED(" - defaultDataSelected= false"),
2050d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu        RADIO_DISABLED_BY_CARRIER(" - powerStateFromCarrier= false");
2063d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
2073d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        public String mFailReasonStr;
2083d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
2093d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        DataAllowFailReasonType(String reason) {
2103d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            mFailReasonStr = reason;
2113d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
2123d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu    }
2133d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
2141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DcTesterFailBringUpAll mDcTesterFailBringUpAll;
2151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DcController mDcc;
2161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** kept in sync with mApnContexts
2181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Higher numbers are higher priority and sorted so highest priority is first */
2191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final PriorityQueue<ApnContext>mPrioritySortedApnContexts =
2201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new PriorityQueue<ApnContext>(5,
2211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new Comparator<ApnContext>() {
2221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                public int compare(ApnContext c1, ApnContext c2) {
2231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    return c2.priority - c1.priority;
2241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
2251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } );
2261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** allApns holds all apns */
2281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ArrayList<ApnSetting> mAllApnSettings = null;
2291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** preferred apn */
2311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ApnSetting mPreferredApn = null;
2321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Is packet service restricted by network */
2341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsPsRestricted = false;
2351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** emergency apn Setting*/
2371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ApnSetting mEmergencyApn = null;
2381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Once disposed dont handle any messages */
2401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsDisposed = false;
2411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ContentResolver mResolver;
2431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Set to true with CMD_ENABLE_MOBILE_PROVISIONING */
2451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsProvisioning = false;
2461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* The Url passed as object parameter in CMD_ENABLE_MOBILE_PROVISIONING */
2481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private String mProvisioningUrl = null;
2491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Intent for the provisioning apn alarm */
2511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_PROVISIONING_APN_ALARM =
2521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "com.android.internal.telephony.provisioning_apn_alarm";
2531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Tag for tracking stale alarms */
2551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String PROVISIONING_APN_ALARM_TAG_EXTRA = "provisioning.apn.alarm.tag";
2561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Debug property for overriding the PROVISIONING_APN_ALARM_DELAY_IN_MS */
2581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String DEBUG_PROV_APN_ALARM = "persist.debug.prov_apn_alarm";
2591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Default for the provisioning apn alarm timeout */
2611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int PROVISIONING_APN_ALARM_DELAY_IN_MS_DEFAULT = 1000 * 60 * 15;
2621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* The provision apn alarm intent used to disable the provisioning apn */
2641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private PendingIntent mProvisioningApnAlarmIntent = null;
2651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Used to track stale provisioning apn alarms */
2671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mProvisioningApnAlarmTag = (int) SystemClock.elapsedRealtime();
2681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private AsyncChannel mReplyAc = new AsyncChannel();
2701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver () {
2721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
2731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void onReceive(Context context, Intent intent) {
2741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            String action = intent.getAction();
275c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu
2761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (action.equals(Intent.ACTION_SCREEN_ON)) {
277baecdb610b30a5d4b35345f8fc63fcbc2133c149Jack Yu                // TODO: Evaluate hooking this up with DeviceStateMonitor
278c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("screen on");
2791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mIsScreenOn = true;
2801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                stopNetStatPoll();
2811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                startNetStatPoll();
2821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartDataStallAlarm();
2831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
284c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("screen off");
2851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mIsScreenOn = false;
2861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                stopNetStatPoll();
2871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                startNetStatPoll();
2881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartDataStallAlarm();
2891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.startsWith(INTENT_RECONNECT_ALARM)) {
2901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("Reconnect alarm. Previous state was " + mState);
2911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onActionIntentReconnectAlarm(intent);
2921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(INTENT_DATA_STALL_ALARM)) {
293c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("Data stall alarm");
2941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onActionIntentDataStallAlarm(intent);
2951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(INTENT_PROVISIONING_APN_ALARM)) {
296c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("Provisioning apn alarm");
2971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onActionIntentProvisioningApnAlarm(intent);
2981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
2991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final android.net.NetworkInfo networkInfo = (NetworkInfo)
3001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
3011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mIsWifiConnected = (networkInfo != null && networkInfo.isConnected());
3021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("NETWORK_STATE_CHANGED_ACTION: mIsWifiConnected=" + mIsWifiConnected);
3031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
304c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("Wifi state changed");
3051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
3061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
3071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (!enabled) {
3081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // when WiFi got disabled, the NETWORK_STATE_CHANGED_ACTION
3091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // quit and won't report disconnected until next enabling.
3101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mIsWifiConnected = false;
3111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
3121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
3131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("WIFI_STATE_CHANGED_ACTION: enabled=" + enabled
3141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + " mIsWifiConnected=" + mIsWifiConnected);
3151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
316d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            } else if (action.equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
317d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                CarrierConfigManager configMgr = (CarrierConfigManager)
318d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                        mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
319d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                if (configMgr != null) {
320d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                    PersistableBundle cfg = configMgr.getConfigForSubId(mPhone.getSubId());
321d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                    if (cfg != null) mAllowUserEditTetherApn =
322d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                            cfg.getBoolean(CarrierConfigManager.KEY_EDITABLE_TETHER_APN_BOOL);
323d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                }
324c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            } else {
325c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("onReceive: Unknown action=" + action);
3261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
3271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    };
3291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final Runnable mPollNetStat = new Runnable() {
3311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
3321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void run() {
3331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            updateDataActivity();
3341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mIsScreenOn) {
3361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mNetStatPollPeriod = Settings.Global.getInt(mResolver,
3371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.PDP_WATCHDOG_POLL_INTERVAL_MS, POLL_NETSTAT_MILLIS);
3381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
3391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mNetStatPollPeriod = Settings.Global.getInt(mResolver,
3401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS,
3411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        POLL_NETSTAT_SCREEN_OFF_MILLIS);
3421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
3431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mNetStatPollEnabled) {
3451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mDataConnectionTracker.postDelayed(this, mNetStatPollPeriod);
3461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
3471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    };
3491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private SubscriptionManager mSubscriptionManager;
3511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final OnSubscriptionsChangedListener mOnSubscriptionsChangedListener =
3521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new OnSubscriptionsChangedListener() {
3531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                public final AtomicInteger mPreviousSubId =
3541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        new AtomicInteger(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
3551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                /**
3571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                 * Callback invoked when there is any change to any SubscriptionInfo. Typically
3581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                 * this method invokes {@link SubscriptionManager#getActiveSubscriptionInfoList}
3591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                 */
3601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                @Override
3611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                public void onSubscriptionsChanged() {
3621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (DBG) log("SubscriptionListener.onSubscriptionInfoChanged");
3631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // Set the network type, in case the radio does not restore it.
3641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    int subId = mPhone.getSubId();
3651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (SubscriptionManager.isValidSubscriptionId(subId)) {
366f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                        registerSettingsObserver();
3671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
3681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mPreviousSubId.getAndSet(subId) != subId &&
3691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            SubscriptionManager.isValidSubscriptionId(subId)) {
3701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onRecordsLoadedOrSubIdChanged();
3711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
3721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
3731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            };
3741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
375f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    private static class SettingsObserver extends ContentObserver {
376f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        final private HashMap<Uri, Integer> mUriEventMap;
377f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        final private Context mContext;
378f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        final private Handler mHandler;
379f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        final private static String TAG = "DcTracker.SettingsObserver";
3801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
381f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        SettingsObserver(Context context, Handler handler) {
382f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            super(null);
383f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            mUriEventMap = new HashMap<Uri, Integer>();
384f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            mContext = context;
385f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            mHandler = handler;
3861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
388f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        void observe(Uri uri, int what) {
389f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            mUriEventMap.put(uri, what);
390f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            final ContentResolver resolver = mContext.getContentResolver();
391f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            resolver.registerContentObserver(uri, false, this);
3921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
394f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        void unobserve() {
395f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            final ContentResolver resolver = mContext.getContentResolver();
396f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            resolver.unregisterContentObserver(this);
3971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
4001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void onChange(boolean selfChange) {
401f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            Rlog.e(TAG, "Should never be reached.");
402f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        }
403f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
404f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        @Override
405f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        public void onChange(boolean selfChange, Uri uri) {
406f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            final Integer what = mUriEventMap.get(uri);
407f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            if (what != null) {
408f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                mHandler.obtainMessage(what.intValue()).sendToTarget();
409f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            } else {
410f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                Rlog.e(TAG, "No matching event to send for URI=" + uri);
4111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
4121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
414f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
415f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    private final SettingsObserver mSettingsObserver;
416f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
417f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    private void registerSettingsObserver() {
418f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.unobserve();
419f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        String simSuffix = "";
420f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu        if (TelephonyManager.getDefault().getSimCount() > 1) {
421f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            simSuffix = Integer.toString(mPhone.getSubId());
422f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        }
423f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu
424f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.observe(
425f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                Settings.Global.getUriFor(Settings.Global.DATA_ROAMING + simSuffix),
426f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                DctConstants.EVENT_ROAMING_ON);
427f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.observe(
428f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
429f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE);
430f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.observe(
431f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED),
432f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE);
433f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    }
4341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
4361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Maintain the sum of transmit and receive packets.
4371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     *
4381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * The packet counts are initialized and reset to -1 and
4391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * remain -1 until they can be updated.
4401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
4411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public static class TxRxSum {
4421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public long txPkts;
4431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public long rxPkts;
4441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public TxRxSum() {
4461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            reset();
4471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public TxRxSum(long txPkts, long rxPkts) {
4501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.txPkts = txPkts;
4511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.rxPkts = rxPkts;
4521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public TxRxSum(TxRxSum sum) {
4551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            txPkts = sum.txPkts;
4561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            rxPkts = sum.rxPkts;
4571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void reset() {
4601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            txPkts = -1;
4611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            rxPkts = -1;
4621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
4651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public String toString() {
4661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return "{txSum=" + txPkts + " rxSum=" + rxPkts + "}";
4671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void updateTxRxSum() {
4701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.txPkts = TrafficStats.getMobileTcpTxPackets();
4711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.rxPkts = TrafficStats.getMobileTcpRxPackets();
4721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
4741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onActionIntentReconnectAlarm(Intent intent) {
4761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON);
4771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        String apnType = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE);
4781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int phoneSubId = mPhone.getSubId();
4801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int currSubId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
4811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
4821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("onActionIntentReconnectAlarm: currSubId = " + currSubId + " phoneSubId=" + phoneSubId);
4831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // Stop reconnect if not current subId is not correct.
4851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // FIXME STOPSHIP - phoneSubId is coming up as -1 way after boot and failing this?
4861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (!SubscriptionManager.isValidSubscriptionId(currSubId) || (currSubId != phoneSubId)) {
4871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("receive ReconnectAlarm but subId incorrect, ignore");
4881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return;
4891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnContext apnContext = mApnContexts.get(apnType);
4921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
4941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("onActionIntentReconnectAlarm: mState=" + mState + " reason=" + reason +
4951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " apnType=" + apnType + " apnContext=" + apnContext +
4961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " mDataConnectionAsyncChannels=" + mDataConnectionAcHashMap);
4971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if ((apnContext != null) && (apnContext.isEnabled())) {
5001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            apnContext.setReason(reason);
5011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            DctConstants.State apnContextState = apnContext.getState();
5021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
5031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("onActionIntentReconnectAlarm: apnContext state=" + apnContextState);
5041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
5051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if ((apnContextState == DctConstants.State.FAILED)
5061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    || (apnContextState == DctConstants.State.IDLE)) {
5071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
5081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("onActionIntentReconnectAlarm: state is FAILED|IDLE, disassociate");
5091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
5101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DcAsyncChannel dcac = apnContext.getDcAc();
5111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (dcac != null) {
5121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (DBG) {
5131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        log("onActionIntentReconnectAlarm: tearDown apnContext=" + apnContext);
5141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
5151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    dcac.tearDown(apnContext, "", null);
5161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
5171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                apnContext.setDataConnectionAc(null);
5181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                apnContext.setState(DctConstants.State.IDLE);
5191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
5201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("onActionIntentReconnectAlarm: keep associated");
5211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
5221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // TODO: IF already associated should we send the EVENT_TRY_SETUP_DATA???
5231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            sendMessage(obtainMessage(DctConstants.EVENT_TRY_SETUP_DATA, apnContext));
5241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            apnContext.setReconnectIntent(null);
5261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
5271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
5281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onActionIntentDataStallAlarm(Intent intent) {
5301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("onActionIntentDataStallAlarm: action=" + intent.getAction());
5311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_DATA_STALL_ALARM,
5321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                intent.getAction());
5331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = intent.getIntExtra(DATA_STALL_ALARM_TAG_EXTRA, 0);
5341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
5351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
5361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final ConnectivityManager mCm;
538c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
539b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla    /**
540a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * List of messages that are waiting to be posted, when data call disconnect
541a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * is complete
542a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
543a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ArrayList<Message> mDisconnectAllCompleteMsgList = new ArrayList<Message>();
544a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
545a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private RegistrantList mAllDataDisconnectedRegistrants = new RegistrantList();
546a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
5471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // member variables
5481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final Phone mPhone;
5491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final UiccController mUiccController;
5501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
5511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DctConstants.Activity mActivity = DctConstants.Activity.NONE;
5521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DctConstants.State mState = DctConstants.State.IDLE;
5531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final Handler mDataConnectionTracker;
5541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private long mTxPkts;
5561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private long mRxPkts;
5571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mNetStatPollPeriod;
5581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mNetStatPollEnabled = false;
5591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private TxRxSum mDataStallTxRxSum = new TxRxSum(0, 0);
5611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Used to track stale data stall alarms.
5621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mDataStallAlarmTag = (int) SystemClock.elapsedRealtime();
5631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // The current data stall alarm intent
5641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private PendingIntent mDataStallAlarmIntent = null;
5651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Number of packets sent since the last received packet
5661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private long mSentSinceLastRecv;
5671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Controls when a simple recovery attempt it to be tried
5681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mNoRecvPollCount = 0;
5690e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    // Reference counter for enabling fail fast
5701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static int sEnableFailFastRefCounter = 0;
5711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // True if data stall detection is enabled
5721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private volatile boolean mDataStallDetectionEnabled = true;
5731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private volatile boolean mFailFast = false;
5751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // True when in voice call
5771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mInVoiceCall = false;
5781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // wifi connection status will be updated by sticky intent
5801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsWifiConnected = false;
5811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Intent sent when the reconnect alarm fires. */
5831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private PendingIntent mReconnectIntent = null;
5841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // When false we will not auto attach and manually attaching is required.
5861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mAutoAttachOnCreationConfig = false;
5871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private AtomicBoolean mAutoAttachOnCreation = new AtomicBoolean(false);
5881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // State of screen
5901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // (TODO: Reconsider tying directly to screen, maybe this is
5911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    //        really a lower power mode")
5921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsScreenOn = true;
5931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Indicates if we found mvno-specific APNs in the full APN list.
5951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // used to determine if we can accept mno-specific APN for tethering.
5961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mMvnoMatched = false;
5971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Allows the generation of unique Id's for DataConnection objects */
5991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private AtomicInteger mUniqueIdGenerator = new AtomicInteger(0);
6001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** The data connections. */
6021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private HashMap<Integer, DataConnection> mDataConnections =
6031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new HashMap<Integer, DataConnection>();
6041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** The data connection async channels */
6061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private HashMap<Integer, DcAsyncChannel> mDataConnectionAcHashMap =
6071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new HashMap<Integer, DcAsyncChannel>();
6081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Convert an ApnType string to Id (TODO: Use "enumeration" instead of String for ApnType) */
6101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private HashMap<String, Integer> mApnToDataConnectionId = new HashMap<String, Integer>();
6111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Phone.APN_TYPE_* ===> ApnContext */
6131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final ConcurrentHashMap<String, ApnContext> mApnContexts =
6141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new ConcurrentHashMap<String, ApnContext>();
6151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
616af5593594070f825032be46dced573cd195956e1Robert Greenwalt    private final SparseArray<ApnContext> mApnContextsById = new SparseArray<ApnContext>();
617af5593594070f825032be46dced573cd195956e1Robert Greenwalt
6181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mDisconnectPendingCount = 0;
619a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
6204c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu    /** Indicate if metered APNs are disabled.
6214c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu     *  set to block all the metered APNs from continuously sending requests, which causes
6224c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu     *  undesired network load */
6234c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu    private boolean mMeteredApnDisabled = false;
62468f4f4a0bc8d4060b5775e7a24a97ea5b485989efionaxu
625a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
6264b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * int to remember whether has setDataProfiles and with roaming or not.
6274b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * 0: default, has never set data profile
6284b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * 1: has set data profile with home protocol
6294b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * 2: has set data profile with roaming protocol
6304b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     * This is not needed once RIL command is updated to support both home and roaming protocol.
6314b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu     */
6324b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu    private int mSetDataProfileStatus = 0;
6334b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu
6344b17d6f820839eb663ee4493b48a0184be7aefd4Junda Liu    /**
635d92c67aa965200385acf3182ffb0af25297a366fJunda Liu     * Whether carrier allow user edited tether APN. Updated by carrier config
636d92c67aa965200385acf3182ffb0af25297a366fJunda Liu     * KEY_EDITABLE_TETHER_APN_BOOL
637d92c67aa965200385acf3182ffb0af25297a366fJunda Liu     * If true, APN with dun type from database will be used, see fetchDunApn for details.
638d92c67aa965200385acf3182ffb0af25297a366fJunda Liu     */
639d92c67aa965200385acf3182ffb0af25297a366fJunda Liu    private boolean mAllowUserEditTetherApn = false;
640d92c67aa965200385acf3182ffb0af25297a366fJunda Liu
641d92c67aa965200385acf3182ffb0af25297a366fJunda Liu    /**
642cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Handles changes to the APN db.
643b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla     */
644cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private class ApnChangeObserver extends ContentObserver {
645cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public ApnChangeObserver () {
646cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            super(mDataConnectionTracker);
647cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
648c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
649cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
650cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public void onChange(boolean selfChange) {
651cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            sendMessage(obtainMessage(DctConstants.EVENT_APN_CHANGED));
652cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
653cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
654c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
655cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Instance Variables
656c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
657cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean mReregisterOnReconnectFailure = false;
658c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
659c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
660cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Constants
661c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
662ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    // Used by puppetmaster/*/radio_stress.py
663ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private static final String PUPPET_MASTER_RADIO_STRESS_TEST = "gsm.defaultpdpcontext.active";
664c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
665ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private static final int POLL_PDP_MILLIS = 5 * 1000;
666c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
6672b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen    private static final int PROVISIONING_SPINNER_TIMEOUT_MILLIS = 120 * 1000;
6682b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen
6696bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville    static final Uri PREFERAPN_NO_UPDATE_URI_USING_SUBID =
6706bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville                        Uri.parse("content://telephony/carriers/preferapn_no_update/subId/");
671cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final String APN_ID = "apn_id";
672cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
673ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private boolean mCanSetPreferApn = false;
674c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
675187a39f896f88eb6c5e4306d9595546654825976Wink Saville    private AtomicBoolean mAttached = new AtomicBoolean(false);
676187a39f896f88eb6c5e4306d9595546654825976Wink Saville
677cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** Watches for changes to the APN db. */
678cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ApnChangeObserver mApnObserver;
679cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
680b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private final String mProvisionActionName;
681b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private BroadcastReceiver mProvisionBroadcastReceiver;
6822b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen    private ProgressDialog mProvisioningSpinner;
683b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
684a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean mImsRegistrationState = false;
685a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
686cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Constructor
6871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public DcTracker(Phone phone) {
6881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        super();
6891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone = phone;
6901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("DCT.constructor");
6921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mResolver = mPhone.getContext().getContentResolver();
6941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mUiccController = UiccController.getInstance();
6951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mUiccController.registerForIccChanged(this, DctConstants.EVENT_ICC_CHANGED, null);
6961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mAlarmManager =
6971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
6981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mCm = (ConnectivityManager) mPhone.getContext().getSystemService(
6991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Context.CONNECTIVITY_SERVICE);
7001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        IntentFilter filter = new IntentFilter();
7031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(Intent.ACTION_SCREEN_ON);
7041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(Intent.ACTION_SCREEN_OFF);
7051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
7061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
7071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(INTENT_DATA_STALL_ALARM);
7081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(INTENT_PROVISIONING_APN_ALARM);
709d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
7101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // TODO - redundent with update call below?
712a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        mDataEnabledSettings.setUserDataEnabled(getDataEnabled());
7131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
7151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
7171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mAutoAttachOnCreation.set(sp.getBoolean(Phone.DATA_DISABLED_ON_BOOT_KEY, false));
7181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mSubscriptionManager = SubscriptionManager.from(mPhone.getContext());
7201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
7211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        HandlerThread dcHandlerThread = new HandlerThread("DcHandlerThread");
7231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        dcHandlerThread.start();
7241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Handler dcHandler = new Handler(dcHandlerThread.getLooper());
7251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcc = DcController.makeDcc(mPhone, this, dcHandler);
7261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcTesterFailBringUpAll = new DcTesterFailBringUpAll(mPhone, dcHandler);
727cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
728cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mDataConnectionTracker = this;
729c374098c17a81f73f51e9d7df99eba574882949bYifan Bai        registerForAllEvents();
730a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        update();
731cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mApnObserver = new ApnChangeObserver();
7321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        phone.getContext().getContentResolver().registerContentObserver(
733cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                Telephony.Carriers.CONTENT_URI, true, mApnObserver);
734cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
735d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        initApnContexts();
736d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
737d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        for (ApnContext apnContext : mApnContexts.values()) {
738d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            // Register the reconnect and restart actions.
7391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            filter = new IntentFilter();
740d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            filter.addAction(INTENT_RECONNECT_ALARM + '.' + apnContext.getApnType());
741d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
742d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        }
743d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
74476f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Add Emergency APN to APN setting list by default to support EPDN in sim absent cases
74576f43316a5a6082d601bffd4b6898d0bd81e11fcram        initEmergencyApnSetting();
74676f43316a5a6082d601bffd4b6898d0bd81e11fcram        addEmergencyApnSetting();
747b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
7481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisionActionName = "com.android.internal.telephony.PROVISION" + phone.getPhoneId();
749f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
750f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver = new SettingsObserver(mPhone.getContext(), this);
751f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        registerSettingsObserver();
7521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
7531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
754af5593594070f825032be46dced573cd195956e1Robert Greenwalt    @VisibleForTesting
755af5593594070f825032be46dced573cd195956e1Robert Greenwalt    public DcTracker() {
756af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mAlarmManager = null;
757af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mCm = null;
758af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mPhone = null;
759af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mUiccController = null;
760af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mDataConnectionTracker = null;
761af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mProvisionActionName = null;
762f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver = new SettingsObserver(null, this);
763af5593594070f825032be46dced573cd195956e1Robert Greenwalt    }
764af5593594070f825032be46dced573cd195956e1Robert Greenwalt
7651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void registerServiceStateTrackerEvents() {
7661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataConnectionAttached(this,
7671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null);
7681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataConnectionDetached(this,
7691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_DATA_CONNECTION_DETACHED, null);
7701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataRoamingOn(this,
7711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_ROAMING_ON, null);
7721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataRoamingOff(this,
7731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_ROAMING_OFF, null);
7741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForPsRestrictedEnabled(this,
7751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_PS_RESTRICT_ENABLED, null);
7761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForPsRestrictedDisabled(this,
7771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_PS_RESTRICT_DISABLED, null);
7781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(this,
7791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_DATA_RAT_CHANGED, null);
780cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
781c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
7821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void unregisterServiceStateTrackerEvents() {
7831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataConnectionAttached(this);
7841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataConnectionDetached(this);
7851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataRoamingOn(this);
7861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataRoamingOff(this);
7871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForPsRestrictedEnabled(this);
7881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForPsRestrictedDisabled(this);
7891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged(this);
7901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
7911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void registerForAllEvents() {
793a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.mCi.registerForAvailable(this, DctConstants.EVENT_RADIO_AVAILABLE, null);
794a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.mCi.registerForOffOrNotAvailable(this,
7959c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
79637a3e51d244774ba156a88cf101432b62c8a42a3Jack Yu        mPhone.mCi.registerForDataCallListChanged(this,
7979c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                DctConstants.EVENT_DATA_STATE_CHANGED, null);
7980710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // Note, this is fragile - the Phone is now presenting a merged picture
7990710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // of PS (volte) & CS and by diving into its internals you're just seeing
8000710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // the CS data.  This works well for the purposes this is currently used for
8010710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // but that may not always be the case.  Should probably be redesigned to
8020710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // accurately reflect what we're really interested in (registerForCSVoiceCallEnded).
8031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getCallTracker().registerForVoiceCallEnded(this,
8041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_VOICE_CALL_ENDED, null);
8051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getCallTracker().registerForVoiceCallStarted(this,
8061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_VOICE_CALL_STARTED, null);
8071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        registerServiceStateTrackerEvents();
808a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     //   SubscriptionManager.registerForDdsSwitch(this,
809a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     //          DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS, null);
8102e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        mPhone.mCi.registerForPcoData(this, DctConstants.EVENT_PCO_DATA_RECEIVED, null);
8116a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu        mPhone.getCarrierActionAgent().registerForCarrierAction(
8126a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu                CarrierActionAgent.CARRIER_ACTION_SET_METERED_APNS_ENABLED, this,
8136a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu                DctConstants.EVENT_SET_CARRIER_DATA_ENABLED, null, false);
814a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
8151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
816cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void dispose() {
8171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("DCT.dispose");
8184dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt
819b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        if (mProvisionBroadcastReceiver != null) {
820b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            mPhone.getContext().unregisterReceiver(mProvisionBroadcastReceiver);
821b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            mProvisionBroadcastReceiver = null;
822b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
8232b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        if (mProvisioningSpinner != null) {
8242b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.dismiss();
8252b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner = null;
8262b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        }
827b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
828cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, null);
829cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
8301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
8311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            dcac.disconnect();
8321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
8331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDataConnectionAcHashMap.clear();
8341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mIsDisposed = true;
8351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getContext().unregisterReceiver(mIntentReceiver);
8361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mUiccController.unregisterForIccChanged(this);
837f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.unobserve();
838f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
8391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mSubscriptionManager
8401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                .removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
8411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcc.dispose();
8421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcTesterFailBringUpAll.dispose();
843cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
844a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getContext().getContentResolver().unregisterContentObserver(mApnObserver);
845a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mApnContexts.clear();
846af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mApnContextsById.clear();
847a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPrioritySortedApnContexts.clear();
848c374098c17a81f73f51e9d7df99eba574882949bYifan Bai        unregisterForAllEvents();
849a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
850a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        destroyDataConnections();
851a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
8521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void unregisterForAllEvents() {
854a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         //Unregister for all events
85522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.unregisterForAvailable(this);
85622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.unregisterForOffOrNotAvailable(this);
857cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
858a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (r != null) {
859a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            r.unregisterForRecordsLoaded(this);
860a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mIccRecords.set(null);
861a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
86237a3e51d244774ba156a88cf101432b62c8a42a3Jack Yu        mPhone.mCi.unregisterForDataCallListChanged(this);
863cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getCallTracker().unregisterForVoiceCallEnded(this);
864cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getCallTracker().unregisterForVoiceCallStarted(this);
8651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        unregisterServiceStateTrackerEvents();
866a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        //SubscriptionManager.unregisterForDdsSwitch(this);
8672e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        mPhone.mCi.unregisterForPcoData(this);
8686a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu        mPhone.getCarrierActionAgent().unregisterForCarrierAction(this,
8696a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu                CarrierActionAgent.CARRIER_ACTION_SET_METERED_APNS_ENABLED);
870cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
871cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
8721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
8731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Called when EVENT_RESET_DONE is received so goto
8741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * IDLE state and send notifications to those interested.
8751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     *
8761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * TODO - currently unused.  Needs to be hooked into DataConnection cleanup
8771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * TODO - needs to pass some notion of which connection is reset..
8781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
8791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onResetDone(AsyncResult ar) {
8801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("EVENT_RESET_DONE");
8811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        String reason = null;
8821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (ar.userObj instanceof String) {
8831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            reason = (String) ar.userObj;
8841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
8851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        gotoIdleAndNotifyDataConnection(reason);
8861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
8871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
8891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Modify {@link android.provider.Settings.Global#MOBILE_DATA} value.
8901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
8911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void setDataEnabled(boolean enable) {
8921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.CMD_SET_USER_DATA_ENABLE);
8931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = enable ? 1 : 0;
8941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("setDataEnabled: sendMessage: enable=" + enable);
8951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
8961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
8971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetUserDataEnabled(boolean enabled) {
899a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        synchronized (mDataEnabledSettings) {
900a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            if (mDataEnabledSettings.isUserDataEnabled() != enabled) {
901a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                mDataEnabledSettings.setUserDataEnabled(enabled);
9021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
903a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                //TODO: We should move the followings into DataEnabledSettings class.
9041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // For single SIM phones, this is a per phone property.
9051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (TelephonyManager.getDefault().getSimCount() == 1) {
9061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    Settings.Global.putInt(mResolver, Settings.Global.MOBILE_DATA, enabled ? 1 : 0);
9071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
9081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    int phoneSubId = mPhone.getSubId();
9091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    Settings.Global.putInt(mResolver, Settings.Global.MOBILE_DATA + phoneSubId,
9101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            enabled ? 1 : 0);
9111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
9125b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu                if (!getDataRoamingEnabled() && mPhone.getServiceState().getDataRoaming()) {
9131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (enabled) {
9141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
9151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
9161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        notifyOffApnsOfAvailability(Phone.REASON_DATA_DISABLED);
9171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
9181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
9191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
920a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                // TODO: We should register for DataEnabledSetting's data enabled/disabled event and
921a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                // handle the rest from there.
9221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (enabled) {
923120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    reevaluateDataConnections();
9241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onTrySetupData(Phone.REASON_DATA_ENABLED);
9251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
9261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);
9271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
9281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
9291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
9301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
9311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
9325292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt    /**
933120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * Reevaluate existing data connections when conditions change.
934120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     *
935120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * For example, handle reverting restricted networks back to unrestricted. If we're changing
936120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * user data to enabled and this makes data truly enabled (not disabled by other factors) we
937120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * need to tear down any metered apn type that was enabled anyway by a privileged request.
938120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * This allows us to reconnect to it in an unrestricted way.
939120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     *
940120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * Or when we brought up a unmetered data connection while data is off, we only limit this
941120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * data connection for unmetered use only. When data is turned back on, we need to tear that
942120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu     * down so a full capable data connection can be re-established.
9435292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt     */
944120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu    private void reevaluateDataConnections() {
945120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        if (mDataEnabledSettings.isDataEnabled()) {
9465292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt            for (ApnContext apnContext : mApnContexts.values()) {
947120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                if (apnContext.isConnectedOrConnecting()) {
948120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    final DcAsyncChannel dcac = apnContext.getDcAc();
949120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    if (dcac != null) {
950120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                        final NetworkCapabilities netCaps = dcac.getNetworkCapabilitiesSync();
951120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                        if (netCaps != null && !netCaps.hasCapability(NetworkCapabilities
952120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                                .NET_CAPABILITY_NOT_RESTRICTED)) {
953120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            if (DBG) {
954120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                                log("Tearing down restricted net:" + apnContext);
955120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            }
956120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // Tearing down the restricted data call (metered or unmetered) when
957120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // conditions change. This will allow reestablishing a new unrestricted
958120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // data connection.
959120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            apnContext.setReason(Phone.REASON_DATA_ENABLED);
960120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            cleanUpConnection(true, apnContext);
961120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                        } else if (apnContext.getApnSetting().isMetered(mPhone.getContext(),
962120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                                mPhone.getSubId(), mPhone.getServiceState().getDataRoaming())
963120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                                && (netCaps != null && netCaps.hasCapability(
964120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                                        NetworkCapabilities.NET_CAPABILITY_NOT_METERED))) {
965120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            if (DBG) {
966120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                                log("Tearing down unmetered net:" + apnContext);
967120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            }
968120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // The APN settings is metered, but the data was still marked as
969120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // unmetered data, must be the unmetered data connection brought up when
970120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // data is off. We need to tear that down when data is enabled again.
971120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            // This will allow reestablishing a new full capability data connection.
972120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            apnContext.setReason(Phone.REASON_DATA_ENABLED);
973120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                            cleanUpConnection(true, apnContext);
97476c5a9479d312139740dcaf7644172f2beb2f7e0Robert Greenwalt                        }
97576c5a9479d312139740dcaf7644172f2beb2f7e0Robert Greenwalt                    }
9765292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt                }
9775292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt            }
9785292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt        }
9795292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt    }
9805292d0e24a73aed20bb3ed8591c0ac6005a0e3c9Robert Greenwalt
981f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    private void onDeviceProvisionedChange() {
982f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        if (getDataEnabled()) {
983a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            mDataEnabledSettings.setUserDataEnabled(true);
984120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu            reevaluateDataConnections();
985f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            onTrySetupData(Phone.REASON_DATA_ENABLED);
986f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        } else {
987a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            mDataEnabledSettings.setUserDataEnabled(false);
988f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);
989f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        }
990f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    }
9911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
9921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
9931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public long getSubId() {
9941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mPhone.getSubId();
9951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
9961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
9971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public DctConstants.Activity getActivity() {
9981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mActivity;
9991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
10001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
10011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void setActivity(DctConstants.Activity activity) {
10021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("setActivity = " + activity);
10031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mActivity = activity;
10041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.notifyDataActivity();
10051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
10061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1007af5593594070f825032be46dced573cd195956e1Robert Greenwalt    public void requestNetwork(NetworkRequest networkRequest, LocalLog log) {
1008af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final int apnId = ApnContext.apnIdForNetworkRequest(networkRequest);
1009af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final ApnContext apnContext = mApnContextsById.get(apnId);
1010af5593594070f825032be46dced573cd195956e1Robert Greenwalt        log.log("DcTracker.requestNetwork for " + networkRequest + " found " + apnContext);
1011692640f429efa8e292c6261472b2c682e1079f8eRobert Greenwalt        if (apnContext != null) apnContext.requestNetwork(networkRequest, log);
1012af5593594070f825032be46dced573cd195956e1Robert Greenwalt    }
1013af5593594070f825032be46dced573cd195956e1Robert Greenwalt
1014af5593594070f825032be46dced573cd195956e1Robert Greenwalt    public void releaseNetwork(NetworkRequest networkRequest, LocalLog log) {
1015af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final int apnId = ApnContext.apnIdForNetworkRequest(networkRequest);
1016af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final ApnContext apnContext = mApnContextsById.get(apnId);
1017af5593594070f825032be46dced573cd195956e1Robert Greenwalt        log.log("DcTracker.releaseNetwork for " + networkRequest + " found " + apnContext);
1018692640f429efa8e292c6261472b2c682e1079f8eRobert Greenwalt        if (apnContext != null) apnContext.releaseNetwork(networkRequest, log);
1019af5593594070f825032be46dced573cd195956e1Robert Greenwalt    }
1020af5593594070f825032be46dced573cd195956e1Robert Greenwalt
1021bda761320929f714951c328bfec6a51a1978db97Wink Saville    public boolean isApnSupported(String name) {
102291bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal        if (name == null) {
102391bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal            loge("isApnSupported: name=null");
102491bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal            return false;
102591bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal        }
1026bda761320929f714951c328bfec6a51a1978db97Wink Saville        ApnContext apnContext = mApnContexts.get(name);
1027bda761320929f714951c328bfec6a51a1978db97Wink Saville        if (apnContext == null) {
1028bda761320929f714951c328bfec6a51a1978db97Wink Saville            loge("Request for unsupported mobile name: " + name);
1029bda761320929f714951c328bfec6a51a1978db97Wink Saville            return false;
1030071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
1031bda761320929f714951c328bfec6a51a1978db97Wink Saville        return true;
1032bda761320929f714951c328bfec6a51a1978db97Wink Saville    }
1033071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
1034bda761320929f714951c328bfec6a51a1978db97Wink Saville    public int getApnPriority(String name) {
1035071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        ApnContext apnContext = mApnContexts.get(name);
1036071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (apnContext == null) {
1037bda761320929f714951c328bfec6a51a1978db97Wink Saville            loge("Request for unsupported mobile name: " + name);
1038071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
1039bda761320929f714951c328bfec6a51a1978db97Wink Saville        return apnContext.priority;
1040071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt    }
1041071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
1042b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    // Turn telephony radio on or off.
1043b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private void setRadio(boolean on) {
1044b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        final ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
1045b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        try {
1046b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            phone.setRadio(on);
1047b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        } catch (Exception e) {
1048b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            // Ignore.
1049b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
1050b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    }
1051b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
1052b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    // Class to handle Intent dispatched with user selects the "Sign-in to network"
1053b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    // notification.
1054b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private class ProvisionNotificationBroadcastReceiver extends BroadcastReceiver {
10552b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        private final String mNetworkOperator;
1056b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        // Mobile provisioning URL.  Valid while provisioning notification is up.
1057b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        // Set prior to notification being posted as URL contains ICCID which
1058b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        // disappears when radio is off (which is the case when notification is up).
1059b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        private final String mProvisionUrl;
1060b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
10612b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        public ProvisionNotificationBroadcastReceiver(String provisionUrl, String networkOperator) {
10622b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mNetworkOperator = networkOperator;
1063b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            mProvisionUrl = provisionUrl;
1064b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
1065b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
1066b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        private void setEnableFailFastMobileData(int enabled) {
10676395443719ec3ee0257085945e753d02f603886bRobert Greenwalt            sendMessage(obtainMessage(DctConstants.CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA, enabled, 0));
1068b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
1069b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
1070b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        private void enableMobileProvisioning() {
1071b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            final Message msg = obtainMessage(DctConstants.CMD_ENABLE_MOBILE_PROVISIONING);
1072b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            msg.setData(Bundle.forPair(DctConstants.PROVISIONING_URL_KEY, mProvisionUrl));
1073b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            sendMessage(msg);
1074b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
1075b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
1076b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        @Override
1077b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        public void onReceive(Context context, Intent intent) {
10782b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // Turning back on the radio can take time on the order of a minute, so show user a
10792b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // spinner so they know something is going on.
1080636fbb01fd32e23d1e9ef86497115b2c992b03daSanket Padawe            log("onReceive : ProvisionNotificationBroadcastReceiver");
10812b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner = new ProgressDialog(context);
10822b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setTitle(mNetworkOperator);
10832b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setMessage(
10842b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    // TODO: Don't borrow "Connecting..." i18n string; give Telephony a version.
10852b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    context.getText(com.android.internal.R.string.media_route_status_connecting));
10862b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setIndeterminate(true);
10872b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setCancelable(true);
10882b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // Allow non-Activity Service Context to create a View.
10892b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.getWindow().setType(
10902b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
10912b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.show();
10922b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // After timeout, hide spinner so user can at least use their device.
10932b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // TODO: Indicate to user that it is taking an unusually long time to connect?
10942b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            sendMessageDelayed(obtainMessage(DctConstants.CMD_CLEAR_PROVISIONING_SPINNER,
10952b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner), PROVISIONING_SPINNER_TIMEOUT_MILLIS);
1096b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            // This code is almost identical to the old
1097b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            // ConnectivityService.handleMobileProvisioningAction code.
1098b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            setRadio(true);
1099b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            setEnableFailFastMobileData(DctConstants.ENABLED);
1100b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            enableMobileProvisioning();
1101b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
1102b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    }
1103b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
1104cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isDataPossible(String apnType) {
1105cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1106cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
1107cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
1108cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1109cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean apnContextIsEnabled = apnContext.isEnabled();
1110cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        DctConstants.State apnContextState = apnContext.getState();
1111cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean apnTypePossible = !(apnContextIsEnabled &&
1112cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                (apnContextState == DctConstants.State.FAILED));
1113cf5205f70eb1eac497164124187a088ecb03fff5Ram        boolean isEmergencyApn = apnContext.getApnType().equals(PhoneConstants.APN_TYPE_EMERGENCY);
1114cf5205f70eb1eac497164124187a088ecb03fff5Ram        // Set the emergency APN availability status as TRUE irrespective of conditions checked in
1115cf5205f70eb1eac497164124187a088ecb03fff5Ram        // isDataAllowed() like IN_SERVICE, MOBILE DATA status etc.
11169c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        boolean dataAllowed = isEmergencyApn || isDataAllowed(null);
1117cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean possible = dataAllowed && apnTypePossible;
1118cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
11190e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        if ((apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
11200e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                    || apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IA))
11210e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                && (mPhone.getServiceState().getRilDataRadioTechnology()
11220e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN)) {
11230e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            log("Default data call activation not possible in iwlan.");
11240e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            possible = false;
11250e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        }
11260e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh
1127ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (VDBG) {
1128cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log(String.format("isDataPossible(%s): possible=%b isDataAllowed=%b " +
1129a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                            "apnTypePossible=%b apnContextisEnabled=%b apnContextState()=%s",
1130cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnType, possible, dataAllowed, apnTypePossible,
1131cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContextIsEnabled, apnContextState));
1132cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1133cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return possible;
1134cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1135cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1136cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1137cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void finalize() {
11387e9240253edb59e0aa657de434faa1ccdf17a742Amit Mahajan        if(DBG && mPhone != null) log("finalize");
1139cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1140cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
11414a9b3afeb2ec4d573eca335a3706392ecf9f281eWink Saville    private ApnContext addApnContext(String type, NetworkConfig networkConfig) {
11420e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        ApnContext apnContext = new ApnContext(mPhone, type, LOG_TAG, networkConfig, this);
1143cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mApnContexts.put(type, apnContext);
1144af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mApnContextsById.put(ApnContext.apnIdForApnName(type), apnContext);
11453fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        mPrioritySortedApnContexts.add(apnContext);
1146bce3d2575122929bb27ec8a37d56e96da39a3ca2Robert Greenwalt        return apnContext;
1147cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1148c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
11491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void initApnContexts() {
1150d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        log("initApnContexts: E");
1151d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        // Load device network attributes from resources
1152d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        String[] networkConfigStrings = mPhone.getContext().getResources().getStringArray(
1153d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                com.android.internal.R.array.networkAttributes);
1154d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        for (String networkConfigString : networkConfigStrings) {
1155d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            NetworkConfig networkConfig = new NetworkConfig(networkConfigString);
1156d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            ApnContext apnContext = null;
1157d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
1158d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            switch (networkConfig.type) {
1159d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE:
1160d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_DEFAULT, networkConfig);
1161d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1162d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_MMS:
1163d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_MMS, networkConfig);
1164d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1165d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_SUPL:
1166d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_SUPL, networkConfig);
1167d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1168d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_DUN:
1169d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_DUN, networkConfig);
1170d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1171d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_HIPRI:
1172d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_HIPRI, networkConfig);
1173d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1174d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_FOTA:
1175d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_FOTA, networkConfig);
1176d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1177d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_IMS:
1178d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_IMS, networkConfig);
1179d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1180d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_CBS:
1181d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_CBS, networkConfig);
1182d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1183d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_IA:
1184d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_IA, networkConfig);
1185d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1186cf5205f70eb1eac497164124187a088ecb03fff5Ram            case ConnectivityManager.TYPE_MOBILE_EMERGENCY:
1187cf5205f70eb1eac497164124187a088ecb03fff5Ram                apnContext = addApnContext(PhoneConstants.APN_TYPE_EMERGENCY, networkConfig);
1188cf5205f70eb1eac497164124187a088ecb03fff5Ram                break;
1189d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            default:
1190d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                log("initApnContexts: skipping unknown type=" + networkConfig.type);
1191d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                continue;
1192d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            }
1193d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            log("initApnContexts: apnContext=" + apnContext);
1194d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        }
1195092e6bd60f1a4a3a55fb73ad0efca1122b8e15e2Jack Yu
1196092e6bd60f1a4a3a55fb73ad0efca1122b8e15e2Jack Yu        if (VDBG) log("initApnContexts: X mApnContexts=" + mApnContexts);
1197d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt    }
1198d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
1199cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public LinkProperties getLinkProperties(String apnType) {
1200cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1201cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
1202454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = apnContext.getDcAc();
1203cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac != null) {
1204cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("return link properites for " + apnType);
1205cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return dcac.getLinkPropertiesSync();
1206cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1207cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1208cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("return new LinkProperties");
1209cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return new LinkProperties();
1210cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1211cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1212608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt    public NetworkCapabilities getNetworkCapabilities(String apnType) {
1213608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        ApnContext apnContext = mApnContexts.get(apnType);
1214608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        if (apnContext!=null) {
1215608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            DcAsyncChannel dataConnectionAc = apnContext.getDcAc();
1216608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            if (dataConnectionAc != null) {
1217608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                if (DBG) {
1218608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                    log("get active pdp is not null, return NetworkCapabilities for " + apnType);
1219608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                }
1220608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                return dataConnectionAc.getNetworkCapabilitiesSync();
1221608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            }
1222608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        }
1223608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        if (DBG) log("return new NetworkCapabilities");
1224608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        return new NetworkCapabilities();
1225608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt    }
1226cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1227cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return all active apn types
1228cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public String[] getActiveApnTypes() {
1229cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("get all active apn types");
1230cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ArrayList<String> result = new ArrayList<String>();
1231cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1232cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1233187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (mAttached.get() && apnContext.isReady()) {
1234cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                result.add(apnContext.getApnType());
1235cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
1236cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1237c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1238cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result.toArray(new String[0]);
1239cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1240cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1241cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return active apn of specific apn type
1242cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public String getActiveApnString(String apnType) {
1243ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (VDBG) log( "get active apn string for type:" + apnType);
1244cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1245cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
1246cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ApnSetting apnSetting = apnContext.getApnSetting();
1247cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnSetting != null) {
1248cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return apnSetting.apn;
1249cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1250cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1251cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
1252cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1253cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1254cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return state of specific apn type
1255cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public DctConstants.State getState(String apnType) {
1256cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1257cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
1258cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return apnContext.getState();
1259c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1260cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return DctConstants.State.FAILED;
1261cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1262c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1263c9b81a0c05128694c617fcdd67e73821895822feWink Saville    // Return if apn type is a provisioning apn.
12641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean isProvisioningApn(String apnType) {
1265c9b81a0c05128694c617fcdd67e73821895822feWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1266c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (apnContext != null) {
1267c9b81a0c05128694c617fcdd67e73821895822feWink Saville            return apnContext.isProvisioningApn();
1268c9b81a0c05128694c617fcdd67e73821895822feWink Saville        }
1269c9b81a0c05128694c617fcdd67e73821895822feWink Saville        return false;
1270c9b81a0c05128694c617fcdd67e73821895822feWink Saville    }
1271c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1272cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return state of overall
1273cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public DctConstants.State getOverallState() {
1274cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isConnecting = false;
1275cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isFailed = true; // All enabled Apns should be FAILED.
1276cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isAnyEnabled = false;
1277cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1278cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1279cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.isEnabled()) {
1280cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                isAnyEnabled = true;
1281cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                switch (apnContext.getState()) {
1282cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case CONNECTED:
1283cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case DISCONNECTING:
12841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (VDBG) log("overall state is CONNECTED");
1285cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return DctConstants.State.CONNECTED;
1286ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                case RETRYING:
1287cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case CONNECTING:
1288cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isConnecting = true;
1289cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isFailed = false;
1290cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
1291cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case IDLE:
1292cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case SCANNING:
1293cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isFailed = false;
1294cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
1295cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                default:
1296cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isAnyEnabled = true;
1297cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
1298cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1299cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1300c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1301c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1302cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (!isAnyEnabled) { // Nothing enabled. return IDLE.
13031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is IDLE");
1304cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.IDLE;
1305c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1306c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1307cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnecting) {
13081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is CONNECTING");
1309cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.CONNECTING;
1310cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (!isFailed) {
13111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is IDLE");
1312cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.IDLE;
1313cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
13141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is FAILED");
1315cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.FAILED;
1316c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1317c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1318c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1319cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1320cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Report on whether data connectivity is enabled for any APN.
1321cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return {@code false} if data connectivity has been explicitly disabled,
1322cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * {@code true} otherwise.
1323cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1324cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean getAnyDataEnabled() {
1325120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        if (!mDataEnabledSettings.isDataEnabled()) return false;
13263d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        DataAllowFailReason failureReason = new DataAllowFailReason();
13273d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!isDataAllowed(failureReason)) {
13283d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if (DBG) log(failureReason.getDataAllowFailReason());
1329cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
1330c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
13313d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        for (ApnContext apnContext : mApnContexts.values()) {
13323d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            // Make sure we don't have a context that is going down
13333d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            // and is explicitly disabled.
13343d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if (isDataAllowedForApn(apnContext)) {
13353d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                return true;
13363d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            }
13373d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13383d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        return false;
1339c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1340c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
13410b03bcd1eccc833d5cac5ecf937cf0e037375561Jack Yu    @VisibleForTesting
1342120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu    public boolean isDataEnabled() {
1343120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        return mDataEnabledSettings.isDataEnabled();
1344a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1345a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
13469c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu    private boolean isDataAllowedForApn(ApnContext apnContext) {
13470e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        //If RAT is iwlan then dont allow default/IA PDP at all.
13480e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        //Rest of APN types can be evaluated for remaining conditions.
13490e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        if ((apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
13500e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                    || apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IA))
13510e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                && (mPhone.getServiceState().getRilDataRadioTechnology()
13520e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN)) {
13530e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            log("Default data call activation not allowed in iwlan.");
13540e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            return false;
13550e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        }
13569c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu
13579c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        return apnContext.isReady();
1358c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1359c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1360cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //****** Called from ServiceStateTracker
1361c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1362cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Invoked when ServiceStateTracker observes a transition from GPRS
1363cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * attach to detach.
1364c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
13651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataConnectionDetached() {
1366cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        /*
1367cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * We presently believe it is unnecessary to tear down the PDP context
1368cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * when GPRS detaches, but we should stop the network polling.
1369cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         */
1370cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log ("onDataConnectionDetached: stop polling and notify detached");
1371cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopNetStatPoll();
1372cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopDataStallAlarm();
1373cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyDataConnection(Phone.REASON_DATA_DETACHED);
1374187a39f896f88eb6c5e4306d9595546654825976Wink Saville        mAttached.set(false);
1375cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1376c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1377cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onDataConnectionAttached() {
1378cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onDataConnectionAttached");
13797ab10e4710bdb54c6d9a5ee01cd443a42a2689f5Sungmin Choi        mAttached.set(true);
1380cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getOverallState() == DctConstants.State.CONNECTED) {
1381cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onDataConnectionAttached: start polling notify attached");
1382cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            startNetStatPoll();
1383cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
1384cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_DATA_ATTACHED);
1385cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1386cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // update APN availability so that APN can be enabled.
1387cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_DATA_ATTACHED);
1388cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
138912fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        if (mAutoAttachOnCreationConfig) {
1390aacc11b299ac047e73e1e712aa396ea0a6a80158Robert Greenwalt            mAutoAttachOnCreation.set(true);
139112fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        }
1392ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(Phone.REASON_DATA_ATTACHED);
1393cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1394c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
13953d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu    private boolean isDataAllowed(DataAllowFailReason failureReason) {
1396cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        final boolean internalDataEnabled;
1397a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        internalDataEnabled = mDataEnabledSettings.isInternalDataEnabled();
1398cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
13999894b3fb2f35e21d9cfd45f233ed093589e14c26sy.yun        boolean attachedState = mAttached.get();
1400cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
14010d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu        boolean radioStateFromCarrier = mPhone.getServiceStateTracker().getPowerStateFromCarrier();
14020e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
14030e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        if (radioTech == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN) {
14040e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            desiredPowerState = true;
14050d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu            radioStateFromCarrier = true;
14060e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        }
14070e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh
1408cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
14092b0f0da4f9fe8449c578632b491e2f158c201bd5Stuart Scott        boolean recordsLoaded = false;
14102b0f0da4f9fe8449c578632b491e2f158c201bd5Stuart Scott        if (r != null) {
14112b0f0da4f9fe8449c578632b491e2f158c201bd5Stuart Scott            recordsLoaded = r.getRecordsLoaded();
14129232dafa7ea833fc0b3a6024d6c7e23fc8e961eaRobert Greenwalt            if (DBG && !recordsLoaded) log("isDataAllowed getRecordsLoaded=" + recordsLoaded);
14132b0f0da4f9fe8449c578632b491e2f158c201bd5Stuart Scott        }
1414cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
141538ca51d0f643405df51e78fce6c546424e9f410dShishir Agrawal        int dataSub = SubscriptionManager.getDefaultDataSubscriptionId();
1416434fa420329b093f68d83862a637c7ded93a4dafCraig Lafayette        boolean defaultDataSelected = SubscriptionManager.isValidSubscriptionId(dataSub);
14173d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
1418b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com        PhoneConstants.State state = PhoneConstants.State.IDLE;
14190710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // Note this is explicitly not using mPhone.getState.  See b/19090488.
14200710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // mPhone.getState reports the merge of CS and PS (volte) voice call state
14210710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // but we only care about CS calls here for data/voice concurrency issues.
14220710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // Calling getCallTracker currently gives you just the CS side where the
14230710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // ImsCallTracker is held internally where applicable.
14240710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // This should be redesigned to ask explicitly what we want:
14250710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // voiceCallStateAllowDataCall, or dataCallAllowed or something similar.
1426b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com        if (mPhone.getCallTracker() != null) {
1427b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com            state = mPhone.getCallTracker().getState();
1428b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com        }
14291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
14303d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (failureReason != null) failureReason.clearAllReasons();
14313d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!(attachedState || mAutoAttachOnCreation.get())) {
14323d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if(failureReason == null) return false;
14333d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            failureReason.addDataAllowFailReason(DataAllowFailReasonType.NOT_ATTACHED);
14343d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
14353d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!recordsLoaded) {
14363d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if(failureReason == null) return false;
14373d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            failureReason.addDataAllowFailReason(DataAllowFailReasonType.RECORD_NOT_LOADED);
14383d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
14393d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (state != PhoneConstants.State.IDLE &&
14403d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
14413d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if(failureReason == null) return false;
14423d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            failureReason.addDataAllowFailReason(DataAllowFailReasonType.INVALID_PHONE_STATE);
14433d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            failureReason.addDataAllowFailReason(
14443d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                    DataAllowFailReasonType.CONCURRENT_VOICE_DATA_NOT_ALLOWED);
14453d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
14463d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!internalDataEnabled) {
14473d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if(failureReason == null) return false;
14483d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            failureReason.addDataAllowFailReason(DataAllowFailReasonType.INTERNAL_DATA_DISABLED);
14493d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
14503d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!defaultDataSelected) {
14513d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if(failureReason == null) return false;
14523d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            failureReason.addDataAllowFailReason(
14533d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                    DataAllowFailReasonType.DEFAULT_DATA_UNSELECTED);
14543d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
14555b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (mPhone.getServiceState().getDataRoaming() && !getDataRoamingEnabled()) {
14563d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if(failureReason == null) return false;
14573d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            failureReason.addDataAllowFailReason(DataAllowFailReasonType.ROAMING_DISABLED);
1458c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
14593d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (mIsPsRestricted) {
14603d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if(failureReason == null) return false;
14613d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            failureReason.addDataAllowFailReason(DataAllowFailReasonType.PS_RESTRICTED);
14623d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
14633d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!desiredPowerState) {
14643d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if(failureReason == null) return false;
14653d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            failureReason.addDataAllowFailReason(DataAllowFailReasonType.UNDESIRED_POWER_STATE);
14663d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
14670d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu        if (!radioStateFromCarrier) {
14680d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu            if(failureReason == null) return false;
14690d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu            failureReason.addDataAllowFailReason(DataAllowFailReasonType.RADIO_DISABLED_BY_CARRIER);
14700d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu        }
14713d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
14723d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        return failureReason == null || !failureReason.isFailed();
1473cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1474c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1475c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    // arg for setupDataOnConnectableApns
1476c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    private enum RetryFailures {
1477c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        // retry failed networks always (the old default)
1478c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        ALWAYS,
14790e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        // retry only when a substantial change has occurred.  Either:
1480c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        // 1) we were restricted by voice/data concurrency and aren't anymore
1481c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        // 2) our apn list has change
1482c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        ONLY_ON_CHANGE
1483c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    };
1484c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt
1485ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void setupDataOnConnectableApns(String reason) {
1486c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        setupDataOnConnectableApns(reason, RetryFailures.ALWAYS);
1487c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    }
1488c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt
1489c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    private void setupDataOnConnectableApns(String reason, RetryFailures retryFailures) {
14909c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        if (VDBG) log("setupDataOnConnectableApns: " + reason);
14913fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
1492c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu        if (DBG && !VDBG) {
1493c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            StringBuilder sb = new StringBuilder(120);
1494c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            for (ApnContext apnContext : mPrioritySortedApnContexts) {
1495c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(apnContext.getApnType());
1496c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(":[state=");
1497c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(apnContext.getState());
1498c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(",enabled=");
1499c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(apnContext.isEnabled());
1500c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append("] ");
1501c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            }
15029c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            log("setupDataOnConnectableApns: " + reason + " " + sb);
1503c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu        }
1504c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu
15053fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        for (ApnContext apnContext : mPrioritySortedApnContexts) {
1506735bc2f4524d68155765351912ffae11306c3bd5Chris Manton            ArrayList<ApnSetting> waitingApns = null;
1507735bc2f4524d68155765351912ffae11306c3bd5Chris Manton
1508c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            if (VDBG) log("setupDataOnConnectableApns: apnContext " + apnContext);
1509c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu
1510735bc2f4524d68155765351912ffae11306c3bd5Chris Manton            if (apnContext.getState() == DctConstants.State.FAILED
15110e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                    || apnContext.getState() == DctConstants.State.SCANNING) {
1512c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                if (retryFailures == RetryFailures.ALWAYS) {
1513ee665b78ad648abd98b019a9c9047f206ed22994Robert Greenwalt                    apnContext.releaseDataConnection(reason);
1514c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                } else if (apnContext.isConcurrentVoiceAndDataAllowed() == false &&
15150e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                        mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
1516c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    // RetryFailures.ONLY_ON_CHANGE - check if voice concurrency has changed
1517ee665b78ad648abd98b019a9c9047f206ed22994Robert Greenwalt                    apnContext.releaseDataConnection(reason);
1518c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                } else {
1519c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    // RetryFailures.ONLY_ON_CHANGE - check if the apns have changed
1520c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
15210e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                    ArrayList<ApnSetting> originalApns = apnContext.getWaitingApns();
1522c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    if (originalApns != null && originalApns.isEmpty() == false) {
1523c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                        waitingApns = buildWaitingApns(apnContext.getApnType(), radioTech);
1524c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                        if (originalApns.size() != waitingApns.size() ||
1525c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                                originalApns.containsAll(waitingApns) == false) {
1526ee665b78ad648abd98b019a9c9047f206ed22994Robert Greenwalt                            apnContext.releaseDataConnection(reason);
1527b290ce3d172215e5ab7cd43c8e7bbee9551ab29eRobert Greenwalt                        } else {
1528b290ce3d172215e5ab7cd43c8e7bbee9551ab29eRobert Greenwalt                            continue;
1529c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                        }
1530b290ce3d172215e5ab7cd43c8e7bbee9551ab29eRobert Greenwalt                    } else {
1531b290ce3d172215e5ab7cd43c8e7bbee9551ab29eRobert Greenwalt                        continue;
1532c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    }
1533c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                }
1534cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1535ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.isConnectable()) {
15369c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                log("isConnectable() call trySetupData");
1537ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setReason(reason);
1538c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                trySetupData(apnContext, waitingApns);
1539cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1540cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1541c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1542c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
15431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    boolean isEmergency() {
1544a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        final boolean result = mPhone.isInEcm() || mPhone.isInEmergencyCall();
15451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("isEmergency: result=" + result);
15461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return result;
15471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
15481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1549cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean trySetupData(ApnContext apnContext) {
1550c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        return trySetupData(apnContext, null);
1551c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    }
1552c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt
1553c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    private boolean trySetupData(ApnContext apnContext, ArrayList<ApnSetting> waitingApns) {
1554cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
1555cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("trySetupData for type:" + apnContext.getApnType() +
15569c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                    " due to " + apnContext.getReason() + ", mIsPsRestricted=" + mIsPsRestricted);
1557cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
15582dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog("trySetupData due to " + apnContext.getReason());
1559cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1560cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
1561cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
1562cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
1563cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setState(DctConstants.State.CONNECTED);
1564cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1565cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1566cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("trySetupData: X We're on the simulator; assuming connected retValue=true");
1567cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return true;
1568cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1569cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1570cf5205f70eb1eac497164124187a088ecb03fff5Ram        // Allow SETUP_DATA request for E-APN to be completed during emergency call
1571cf5205f70eb1eac497164124187a088ecb03fff5Ram        // and MOBILE DATA On/Off cases as well.
1572cf5205f70eb1eac497164124187a088ecb03fff5Ram        boolean isEmergencyApn = apnContext.getApnType().equals(PhoneConstants.APN_TYPE_EMERGENCY);
1573c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        final ServiceStateTracker sst = mPhone.getServiceStateTracker();
15740e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
15753d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        DataAllowFailReason failureReason = new DataAllowFailReason();
15763d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
1577120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        boolean unmeteredUseOnly = false;
1578120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        boolean isDataAllowed = isDataAllowed(failureReason);
1579120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        boolean isMeteredApnType = ApnSetting.isMeteredApnType(apnContext.getApnType(),
1580120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                mPhone.getContext(), mPhone.getSubId(), mPhone.getServiceState().getDataRoaming());
1581120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        if (!isDataAllowed) {
1582120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu            // If the data not allowed due to roaming disabled, but the request APN type is not
1583120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu            // metered, we should allow data (because the user won't be charged anyway)
1584120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu            if (failureReason.isFailForSingleReason(DataAllowFailReasonType.ROAMING_DISABLED)
1585120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    && !isMeteredApnType) {
1586120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                isDataAllowed = true;
1587120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                unmeteredUseOnly = true;
1588120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu            }
1589120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        }
1590120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu
1591120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        if (isDataAllowed) {
1592120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu            if (!mDataEnabledSettings.isDataEnabled()) {
1593120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                // If the data is turned off, we should not allow a data connection.
1594120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                isDataAllowed = false;
1595120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu
1596120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                // But there are some exceptions we should allow data even when data is turned off.
1597120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                if (!apnContext.hasNoRestrictedRequests(true /*exclude DUN */)) {
1598120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    // A restricted request can request data even when data is turned off.
1599120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    // Note this takes precedence over unmetered request.
1600120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    isDataAllowed = true;
1601120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    unmeteredUseOnly = false;
1602120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                } else if (!isMeteredApnType) {
1603120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    // If the APN is unmetered, we should allow data even if data is turned off.
1604120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    // This will allow users to make VoLTE calls or send MMS while data is
1605120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    // turned off.
1606120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    isDataAllowed = true;
1607120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu
1608120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    // When data is off, if we allow a data call because it's unmetered, we
1609120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    // should restrict it for unmetered use only. For example, if one
1610120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    // carrier has both internet (metered) and MMS (unmetered) APNs mixed in one
1611120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    // APN setting, when we bring up a data call for MMS purpose, we should
1612120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    // restrict it for unmetered use only. We should not allow it for other
1613120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    // metered purposes such as internet.
1614120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    unmeteredUseOnly = true;
1615120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                }
1616120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu            }
1617120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        }
1618cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1619120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        if (apnContext.isConnectable()
1620120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                && (isEmergencyApn
1621120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                || (isDataAllowed && isDataAllowedForApn(apnContext) && !isEmergency()))) {
1622ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getState() == DctConstants.State.FAILED) {
16233d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                String str = "trySetupData: make a FAILED ApnContext IDLE so its reusable";
16242dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                if (DBG) log(str);
16252dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                apnContext.requestLog(str);
1626ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setState(DctConstants.State.IDLE);
1627ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1628203e588e3c42a81aa8a56f595119c181a63b12caWink Saville            int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
1629c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt            apnContext.setConcurrentVoiceAndDataAllowed(sst.isConcurrentVoiceAndDataAllowed());
1630cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.getState() == DctConstants.State.IDLE) {
1631c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                if (waitingApns == null) {
1632c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    waitingApns = buildWaitingApns(apnContext.getApnType(), radioTech);
1633c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                }
1634cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (waitingApns.isEmpty()) {
1635ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    notifyNoData(DcFailCause.MISSING_UNKNOWN_APN, apnContext);
1636cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    notifyOffApnsOfAvailability(apnContext.getReason());
16372dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    String str = "trySetupData: X No APN found retValue=false";
16382dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    if (DBG) log(str);
16392dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    apnContext.requestLog(str);
1640cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return false;
1641cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1642cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setWaitingApns(waitingApns);
1643cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) {
1644ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        log ("trySetupData: Create from mAllApnSettings : "
1645ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                    + apnListToString(mAllApnSettings));
1646cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1647cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1648cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1649cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1650120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu            boolean retValue = setupData(apnContext, radioTech, unmeteredUseOnly);
1651cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(apnContext.getReason());
1652cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1653cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("trySetupData: X retValue=" + retValue);
1654cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return retValue;
1655cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1656cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
1657ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    && apnContext.isConnectable()) {
1658cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
1659ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1660cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(apnContext.getReason());
16612e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
16622e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            StringBuilder str = new StringBuilder();
16632e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
16642e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            str.append("trySetupData failed. apnContext = [type=" + apnContext.getApnType() +
16652e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu                    ", mState=" + apnContext.getState() + ", mDataEnabled=" +
16662e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu                    apnContext.isEnabled() + ", mDependencyMet=" +
16672e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu                    apnContext.getDependencyMet() + "] ");
16682e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
16692e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            if (!apnContext.isConnectable()) {
16702e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu                str.append("isConnectable = false. ");
16712dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt            }
16723d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if (!isDataAllowed) {
16733d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                str.append("data not allowed: " + failureReason.getDataAllowFailReason() + ". ");
16742e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            }
16752e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            if (!isDataAllowedForApn(apnContext)) {
16762e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu                str.append("isDataAllowedForApn = false. RAT = " +
16772e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu                        mPhone.getServiceState().getRilDataRadioTechnology());
16782e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            }
1679120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu            if (!mDataEnabledSettings.isDataEnabled()) {
1680120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                str.append("isDataEnabled() = false. "
1681120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                        + "isInternalDataEnabled = " + mDataEnabledSettings.isInternalDataEnabled()
1682120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                        + ", userDataEnabled = " + mDataEnabledSettings.isUserDataEnabled()
1683120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                        + ", isPolicyDataEnabled = " + mDataEnabledSettings.isPolicyDataEnabled()
1684120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                        + ", isCarrierDataEnabled = "
1685120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                        + mDataEnabledSettings.isCarrierDataEnabled());
16862e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            }
16872e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            if (isEmergency()) {
16882e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu                str.append("emergency = true");
16892e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            }
16902e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
16912e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            if (DBG) log(str.toString());
16922e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            apnContext.requestLog(str.toString());
16932e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
1694cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
1695cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1696c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1697c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
16980e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    // Disabled apn's still need avail/unavail notifications - send them out
16991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyOffApnsOfAvailability(String reason) {
17009c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        if (DBG) {
17013d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            DataAllowFailReason failureReason = new DataAllowFailReason();
17023d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if (!isDataAllowed(failureReason)) {
17033d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                log(failureReason.getDataAllowFailReason());
17049c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            }
17059c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        }
1706cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1707187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (!mAttached.get() || !apnContext.isReady()) {
1708ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) log("notifyOffApnOfAvailability type:" + apnContext.getApnType());
1709cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
1710cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                            apnContext.getApnType(),
1711cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                            PhoneConstants.DataState.DISCONNECTED);
1712cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1713ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) {
1714187a39f896f88eb6c5e4306d9595546654825976Wink Saville                    log("notifyOffApnsOfAvailability skipped apn due to attached && isReady " +
1715cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            apnContext.toString());
1716cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1717c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1718c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1719c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1720c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1721cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1722cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * If tearDown is true, this only tears down a CONNECTED session. Presently,
1723cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * there is no mechanism for abandoning an CONNECTING session,
1724cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * but would likely involve cancelling pending async requests or
1725cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * setting a flag or new state to ignore them when they came in
1726cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param tearDown true if the underlying DataConnection should be
1727cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * disconnected.
1728cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param reason reason for the clean up.
17293fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return boolean - true if we did cleanup any connections, false if they
17303fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     *                   were already all disconnected.
1731cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
17321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean cleanUpAllConnections(boolean tearDown, String reason) {
1733cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("cleanUpAllConnections: tearDown=" + tearDown + " reason=" + reason);
17343fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        boolean didDisconnect = false;
17354c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu        boolean disableMeteredOnly = false;
1736a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
17374c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu        // reasons that only metered apn will be torn down
1738a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (!TextUtils.isEmpty(reason)) {
17394c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            disableMeteredOnly = reason.equals(Phone.REASON_DATA_SPECIFIC_DISABLED) ||
17404c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                    reason.equals(Phone.REASON_ROAMING_ON) ||
17414c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                    reason.equals(Phone.REASON_CARRIER_ACTION_DISABLE_METERED_APN);
1742a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1743cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1744cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
17453fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (apnContext.isDisconnected() == false) didDisconnect = true;
17464c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            if (disableMeteredOnly) {
1747783061ca03572618c01ce244d70d82fa4328d45ffionaxu                // Use ApnSetting to decide metered or non-metered.
1748783061ca03572618c01ce244d70d82fa4328d45ffionaxu                // Tear down all metered data connections.
1749783061ca03572618c01ce244d70d82fa4328d45ffionaxu                ApnSetting apnSetting = apnContext.getApnSetting();
1750783061ca03572618c01ce244d70d82fa4328d45ffionaxu                if (apnSetting != null && apnSetting.isMetered(mPhone.getContext(),
17513d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                        mPhone.getSubId(), mPhone.getServiceState().getDataRoaming())) {
1752783061ca03572618c01ce244d70d82fa4328d45ffionaxu                    if (DBG) log("clean up metered ApnContext Type: " + apnContext.getApnType());
1753a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    apnContext.setReason(reason);
1754a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    cleanUpConnection(tearDown, apnContext);
1755a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1756a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
1757a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // TODO - only do cleanup if not disconnected
1758a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                apnContext.setReason(reason);
1759a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                cleanUpConnection(tearDown, apnContext);
1760a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1761c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1762cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1763cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopNetStatPoll();
1764cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopDataStallAlarm();
1765cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1766cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: Do we need mRequestedApnType?
1767cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
1768a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1769a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("cleanUpConnection: mDisconnectPendingCount = " + mDisconnectPendingCount);
1770a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (tearDown && mDisconnectPendingCount == 0) {
1771a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyDataDisconnectComplete();
1772a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
1773a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1774a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
17753fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return didDisconnect;
1776cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1777cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1778cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1779cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Cleanup all connections.
1780cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1781cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * TODO: Cleanup only a specified connection passed as a parameter.
1782cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *       Also, make sure when you clean up a conn, if it is last apply
1783cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *       logic as though it is cleanupAllConnections
1784cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1785cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param cause for the clean up.
1786cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
17871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onCleanUpAllConnections(String cause) {
1788cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, cause);
1789cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1790cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
17911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    void sendCleanUpConnection(boolean tearDown, ApnContext apnContext) {
17921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("sendCleanUpConnection: tearDown=" + tearDown + " apnContext=" + apnContext);
17931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_CLEAN_UP_CONNECTION);
17941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = tearDown ? 1 : 0;
17951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg2 = 0;
17961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.obj = apnContext;
17971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
17981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
1799cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
18001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void cleanUpConnection(boolean tearDown, ApnContext apnContext) {
1801cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
1802cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("cleanUpConnection: apn context is null");
1803cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
1804cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1805cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1806454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac = apnContext.getDcAc();
18072dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        String str = "cleanUpConnection: tearDown=" + tearDown + " reason=" +
18082dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                apnContext.getReason();
18099c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        if (VDBG) log(str + " apnContext=" + apnContext);
18102dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog(str);
1811cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (tearDown) {
1812cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.isDisconnected()) {
1813cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // The request is tearDown and but ApnContext is not connected.
1814cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // If apnContext is not enabled anymore, break the linkage to the DCAC/DC.
1815cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setState(DctConstants.State.IDLE);
1816cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (!apnContext.isReady()) {
18174750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                    if (dcac != null) {
18180e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                        str = "cleanUpConnection: teardown, disconnected, !ready";
18192dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        if (DBG) log(str + " apnContext=" + apnContext);
18202dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        apnContext.requestLog(str);
18214750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                        dcac.tearDown(apnContext, "", null);
18224750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                    }
1823cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setDataConnectionAc(null);
1824cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1825cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1826cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Connection is still there. Try to clean up.
1827cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (dcac != null) {
1828cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (apnContext.getState() != DctConstants.State.DISCONNECTING) {
1829cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        boolean disconnectAll = false;
1830cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (PhoneConstants.APN_TYPE_DUN.equals(apnContext.getApnType())) {
1831a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            // CAF_MSIM is this below condition required.
1832a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            // if (PhoneConstants.APN_TYPE_DUN.equals(PhoneConstants.APN_TYPE_DEFAULT)) {
18331484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                            if (teardownForDun()) {
183445eaa2335e64a8ff1ad8d5e8224c580ef996f370Wink Saville                                if (DBG) {
183545eaa2335e64a8ff1ad8d5e8224c580ef996f370Wink Saville                                    log("cleanUpConnection: disconnectAll DUN connection");
183645eaa2335e64a8ff1ad8d5e8224c580ef996f370Wink Saville                                }
1837cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // we need to tear it down - we brought it up just for dun and
1838cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // other people are camped on it and now dun is done.  We need
1839cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // to stop using it and let the normal apn list get used to find
1840cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // connections for the remaining desired connections
1841cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                disconnectAll = true;
1842cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            }
1843cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
18441a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                        final int generation = apnContext.getConnectionGeneration();
18451a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                        str = "cleanUpConnection: tearing down" + (disconnectAll ? " all" : "") +
18461a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                                " using gen#" + generation;
18472dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        if (DBG) log(str + "apnContext=" + apnContext);
18482dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        apnContext.requestLog(str);
184937cacdfe7ed079d89fb9e80317b5dfd2acb975e5Robert Greenwalt                        Pair<ApnContext, Integer> pair =
18501a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                                new Pair<ApnContext, Integer>(apnContext, generation);
185137cacdfe7ed079d89fb9e80317b5dfd2acb975e5Robert Greenwalt                        Message msg = obtainMessage(DctConstants.EVENT_DISCONNECT_DONE, pair);
1852cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (disconnectAll) {
1853ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            apnContext.getDcAc().tearDownAll(apnContext.getReason(), msg);
1854cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        } else {
1855ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            apnContext.getDcAc()
1856cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                .tearDown(apnContext, apnContext.getReason(), msg);
1857cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
1858cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.setState(DctConstants.State.DISCONNECTING);
1859a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        mDisconnectPendingCount++;
1860cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1861cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1862cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // apn is connected but no reference to dcac.
1863cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // Should not be happen, but reset the state in case.
1864cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setState(DctConstants.State.IDLE);
18652dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    apnContext.requestLog("cleanUpConnection: connected, bug no DCAC");
1866cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mPhone.notifyDataConnection(apnContext.getReason(),
1867cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                                apnContext.getApnType());
1868cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1869cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1870cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1871cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // force clean up the data connection.
1872ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac != null) dcac.reqReset();
1873cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setState(DctConstants.State.IDLE);
1874cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1875cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setDataConnectionAc(null);
1876cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1877cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1878ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // Make sure reconnection alarm is cleaned up if there is no ApnContext
1879cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // associated to the connection.
1880cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (dcac != null) {
1881ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            cancelReconnectAlarm(apnContext);
1882c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
18832dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        str = "cleanUpConnection: X tearDown=" + tearDown + " reason=" + apnContext.getReason();
18842dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        if (DBG) log(str + " apnContext=" + apnContext + " dcac=" + apnContext.getDcAc());
18852dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog(str);
1886cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1887c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
18881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    ApnSetting fetchDunApn() {
18891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (SystemProperties.getBoolean("net.tethering.noprovisioning", false)) {
18901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("fetchDunApn: net.tethering.noprovisioning=true ret: null");
18911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return null;
18921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
18931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int bearer = mPhone.getServiceState().getRilDataRadioTechnology();
1894d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        IccRecords r = mIccRecords.get();
1895d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        String operator = (r != null) ? r.getOperatorNumeric() : "";
1896d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        ArrayList<ApnSetting> dunCandidates = new ArrayList<ApnSetting>();
18971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting retDunSetting = null;
1898d92c67aa965200385acf3182ffb0af25297a366fJunda Liu
1899d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        // Places to look for tether APN in order: TETHER_DUN_APN setting, APN database if
1900d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        // carrier allows it, and config_tether_apndata resource.
19011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        String apnData = Settings.Global.getString(mResolver, Settings.Global.TETHER_DUN_APN);
1902d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        if (!TextUtils.isEmpty(apnData)) {
1903d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            dunCandidates.addAll(ApnSetting.arrayFromString(apnData));
1904d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            if (VDBG) log("fetchDunApn: dunCandidates from Setting: " + dunCandidates);
1905d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        } else if (mAllowUserEditTetherApn) {
1906d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            for (ApnSetting apn : mAllApnSettings) {
1907d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                if (apn.canHandleType(PhoneConstants.APN_TYPE_DUN)) {
1908d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                    dunCandidates.add(apn);
19091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
19101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
1911d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            if (VDBG) log("fetchDunApn: dunCandidates from database: " + dunCandidates);
1912d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        }
1913d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        // If TETHER_DUN_APN isn't set or
1914d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        // mAllowUserEditTetherApn is true but APN database doesn't have dun APN,
1915d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        // try the resource as last resort.
1916d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        if (dunCandidates.isEmpty()) {
1917d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            String[] apnArrayData = mPhone.getContext().getResources()
1918d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                .getStringArray(R.array.config_tether_apndata);
1919d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            for (String apnString : apnArrayData) {
1920d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                ApnSetting apn = ApnSetting.fromString(apnString);
1921d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                // apn may be null if apnString isn't valid or has error parsing
1922d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                if (apn != null) dunCandidates.add(apn);
1923d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            }
1924d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            if (VDBG) log("fetchDunApn: dunCandidates from resource: " + dunCandidates);
19251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
19261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1927d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        for (ApnSetting dunSetting : dunCandidates) {
1928d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            if (!ServiceState.bitmaskHasTech(dunSetting.bearerBitmask, bearer)) continue;
1929d92c67aa965200385acf3182ffb0af25297a366fJunda Liu            if (dunSetting.numeric.equals(operator)) {
19301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (dunSetting.hasMvnoParams()) {
19311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (r != null && ApnSetting.mvnoMatches(r, dunSetting.mvnoType,
19321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            dunSetting.mvnoMatchData)) {
1933d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                        retDunSetting = dunSetting;
1934d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                        break;
19351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
19361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else if (mMvnoMatched == false) {
19371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    retDunSetting = dunSetting;
1938d92c67aa965200385acf3182ffb0af25297a366fJunda Liu                    break;
19391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
19401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
19411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
19421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1943d92c67aa965200385acf3182ffb0af25297a366fJunda Liu        if (VDBG) log("fetchDunApn: dunSetting=" + retDunSetting);
19441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return retDunSetting;
19451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
19461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
19471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public boolean hasMatchedTetherApnSetting() {
19481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting matched = fetchDunApn();
19491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("hasMatchedTetherApnSetting: APN=" + matched);
19501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return matched != null;
19511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
19521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1953cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
19541484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt     * Determine if DUN connection is special and we need to teardown on start/stop
19551484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt     */
19561484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt    private boolean teardownForDun() {
19571484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // CDMA always needs to do this the profile id is correct
19581484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        final int rilRat = mPhone.getServiceState().getRilDataRadioTechnology();
19591484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        if (ServiceState.isCdma(rilRat)) return true;
19601484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt
19611484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        return (fetchDunApn() != null);
19621484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt    }
19631484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt
19641484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt    /**
1965ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Cancels the alarm associated with apnContext.
1966cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1967ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * @param apnContext on which the alarm should be stopped.
1968cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1969ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void cancelReconnectAlarm(ApnContext apnContext) {
1970ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnContext == null) return;
1971cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1972ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        PendingIntent intent = apnContext.getReconnectIntent();
1973cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1974cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (intent != null) {
1975cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                AlarmManager am =
1976cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
1977cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                am.cancel(intent);
1978ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setReconnectIntent(null);
1979cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1980c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1981c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1982cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1983cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param types comma delimited list of APN types
1984cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return array of APN types
1985cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1986cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private String[] parseTypes(String types) {
1987c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String[] result;
1988cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // If unset, set to DEFAULT.
1989cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (types == null || types.equals("")) {
1990c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            result = new String[1];
1991cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result[0] = PhoneConstants.APN_TYPE_ALL;
1992cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1993cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result = types.split(",");
1994c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1995c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
1996c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1997c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1998ccfe5ebaf81c1378e8dbe44e45df26b0dc462a21Jack Yu    boolean isPermanentFailure(DcFailCause dcFailCause) {
1999ccfe5ebaf81c1378e8dbe44e45df26b0dc462a21Jack Yu        return (dcFailCause.isPermanentFailure(mPhone.getContext(), mPhone.getSubId()) &&
2000796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan                (mAttached.get() == false || dcFailCause != DcFailCause.SIGNAL_LOST));
2001796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan    }
2002796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan
2003fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    private ApnSetting makeApnSetting(Cursor cursor) {
2004fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        String[] types = parseTypes(
2005fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.TYPE)));
2006fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        ApnSetting apn = new ApnSetting(
2007fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID)),
2008fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NUMERIC)),
2009fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NAME)),
2010fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN)),
2011fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
2012fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
2013fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY))),
2014fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PORT)),
2015fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
2016fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
2017fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC))),
2018fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
2019fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
2020fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY))),
2021fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPORT)),
2022fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)),
2023fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)),
20241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.AUTH_TYPE)),
2025fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                types,
2026fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROTOCOL)),
2027fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(
2028fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        Telephony.Carriers.ROAMING_PROTOCOL)),
2029fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(
2030fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        Telephony.Carriers.CARRIER_ENABLED)) == 1,
20319d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.BEARER)),
2032aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.BEARER_BITMASK)),
20339d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROFILE_ID)),
20349d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(
20359d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                        Telephony.Carriers.MODEM_COGNITIVE)) == 1,
20369d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MAX_CONNS)),
20379d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(
20389d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                        Telephony.Carriers.WAIT_TIME)),
2039e9701717e43cc5aacbcf624f77a53be92350662cw                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MAX_CONNS_TIME)),
20403262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MTU)),
20413262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_TYPE)),
20423262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_MATCH_DATA)));
2043fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        return apn;
2044fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    }
2045fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
2046cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ArrayList<ApnSetting> createApnList(Cursor cursor) {
20473262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        ArrayList<ApnSetting> mnoApns = new ArrayList<ApnSetting>();
20483262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        ArrayList<ApnSetting> mvnoApns = new ArrayList<ApnSetting>();
2049fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        IccRecords r = mIccRecords.get();
2050fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
2051cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor.moveToFirst()) {
2052cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            do {
20533262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                ApnSetting apn = makeApnSetting(cursor);
20543262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                if (apn == null) {
20553262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                    continue;
20563262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                }
20573262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
20583262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                if (apn.hasMvnoParams()) {
205963913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan                    if (r != null && ApnSetting.mvnoMatches(r, apn.mvnoType, apn.mvnoMatchData)) {
20603262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                        mvnoApns.add(apn);
2061fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    }
2062fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                } else {
20633262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                    mnoApns.add(apn);
2064fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                }
2065cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } while (cursor.moveToNext());
2066cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
20673262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
20681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ArrayList<ApnSetting> result;
20691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mvnoApns.isEmpty()) {
20701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            result = mnoApns;
20711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mMvnoMatched = false;
20721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
20731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            result = mvnoApns;
20741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mMvnoMatched = true;
20751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
2076cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createApnList: X result=" + result);
2077c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
2078c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2079c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2080454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private boolean dataConnectionNotInUse(DcAsyncChannel dcac) {
2081ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("dataConnectionNotInUse: check if dcac is inuse dcac=" + dcac);
2082cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
2083ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getDcAc() == dcac) {
2084cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("dataConnectionNotInUse: in use by apnContext=" + apnContext);
2085cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
2086cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2087cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2088cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: Fix retry handling so free DataConnections have empty apnlists.
2089cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Probably move retry handling into DataConnections and reduce complexity
2090cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // of DCT.
2091cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("dataConnectionNotInUse: tearDownAll");
2092ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        dcac.tearDownAll("No connection", null);
2093cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("dataConnectionNotInUse: not in use return true");
2094cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
2095cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2096cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2097454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel findFreeDataConnection() {
2098454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
2099cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac.isInactiveSync() && dataConnectionNotInUse(dcac)) {
2100cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
2101cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("findFreeDataConnection: found free DataConnection=" +
2102ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        " dcac=" + dcac);
2103cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2104ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                return dcac;
2105cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2106cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2107cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("findFreeDataConnection: NO free DataConnection");
2108cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
2109cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2110cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2111120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu    private boolean setupData(ApnContext apnContext, int radioTech, boolean unmeteredUseOnly) {
2112cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setupData: apnContext=" + apnContext);
21132dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog("setupData");
2114ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnSetting apnSetting;
21151484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        DcAsyncChannel dcac = null;
2116cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
21170e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        apnSetting = apnContext.getNextApnSetting();
21180e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
2119ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnSetting == null) {
2120cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("setupData: return for no apn found!");
2121cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
2122cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2123cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2124231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        int profileId = apnSetting.profileId;
2125231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        if (profileId == 0) {
2126231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen            profileId = getApnProfileID(apnContext.getApnType());
2127231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        }
2128231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen
21291484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // On CDMA, if we're explicitly asking for DUN, we need have
21301484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // a dun-profiled connection so we can't share an existing one
21311484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // On GSM/LTE we can share existing apn connections provided they support
21321484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // this type.
21331484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        if (apnContext.getApnType() != PhoneConstants.APN_TYPE_DUN ||
21341484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                teardownForDun() == false) {
21351484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt            dcac = checkForCompatibleConnectedApnContext(apnContext);
21361484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt            if (dcac != null) {
21371484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // Get the dcacApnSetting for the connection we want to share.
21381484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                ApnSetting dcacApnSetting = dcac.getApnSettingSync();
21391484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                if (dcacApnSetting != null) {
21401484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    // Setting is good, so use it.
21411484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    apnSetting = dcacApnSetting;
21421484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                }
2143ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
2144ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
2145ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (dcac == null) {
21463fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (isOnlySingleDcAllowed(radioTech)) {
21473fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (isHigherPriorityApnContextActive(apnContext)) {
21483fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (DBG) {
21493fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        log("setupData: Higher priority ApnContext active.  Ignoring call");
21503fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    }
21513fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    return false;
21523fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                }
21533fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
21543fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // Only lower priority calls left.  Disconnect them all in this single PDP case
21553fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // so that we can bring up the requested higher priority call (once we receive
21560e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                // response for deactivate request for the calls we are about to disconnect
21573fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (cleanUpAllConnections(true, Phone.REASON_SINGLE_PDN_ARBITRATION)) {
21583fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // If any call actually requested to be disconnected, means we can't
21593fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // bring up this connection yet as we need to wait for those data calls
21603fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // to be disconnected.
21613fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (DBG) log("setupData: Some calls are disconnecting first.  Wait and retry");
21623fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    return false;
21633fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                }
21643fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
21653fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // No other calls are active, so proceed
21663fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (DBG) log("setupData: Single pdp. Continue setting up data call.");
21673fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
21683fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
2169ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            dcac = findFreeDataConnection();
2170cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2171ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac == null) {
2172ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                dcac = createDataConnection();
2173cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2174cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2175ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac == null) {
2176ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) log("setupData: No free DataConnection and couldn't create one, WEIRD");
2177cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
2178cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2179cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
21801a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        final int generation = apnContext.incAndGetConnectionGeneration();
21811a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        if (DBG) {
21821a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt            log("setupData: dcac=" + dcac + " apnSetting=" + apnSetting + " gen#=" + generation);
21831a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        }
2184cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2185cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setDataConnectionAc(dcac);
2186ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setApnSetting(apnSetting);
2187cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setState(DctConstants.State.CONNECTING);
2188cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
2189cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2190cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Message msg = obtainMessage();
2191cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        msg.what = DctConstants.EVENT_DATA_SETUP_COMPLETE;
21921a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        msg.obj = new Pair<ApnContext, Integer>(apnContext, generation);
2193120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu        dcac.bringUp(apnContext, profileId, radioTech, unmeteredUseOnly, msg, generation);
2194cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2195cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setupData: initing!");
2196cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
2197cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2198cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
21991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void setInitialAttachApn() {
22001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting iaApnSetting = null;
22011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting defaultApnSetting = null;
22021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting firstApnSetting = null;
22031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
22041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("setInitialApn: E mPreferredApn=" + mPreferredApn);
22051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
220640b0e247a4a79e83f10b6410025ef1d7cc537692Robert Greenwalt        if (mPreferredApn != null && mPreferredApn.canHandleType(PhoneConstants.APN_TYPE_IA)) {
220740b0e247a4a79e83f10b6410025ef1d7cc537692Robert Greenwalt              iaApnSetting = mPreferredApn;
220840b0e247a4a79e83f10b6410025ef1d7cc537692Robert Greenwalt        } else if (mAllApnSettings != null && !mAllApnSettings.isEmpty()) {
22091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            firstApnSetting = mAllApnSettings.get(0);
22101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("setInitialApn: firstApnSetting=" + firstApnSetting);
22111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
22121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Search for Initial APN setting and the first apn that can handle default
22131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (ApnSetting apn : mAllApnSettings) {
221440b0e247a4a79e83f10b6410025ef1d7cc537692Robert Greenwalt                if (apn.canHandleType(PhoneConstants.APN_TYPE_IA)) {
22151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // The Initial Attach APN is highest priority so use it if there is one
22161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("setInitialApn: iaApnSetting=" + apn);
22171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    iaApnSetting = apn;
22181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    break;
22191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else if ((defaultApnSetting == null)
22201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        && (apn.canHandleType(PhoneConstants.APN_TYPE_DEFAULT))) {
22211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // Use the first default apn if no better choice
22221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("setInitialApn: defaultApnSetting=" + apn);
22231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    defaultApnSetting = apn;
22241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
22251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
22261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
22271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
22281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // The priority of apn candidates from highest to lowest is:
22290e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        //   1) APN_TYPE_IA (Initial Attach)
22301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        //   2) mPreferredApn, i.e. the current preferred apn
22311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        //   3) The first apn that than handle APN_TYPE_DEFAULT
22321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        //   4) The first APN we can find.
22331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
22341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting initialAttachApnSetting = null;
22351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (iaApnSetting != null) {
22361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using iaApnSetting");
22371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = iaApnSetting;
22381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (mPreferredApn != null) {
22391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using mPreferredApn");
22401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = mPreferredApn;
22411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (defaultApnSetting != null) {
22421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using defaultApnSetting");
22431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = defaultApnSetting;
22441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (firstApnSetting != null) {
22451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using firstApnSetting");
22461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = firstApnSetting;
22471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
22481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
22491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (initialAttachApnSetting == null) {
22501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: X There in no available apn");
22511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
22521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: X selected Apn=" + initialAttachApnSetting);
22531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
22548e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu            mPhone.mCi.setInitialAttachApn(new DataProfile(initialAttachApnSetting),
22558e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                    mPhone.getServiceState().getDataRoaming(), null);
22561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
22571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
22581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2259c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
2260cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Handles changes to the APN database.
2261c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
2262cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onApnChanged() {
2263cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        DctConstants.State overallState = getOverallState();
2264cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isDisconnected = (overallState == DctConstants.State.IDLE ||
2265cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                overallState == DctConstants.State.FAILED);
2266cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
22671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mPhone instanceof GsmCdmaPhone) {
2268cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // The "current" may no longer be valid.  MMS depends on this to send properly. TBD
22691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            ((GsmCdmaPhone)mPhone).updateCurrentCarrierInProvider();
2270cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2271cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2272cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: It'd be nice to only do this if the changed entrie(s)
2273cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // match the current operator.
2274cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onApnChanged: createAllApnList and cleanUpAllConnections");
2275cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        createAllApnList();
22765d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi        setInitialAttachApn();
22779a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        cleanUpConnectionsOnUpdatedApns(!isDisconnected);
2278bda761320929f714951c328bfec6a51a1978db97Wink Saville
22798f6f52e4f7598e44cea1f9e5f4781291f9060d1dWink Saville        // FIXME: See bug 17426028 maybe no conditional is needed.
228038ca51d0f643405df51e78fce6c546424e9f410dShishir Agrawal        if (mPhone.getSubId() == SubscriptionManager.getDefaultDataSubscriptionId()) {
2281ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_APN_CHANGED);
2282c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2283c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2284c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2285c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
2286cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param cid Connection id provided from RIL.
2287cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return DataConnectionAc associated with specified cid.
2288c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
2289454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel findDataConnectionAcByCid(int cid) {
2290454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
2291cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac.getCidSync() == cid) {
2292cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return dcac;
2293cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2294c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2295cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
2296c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2297c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2298cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // TODO: For multiple Active APNs not exactly sure how to do this.
22991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void gotoIdleAndNotifyDataConnection(String reason) {
2300cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("gotoIdleAndNotifyDataConnection: reason=" + reason);
2301cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyDataConnection(reason);
2302cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2303cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
23043fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    /**
23053fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * "Active" here means ApnContext isEnabled() and not in FAILED state
23063fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @param apnContext to compare with
23073fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return true if higher priority active apn found
23083fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     */
23093fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean isHigherPriorityApnContextActive(ApnContext apnContext) {
23103fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        for (ApnContext otherContext : mPrioritySortedApnContexts) {
23113fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (apnContext.getApnType().equalsIgnoreCase(otherContext.getApnType())) return false;
23123fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (otherContext.isEnabled() && otherContext.getState() != DctConstants.State.FAILED) {
23133fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                return true;
23143fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
23153fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
23163fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return false;
23173fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    }
23183fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
23193fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    /**
23203fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * Reports if we support multiple connections or not.
23213fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * This is a combination of factors, based on carrier and RAT.
23223fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @param rilRadioTech the RIL Radio Tech currently in use
23233fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return true if only single DataConnection is allowed
23243fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     */
23253fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean isOnlySingleDcAllowed(int rilRadioTech) {
2326bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        // Default single dc rats with no knowledge of carrier
2327bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        int[] singleDcRats = null;
2328bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        // get the carrier specific value, if it exists, from CarrierConfigManager.
2329bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        // generally configManager and bundle should not be null, but if they are it should be okay
2330bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        // to leave singleDcRats null as well
2331bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        CarrierConfigManager configManager = (CarrierConfigManager)
2332bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu                mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
2333bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        if (configManager != null) {
2334bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu            PersistableBundle bundle = configManager.getConfig();
2335bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu            if (bundle != null) {
2336bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu                singleDcRats = bundle.getIntArray(
2337bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu                        CarrierConfigManager.KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY);
2338bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu            }
2339bc95db4ecce234c24c6cb549a6762d8a39d5ab84Jordan Liu        }
23403fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        boolean onlySingleDcAllowed = false;
23413fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (Build.IS_DEBUGGABLE &&
23423fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                SystemProperties.getBoolean("persist.telephony.test.singleDc", false)) {
23433fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            onlySingleDcAllowed = true;
23443fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
23453fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (singleDcRats != null) {
23463fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            for (int i=0; i < singleDcRats.length && onlySingleDcAllowed == false; i++) {
23473fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (rilRadioTech == singleDcRats[i]) onlySingleDcAllowed = true;
23483fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
23493fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
23503fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
23513fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (DBG) log("isOnlySingleDcAllowed(" + rilRadioTech + "): " + onlySingleDcAllowed);
23523fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return onlySingleDcAllowed;
23533fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    }
23543fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
23551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    void sendRestartRadio() {
23561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG)log("sendRestartRadio:");
23571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_RESTART_RADIO);
23581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
23591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
23601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
23611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void restartRadio() {
2362cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("restartRadio: ************TURN OFF RADIO**************");
2363cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, Phone.REASON_RADIO_TURNED_OFF);
2364cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().powerOffRadioSafely(this);
2365cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        /* Note: no need to call setRadioPower(true).  Assuming the desired
2366cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * radio power state is still ON (as tracked by ServiceStateTracker),
2367cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * ServiceStateTracker will call setRadioPower when it receives the
2368cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * RADIO_STATE_CHANGED notification for the power off.  And if the
2369cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * desired power state has changed in the interim, we don't want to
2370cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * override it with an unconditional power on.
2371cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         */
2372cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2373cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int reset = Integer.parseInt(SystemProperties.get("net.ppp.reset-by-timeout", "0"));
23740e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        SystemProperties.set("net.ppp.reset-by-timeout", String.valueOf(reset + 1));
2375cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2376cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2377cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
2378cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Return true if data connection need to be setup after disconnected due to
2379cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * reason.
2380cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
23810e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu     * @param apnContext APN context
2382cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return true if try setup data connection is need for this reason
2383cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
23843fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean retryAfterDisconnected(ApnContext apnContext) {
2385cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean retry = true;
23863fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        String reason = apnContext.getReason();
2387cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
23883fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) ||
23893fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())
23903fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                 && isHigherPriorityApnContextActive(apnContext))) {
2391cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            retry = false;
2392cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2393cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return retry;
2394cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2395cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
23960e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    private void startAlarmForReconnect(long delay, ApnContext apnContext) {
2397cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String apnType = apnContext.getApnType();
239874672e8ee972f12406b72551261b4cc7e0651933Wink Saville
239974672e8ee972f12406b72551261b4cc7e0651933Wink Saville        Intent intent = new Intent(INTENT_RECONNECT_ALARM + "." + apnType);
240074672e8ee972f12406b72551261b4cc7e0651933Wink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, apnContext.getReason());
2401cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, apnType);
240267d43cfed4b996c20780bfec8fde1ae8c1391779Junda Liu        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
2403cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2404a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // Get current sub id.
240538ca51d0f643405df51e78fce6c546424e9f410dShishir Agrawal        int subId = SubscriptionManager.getDefaultDataSubscriptionId();
2406a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
2407a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
240874672e8ee972f12406b72551261b4cc7e0651933Wink Saville        if (DBG) {
240974672e8ee972f12406b72551261b4cc7e0651933Wink Saville            log("startAlarmForReconnect: delay=" + delay + " action=" + intent.getAction()
241074672e8ee972f12406b72551261b4cc7e0651933Wink Saville                    + " apn=" + apnContext);
241174672e8ee972f12406b72551261b4cc7e0651933Wink Saville        }
241274672e8ee972f12406b72551261b4cc7e0651933Wink Saville
24130e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        PendingIntent alarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0,
2414cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                        intent, PendingIntent.FLAG_UPDATE_CURRENT);
2415ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setReconnectIntent(alarmIntent);
24167d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu
24177d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu        // Use the exact timer instead of the inexact one to provide better user experience.
24187d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu        // In some extreme cases, we saw the retry was delayed for few minutes.
24190852a954be5937a1b0bca94df0c2007d7ee3c0c7Jack Yu        // Note that if the stated trigger time is in the past, the alarm will be triggered
24200852a954be5937a1b0bca94df0c2007d7ee3c0c7Jack Yu        // immediately.
24217d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu        mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
2422cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                SystemClock.elapsedRealtime() + delay, alarmIntent);
2423cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2424cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2425ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void notifyNoData(DcFailCause lastFailCauseCode,
2426cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                              ApnContext apnContext) {
2427cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log( "notifyNoData: type=" + apnContext.getApnType());
2428ccfe5ebaf81c1378e8dbe44e45df26b0dc462a21Jack Yu        if (isPermanentFailure(lastFailCauseCode)
2429cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            && (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT))) {
2430cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
2431cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2432cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2433cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
24341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public boolean getAutoAttachOnCreation() {
24351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mAutoAttachOnCreation.get();
24361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
24371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
24381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRecordsLoadedOrSubIdChanged() {
24391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("onRecordsLoadedOrSubIdChanged: createAllApnList");
244012fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        mAutoAttachOnCreationConfig = mPhone.getContext().getResources()
244112fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao                .getBoolean(com.android.internal.R.bool.config_auto_attach_data_on_creation);
2442bda761320929f714951c328bfec6a51a1978db97Wink Saville
2443cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        createAllApnList();
24445d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi        setInitialAttachApn();
244522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPhone.mCi.getRadioState().isOn()) {
24461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("onRecordsLoadedOrSubIdChanged: notifying data availability");
2447cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_SIM_LOADED);
2448cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2449bda761320929f714951c328bfec6a51a1978db97Wink Saville        setupDataOnConnectableApns(Phone.REASON_SIM_LOADED);
2450cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2451cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
24524c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu    /**
24534c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu     * Action set from carrier signalling broadcast receivers to enable/disable metered apns.
24544c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu     */
24556a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu    private void onSetCarrierDataEnabled(AsyncResult ar) {
24566a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu        if (ar.exception != null) {
24576a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu            Rlog.e(LOG_TAG, "CarrierDataEnable exception: " + ar.exception);
24586a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu            return;
24596a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu        }
2460a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        synchronized (mDataEnabledSettings) {
24616a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu            boolean enabled = (boolean) ar.result;
2462a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            if (enabled != mDataEnabledSettings.isCarrierDataEnabled()) {
2463a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                if (DBG) {
2464a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                    log("carrier Action: set metered apns enabled: " + enabled);
2465a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                }
2466a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
2467a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                // Disable/enable all metered apns
2468a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                mDataEnabledSettings.setCarrierDataEnabled(enabled);
2469a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
2470a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                if (!enabled) {
2471a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                    // Send otasp_sim_unprovisioned so that SuW is able to proceed and notify users
24726432c2f4a4f438b72fa0d4b51d5098b179935868Nathan Harold                    mPhone.notifyOtaspChanged(TelephonyManager.OTASP_SIM_UNPROVISIONED);
2473a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                    // Tear down all metered apns
2474a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                    cleanUpAllConnections(true, Phone.REASON_CARRIER_ACTION_DISABLE_METERED_APN);
2475a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                } else {
2476120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    // Re-evaluate Otasp state
24774839eb565b4294443a34a93ee2ca93ac70b72b87fionaxu                    int otaspState = mPhone.getServiceStateTracker().getOtasp();
24784839eb565b4294443a34a93ee2ca93ac70b72b87fionaxu                    mPhone.notifyOtaspChanged(otaspState);
24794839eb565b4294443a34a93ee2ca93ac70b72b87fionaxu
2480120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                    reevaluateDataConnections();
2481a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                    setupDataOnConnectableApns(Phone.REASON_DATA_ENABLED);
2482a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                }
248368f4f4a0bc8d4060b5775e7a24a97ea5b485989efionaxu            }
2484a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        }
2485a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    }
2486a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
24870469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal    private void onSimNotReady() {
24880469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        if (DBG) log("onSimNotReady");
24890469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal
24900469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        cleanUpAllConnections(true, Phone.REASON_SIM_NOT_READY);
24910469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        mAllApnSettings = null;
24920469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        mAutoAttachOnCreationConfig = false;
24937e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C        // Clear auto attach as modem is expected to do a new attach once SIM is ready
24947e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C        mAutoAttachOnCreation.set(false);
24950469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal    }
24960469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal
24971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetDependencyMet(String apnType, boolean met) {
2498cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // don't allow users to tweak hipri to work around default dependency not met
2499cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_HIPRI.equals(apnType)) return;
2500cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2501cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
2502cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
2503cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onSetDependencyMet: ApnContext not found in onSetDependencyMet(" +
2504cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnType + ", " + met + ")");
2505cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
2506cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2507cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        applyNewState(apnContext, apnContext.isEnabled(), met);
2508cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_DEFAULT.equals(apnType)) {
2509cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // tie actions on default to similar actions on HIPRI regarding dependencyMet
2510cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext = mApnContexts.get(PhoneConstants.APN_TYPE_HIPRI);
2511cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext != null) applyNewState(apnContext, apnContext.isEnabled(), met);
2512cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2513cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2514c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2515a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    public void setPolicyDataEnabled(boolean enabled) {
2516a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        if (DBG) log("setPolicyDataEnabled: " + enabled);
2517a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        Message msg = obtainMessage(DctConstants.CMD_SET_POLICY_DATA_ENABLE);
2518a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        msg.arg1 = (enabled ? DctConstants.ENABLED : DctConstants.DISABLED);
2519a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        sendMessage(msg);
2520a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    }
2521a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
25221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetPolicyDataEnabled(boolean enabled) {
2523a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        synchronized (mDataEnabledSettings) {
25241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            final boolean prevEnabled = getAnyDataEnabled();
2525a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            if (mDataEnabledSettings.isPolicyDataEnabled() != enabled) {
2526a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                mDataEnabledSettings.setPolicyDataEnabled(enabled);
2527a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                // TODO: We should register for DataEnabledSetting's data enabled/disabled event and
2528a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                // handle the rest from there.
25291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (prevEnabled != getAnyDataEnabled()) {
25301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (!prevEnabled) {
2531120d52b890d9ec9993747a31b199694ba2c0b7a2Jack Yu                        reevaluateDataConnections();
25321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onTrySetupData(Phone.REASON_DATA_ENABLED);
25331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
25341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);
25351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
25361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
25371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
25381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
25391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
25401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2541cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void applyNewState(ApnContext apnContext, boolean enabled, boolean met) {
2542cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean cleanup = false;
2543cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean trySetup = false;
25442dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        String str ="applyNewState(" + apnContext.getApnType() + ", " + enabled +
25452dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                "(" + apnContext.isEnabled() + "), " + met + "(" +
25462dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                apnContext.getDependencyMet() +"))";
25472dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        if (DBG) log(str);
25482dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog(str);
25492dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt
2550cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext.isReady()) {
2551305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt            cleanup = true;
25522428693913ae731d4ace3414429f5e91af24ea36Wink Saville            if (enabled && met) {
25532428693913ae731d4ace3414429f5e91af24ea36Wink Saville                DctConstants.State state = apnContext.getState();
25542428693913ae731d4ace3414429f5e91af24ea36Wink Saville                switch(state) {
25552428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case CONNECTING:
25562428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case SCANNING:
25572428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case CONNECTED:
25582428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case DISCONNECTING:
25592428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // We're "READY" and active so just return
25602428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        if (DBG) log("applyNewState: 'ready' so return");
25612dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        apnContext.requestLog("applyNewState state=" + state + ", so return");
25622428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        return;
25632428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case IDLE:
25642428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // fall through: this is unexpected but if it happens cleanup and try setup
25652428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case FAILED:
25662428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case RETRYING: {
25672428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // We're "READY" but not active so disconnect (cleanup = true) and
25682428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // connect (trySetup = true) to be sure we retry the connection.
25692428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        trySetup = true;
25702428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        apnContext.setReason(Phone.REASON_DATA_ENABLED);
25712428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        break;
25722428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    }
25732428693913ae731d4ace3414429f5e91af24ea36Wink Saville                }
2574305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt            } else if (met) {
2575cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setReason(Phone.REASON_DATA_DISABLED);
2576305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // If ConnectivityService has disabled this network, stop trying to bring
2577305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // it up, but do not tear it down - ConnectivityService will do that
2578305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // directly by talking with the DataConnection.
25791484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                //
25801484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // This doesn't apply to DUN, however.  Those connections have special
25811484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // requirements from carriers and we need stop using them when the dun
25821484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // request goes away.  This applies to both CDMA and GSM because they both
25831484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // can declare the DUN APN sharable by default traffic, thus still satisfying
25841484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // those requests and not torn down organically.
25851484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                if (apnContext.getApnType() == PhoneConstants.APN_TYPE_DUN && teardownForDun()) {
25861484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    cleanup = true;
25871484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                } else {
25881484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    cleanup = false;
25891484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                }
2590cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
2591cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_UNMET);
2592cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2593cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2594cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (enabled && met) {
2595cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apnContext.isEnabled()) {
2596cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_MET);
2597cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2598cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setReason(Phone.REASON_DATA_ENABLED);
2599c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
2600cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apnContext.getState() == DctConstants.State.FAILED) {
2601cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setState(DctConstants.State.IDLE);
2602cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2603cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                trySetup = true;
2604cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2605cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2606cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setEnabled(enabled);
2607cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setDependencyMet(met);
2608cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cleanup) cleanUpConnection(true, apnContext);
26090d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt        if (trySetup) {
26100d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt            apnContext.resetErrorCodeRetries();
26110d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt            trySetupData(apnContext);
26120d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt        }
2613cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2614c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2615454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel checkForCompatibleConnectedApnContext(ApnContext apnContext) {
2616cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String apnType = apnContext.getApnType();
2617cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnSetting dunSetting = null;
2618cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2619cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_DUN.equals(apnType)) {
2620cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            dunSetting = fetchDunApn();
2621cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2622ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) {
2623ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            log("checkForCompatibleConnectedApnContext: apnContext=" + apnContext );
2624ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
2625cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2626454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel potentialDcac = null;
2627ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnContext potentialApnCtx = null;
2628ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        for (ApnContext curApnCtx : mApnContexts.values()) {
2629454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel curDcac = curApnCtx.getDcAc();
2630ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (curDcac != null) {
2631ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                ApnSetting apnSetting = curApnCtx.getApnSetting();
2632a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("apnSetting: " + apnSetting);
2633cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (dunSetting != null) {
2634cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (dunSetting.equals(apnSetting)) {
2635ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        switch (curApnCtx.getState()) {
2636cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            case CONNECTED:
2637cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                if (DBG) {
2638ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                    log("checkForCompatibleConnectedApnContext:"
2639ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                            + " found dun conn=" + curDcac
2640ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                            + " curApnCtx=" + curApnCtx);
2641cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                }
2642ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                return curDcac;
2643ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            case RETRYING:
2644cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            case CONNECTING:
2645ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                potentialDcac = curDcac;
2646ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                potentialApnCtx = curApnCtx;
2647cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            default:
2648cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // Not connected, potential unchanged
2649cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                break;
2650cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
2651cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2652cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else if (apnSetting != null && apnSetting.canHandleType(apnType)) {
2653ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    switch (curApnCtx.getState()) {
2654cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        case CONNECTED:
2655cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            if (DBG) {
2656ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                log("checkForCompatibleConnectedApnContext:"
2657ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        + " found canHandle conn=" + curDcac
2658ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        + " curApnCtx=" + curApnCtx);
2659cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            }
2660ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            return curDcac;
2661ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        case RETRYING:
2662cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        case CONNECTING:
2663ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            potentialDcac = curDcac;
2664ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            potentialApnCtx = curApnCtx;
2665cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        default:
2666cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            // Not connected, potential unchanged
2667cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            break;
2668cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2669cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2670ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            } else {
2671ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) {
2672ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    log("checkForCompatibleConnectedApnContext: not conn curApnCtx=" + curApnCtx);
2673ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                }
2674cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2675cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2676ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (potentialDcac != null) {
2677cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
2678ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                log("checkForCompatibleConnectedApnContext: found potential conn=" + potentialDcac
2679ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        + " curApnCtx=" + potentialApnCtx);
2680cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2681ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            return potentialDcac;
2682cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2683c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2684ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("checkForCompatibleConnectedApnContext: NO conn apnContext=" + apnContext);
2685cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
2686cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2687c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
268827b650c406018355a88a41528db7859e232728a0Jack Yu    public void setEnabled(int id, boolean enable) {
26891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_ENABLE_NEW_APN);
26901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = id;
26911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg2 = (enable ? DctConstants.ENABLED : DctConstants.DISABLED);
26921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
26931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
26941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
26951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onEnableApn(int apnId, int enabled) {
2696af5593594070f825032be46dced573cd195956e1Robert Greenwalt        ApnContext apnContext = mApnContextsById.get(apnId);
2697cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
2698cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onEnableApn(" + apnId + ", " + enabled + "): NO ApnContext");
2699cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
2700cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2701cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO change our retry manager to use the appropriate numbers for the new APN
2702cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onEnableApn: apnContext=" + apnContext + " call applyNewState");
2703cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        applyNewState(apnContext, enabled == DctConstants.ENABLED, apnContext.getDependencyMet());
2704af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla
2705af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla        if ((enabled == DctConstants.DISABLED) &&
2706af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology()) &&
2707af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            !isHigherPriorityApnContextActive(apnContext)) {
2708af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla
2709af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            if(DBG) log("onEnableApn: isOnlySingleDcAllowed true & higher priority APN disabled");
2710af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            // If the highest priority APN is disabled and only single
2711af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            // data call is allowed, try to setup data call on other connectable APN.
2712af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla            setupDataOnConnectableApns(Phone.REASON_SINGLE_PDN_ARBITRATION);
2713af0722d026bf9687288c5aed65cdae9acc46059cNaveen Kalla        }
2714cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2715c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2716cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // TODO: We shouldnt need this.
27171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean onTrySetupData(String reason) {
2718cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onTrySetupData: reason=" + reason);
2719ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(reason);
2720cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
2721cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2722c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
27231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean onTrySetupData(ApnContext apnContext) {
2724cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onTrySetupData: apnContext=" + apnContext);
2725cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return trySetupData(apnContext);
2726cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2727c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
27281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
27291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Return current {@link android.provider.Settings.Global#MOBILE_DATA} value.
27301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
2731a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    //TODO: Merge this into DataSettings. And probably should rename to getUserDataEnabled().
27321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public boolean getDataEnabled() {
2733f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        final int device_provisioned =
2734f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                Settings.Global.getInt(mResolver, Settings.Global.DEVICE_PROVISIONED, 0);
2735f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
27361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        boolean retVal = "true".equalsIgnoreCase(SystemProperties.get(
27371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                "ro.com.android.mobiledata", "true"));
2738f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        if (TelephonyManager.getDefault().getSimCount() == 1) {
2739f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            retVal = Settings.Global.getInt(mResolver, Settings.Global.MOBILE_DATA,
2740f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                    retVal ? 1 : 0) != 0;
2741f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        } else {
2742f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            int phoneSubId = mPhone.getSubId();
2743f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            try {
2744f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                retVal = TelephonyManager.getIntWithSubId(mResolver,
2745f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                        Settings.Global.MOBILE_DATA, phoneSubId) != 0;
2746f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            } catch (SettingNotFoundException e) {
2747f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                // use existing retVal
2748f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            }
2749f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        }
2750f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        if (VDBG) log("getDataEnabled: retVal=" + retVal);
2751f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        if (device_provisioned == 0) {
2752f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            // device is still getting provisioned - use whatever setting they
2753f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            // want during this process
2754f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            //
2755f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            // use the normal data_enabled setting (retVal, determined above)
2756f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            // as the default if nothing else is set
2757f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            final String prov_property = SystemProperties.get("ro.com.android.prov_mobiledata",
2758f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                  retVal ? "true" : "false");
2759f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            retVal = "true".equalsIgnoreCase(prov_property);
2760f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
2761f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            final int prov_mobile_data = Settings.Global.getInt(mResolver,
2762f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                    Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED,
2763f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                    retVal ? 1 : 0);
2764f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            retVal = prov_mobile_data != 0;
2765f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            log("getDataEnabled during provisioning retVal=" + retVal + " - (" + prov_property +
2766f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                    ", " + prov_mobile_data + ")");
27671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
2768f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
27691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return retVal;
27701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
27711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
27721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
27731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Modify {@link android.provider.Settings.Global#DATA_ROAMING} value.
27741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
27755b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    public void setDataRoamingEnabled(boolean enabled) {
27761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        final int phoneSubId = mPhone.getSubId();
27775b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (getDataRoamingEnabled() != enabled) {
27781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            int roaming = enabled ? 1 : 0;
27791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
27801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // For single SIM phones, this is a per phone property.
27811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (TelephonyManager.getDefault().getSimCount() == 1) {
27821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Settings.Global.putInt(mResolver, Settings.Global.DATA_ROAMING, roaming);
27831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
27841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Settings.Global.putInt(mResolver, Settings.Global.DATA_ROAMING +
27851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                         phoneSubId, roaming);
27861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
27871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
27881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSubscriptionManager.setDataRoaming(roaming, phoneSubId);
27891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // will trigger handleDataOnRoamingChange() through observer
27901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
27915b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu                log("setDataRoamingEnabled: set phoneSubId=" + phoneSubId
27925b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu                        + " isRoaming=" + enabled);
27931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
27941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
27951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
27965b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu                log("setDataRoamingEnabled: unchanged phoneSubId=" + phoneSubId
27971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        + " isRoaming=" + enabled);
27981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu             }
27991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
28001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
28011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
28021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
28031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Return current {@link android.provider.Settings.Global#DATA_ROAMING} value.
28041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
28055b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    public boolean getDataRoamingEnabled() {
28061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        boolean isDataRoamingEnabled = "true".equalsIgnoreCase(SystemProperties.get(
28071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                "ro.com.android.dataroaming", "false"));
28081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        final int phoneSubId = mPhone.getSubId();
28091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
28101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        try {
28111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // For single SIM phones, this is a per phone property.
28121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (TelephonyManager.getDefault().getSimCount() == 1) {
28131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                isDataRoamingEnabled = Settings.Global.getInt(mResolver,
28141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.DATA_ROAMING, isDataRoamingEnabled ? 1 : 0) != 0;
28151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
28161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                isDataRoamingEnabled = TelephonyManager.getIntWithSubId(mResolver,
28171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.DATA_ROAMING, phoneSubId) != 0;
28181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
28191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } catch (SettingNotFoundException snfe) {
28205b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            if (DBG) log("getDataRoamingEnabled: SettingNofFoundException snfe=" + snfe);
28211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
28221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) {
28235b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            log("getDataRoamingEnabled: phoneSubId=" + phoneSubId
28245b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu                    + " isDataRoamingEnabled=" + isDataRoamingEnabled);
28251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
28261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return isDataRoamingEnabled;
28271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
28281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
28295b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    // When the data roaming status changes from roaming to non-roaming.
28305b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    private void onDataRoamingOff() {
28315b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (DBG) log("onDataRoamingOff");
2832c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
28335b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (!getDataRoamingEnabled()) {
28345b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // TODO: Remove this once all old vendor RILs are gone. We don't need to set initial apn
28355b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // attach and send the data profile again as the modem should have both roaming and
28365b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // non-roaming protocol in place. Modem should choose the right protocol based on the
28375b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // roaming condition.
28385b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            setInitialAttachApn();
28395b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            setDataProfilesAsNeeded();
28408e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu
28415b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // If the user did not enable data roaming, now when we transit from roaming to
28425b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // non-roaming, we should try to reestablish the data connection.
2843c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2844cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_OFF);
2845bda761320929f714951c328bfec6a51a1978db97Wink Saville            setupDataOnConnectableApns(Phone.REASON_ROAMING_OFF);
2846cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2847cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_ROAMING_OFF);
2848cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2849cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2850cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
28515b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    // This method is called
28525b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    // 1. When the data roaming status changes from non-roaming to roaming.
28535b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    // 2. When allowed data roaming settings is changed by the user.
28545b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu    private void onDataRoamingOnOrSettingsChanged() {
28555b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (DBG) log("onDataRoamingOnOrSettingsChanged");
2856f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu
2857f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu        // Check if the device is actually data roaming
2858f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu        if (!mPhone.getServiceState().getDataRoaming()) {
2859f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu            if (DBG) log("device is not roaming. ignored the request.");
2860f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu            return;
2861f629e7f1a1e36215d9bbed40df310a54b772f9e9Jack Yu        }
2862cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
28635b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu        if (getDataRoamingEnabled()) {
28645b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            if (DBG) log("onDataRoamingOnOrSettingsChanged: setup data on roaming");
28655b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu
2866ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_ROAMING_ON);
2867cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_ROAMING_ON);
2868cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
28695b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // If the user does not turn on data roaming, when we transit from non-roaming to
28705b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // roaming, we need to tear down the data connection otherwise the user might be
28715b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            // charged for data roaming usage.
28725b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu            if (DBG) log("onDataRoamingOnOrSettingsChanged: Tear down data connection on roaming.");
2873cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpAllConnections(true, Phone.REASON_ROAMING_ON);
2874cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
2875cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2876cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2877cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
28781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRadioAvailable() {
2879cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onRadioAvailable");
2880cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
2881cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
2882cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
2883cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // setState(DctConstants.State.CONNECTED);
2884cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(null);
2885cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2886cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("onRadioAvailable: We're on the simulator; assuming data is connected");
2887cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2888cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2889cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
2890cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (r != null && r.getRecordsLoaded()) {
2891cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(null);
2892cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2893cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2894cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getOverallState() != DctConstants.State.IDLE) {
2895cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpConnection(true, null);
2896cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2897cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2898cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
28991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRadioOffOrNotAvailable() {
2900cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Make sure our reconnect delay starts at the initial value
2901cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // next time the radio comes on
2902cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2903cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mReregisterOnReconnectFailure = false;
2904cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
29057e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C        // Clear auto attach as modem is expected to do a new attach
29067e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C        mAutoAttachOnCreation.set(false);
29077e1fba5b0d8ab3815fdbd1e66f22ca3ab7decb83Jayachandran C
2908cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
2909cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
2910cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
2911cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("We're on the simulator; assuming radio off is meaningless");
2912cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2913cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRadioOffOrNotAvailable: is off and clean up all connections");
2914cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpAllConnections(false, Phone.REASON_RADIO_TURNED_OFF);
2915cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2916cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyOffApnsOfAvailability(null);
2917cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2918cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
29191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void completeConnection(ApnContext apnContext) {
2920c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2921c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (DBG) log("completeConnection: successful, notify the world apnContext=" + apnContext);
2922c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2923c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (mIsProvisioning && !TextUtils.isEmpty(mProvisioningUrl)) {
2924c9b81a0c05128694c617fcdd67e73821895822feWink Saville            if (DBG) {
2925c9b81a0c05128694c617fcdd67e73821895822feWink Saville                log("completeConnection: MOBILE_PROVISIONING_ACTION url="
2926c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        + mProvisioningUrl);
2927c9b81a0c05128694c617fcdd67e73821895822feWink Saville            }
2928c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt            Intent newIntent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN,
2929c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt                    Intent.CATEGORY_APP_BROWSER);
2930c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt            newIntent.setData(Uri.parse(mProvisioningUrl));
2931c9b81a0c05128694c617fcdd67e73821895822feWink Saville            newIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
2932c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    Intent.FLAG_ACTIVITY_NEW_TASK);
2933c9b81a0c05128694c617fcdd67e73821895822feWink Saville            try {
2934c9b81a0c05128694c617fcdd67e73821895822feWink Saville                mPhone.getContext().startActivity(newIntent);
2935c9b81a0c05128694c617fcdd67e73821895822feWink Saville            } catch (ActivityNotFoundException e) {
2936c9b81a0c05128694c617fcdd67e73821895822feWink Saville                loge("completeConnection: startActivityAsUser failed" + e);
2937c9b81a0c05128694c617fcdd67e73821895822feWink Saville            }
2938c9b81a0c05128694c617fcdd67e73821895822feWink Saville        }
2939c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mIsProvisioning = false;
2940c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mProvisioningUrl = null;
29412b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        if (mProvisioningSpinner != null) {
29422b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            sendMessage(obtainMessage(DctConstants.CMD_CLEAR_PROVISIONING_SPINNER,
29432b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner));
29442b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        }
2945c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2946c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
2947c9b81a0c05128694c617fcdd67e73821895822feWink Saville        startNetStatPoll();
2948c9b81a0c05128694c617fcdd67e73821895822feWink Saville        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
2949c9b81a0c05128694c617fcdd67e73821895822feWink Saville    }
2950c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2951ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
2952ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * A SETUP (aka bringUp) has completed, possibly with an error. If
2953ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * there is an error this method will call {@link #onDataSetupCompleteError}.
2954ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
29551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataSetupComplete(AsyncResult ar) {
2956608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt
2957ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        DcFailCause cause = DcFailCause.UNKNOWN;
2958cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean handleError = false;
2959ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDataSetupComplete");
2960cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2961ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
2962cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2963cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (ar.exception == null) {
2964454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = apnContext.getDcAc();
2965cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2966cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (RADIO_TESTS) {
2967cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Note: To change radio.test.onDSC.null.dcac from command line you need to
2968cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // adb root and adb remount and from the command line you can only change the
2969cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // value to 1 once. To change it a second time you can reboot or execute
2970cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // adb shell stop and then adb shell start. The command line to set the value is:
2971ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink 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');"
2972cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ContentResolver cr = mPhone.getContext().getContentResolver();
2973cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                String radioTestProperty = "radio.test.onDSC.null.dcac";
2974cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (Settings.System.getInt(cr, radioTestProperty, 0) == 1) {
2975cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: " + radioTestProperty +
2976cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            " is true, set dcac to null and reset property to false");
2977cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    dcac = null;
2978cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    Settings.System.putInt(cr, radioTestProperty, 0);
2979cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: " + radioTestProperty + "=" +
2980cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            Settings.System.getInt(mPhone.getContext().getContentResolver(),
2981cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                    radioTestProperty, -1));
2982cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2983c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2984cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac == null) {
2985cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("onDataSetupComplete: no connection to DC, handle as error");
2986ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                cause = DcFailCause.CONNECTION_TO_DATACONNECTIONAC_BROKEN;
2987cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                handleError = true;
2988cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
2989cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ApnSetting apn = apnContext.getApnSetting();
2990cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
2991cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: success apn=" + (apn == null ? "unknown" : apn.apn));
2992cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2993cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn != null && apn.proxy != null && apn.proxy.length() != 0) {
2994cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    try {
2995cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        String port = apn.port;
2996cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (TextUtils.isEmpty(port)) port = "8080";
29979c180aedfc9f0d20525c0128487d3500e6c0a715Jason Monk                        ProxyInfo proxy = new ProxyInfo(apn.proxy,
2998cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                Integer.parseInt(port), null);
2999cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        dcac.setLinkPropertiesHttpProxySync(proxy);
3000cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    } catch (NumberFormatException e) {
3001cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        loge("onDataSetupComplete: NumberFormatException making ProxyProperties (" +
3002cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                apn.port + "): " + e);
3003cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
3004cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3005cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3006cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // everything is setup
3007cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if(TextUtils.equals(apnContext.getApnType(),PhoneConstants.APN_TYPE_DEFAULT)) {
300827b650c406018355a88a41528db7859e232728a0Jack Yu                    try {
300927b650c406018355a88a41528db7859e232728a0Jack Yu                        SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "true");
301027b650c406018355a88a41528db7859e232728a0Jack Yu                    } catch (RuntimeException ex) {
301127b650c406018355a88a41528db7859e232728a0Jack Yu                        log("Failed to set PUPPET_MASTER_RADIO_STRESS_TEST to true");
301227b650c406018355a88a41528db7859e232728a0Jack Yu                    }
301322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mCanSetPreferApn && mPreferredApn == null) {
30140e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                        if (DBG) log("onDataSetupComplete: PREFERRED APN is null");
3015cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mPreferredApn = apn;
3016cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (mPreferredApn != null) {
3017cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            setPreferredApn(mPreferredApn.id);
3018cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
3019cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
3020cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
302127b650c406018355a88a41528db7859e232728a0Jack Yu                    try {
302227b650c406018355a88a41528db7859e232728a0Jack Yu                        SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
302327b650c406018355a88a41528db7859e232728a0Jack Yu                    } catch (RuntimeException ex) {
302427b650c406018355a88a41528db7859e232728a0Jack Yu                        log("Failed to set PUPPET_MASTER_RADIO_STRESS_TEST to false");
302527b650c406018355a88a41528db7859e232728a0Jack Yu                    }
3026cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3027c9b81a0c05128694c617fcdd67e73821895822feWink Saville
3028c9b81a0c05128694c617fcdd67e73821895822feWink Saville                // A connection is setup
3029c9b81a0c05128694c617fcdd67e73821895822feWink Saville                apnContext.setState(DctConstants.State.CONNECTED);
30300e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
3031c9b81a0c05128694c617fcdd67e73821895822feWink Saville                boolean isProvApn = apnContext.isProvisioningApn();
3032b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                final ConnectivityManager cm = ConnectivityManager.from(mPhone.getContext());
3033b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                if (mProvisionBroadcastReceiver != null) {
3034b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mPhone.getContext().unregisterReceiver(mProvisionBroadcastReceiver);
3035b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mProvisionBroadcastReceiver = null;
3036b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                }
3037c9b81a0c05128694c617fcdd67e73821895822feWink Saville                if ((!isProvApn) || mIsProvisioning) {
3038b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // Hide any provisioning notification.
3039b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    cm.setProvisioningNotificationVisible(false, ConnectivityManager.TYPE_MOBILE,
3040b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                            mProvisionActionName);
3041c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // Complete the connection normally notifying the world we're connected.
3042c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // We do this if this isn't a special provisioning apn or if we've been
3043c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // told its time to provision.
3044c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    completeConnection(apnContext);
3045c9b81a0c05128694c617fcdd67e73821895822feWink Saville                } else {
3046c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // This is a provisioning APN that we're reporting as connected. Later
3047c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // when the user desires to upgrade this to a "default" connection,
3048c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // mIsProvisioning == true, we'll go through the code path above.
3049c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // mIsProvisioning becomes true when CMD_ENABLE_MOBILE_PROVISIONING
3050c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // is sent to the DCT.
3051c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    if (DBG) {
3052c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        log("onDataSetupComplete: successful, BUT send connected to prov apn as"
3053c9b81a0c05128694c617fcdd67e73821895822feWink Saville                                + " mIsProvisioning:" + mIsProvisioning + " == false"
3054c9b81a0c05128694c617fcdd67e73821895822feWink Saville                                + " && (isProvisioningApn:" + isProvApn + " == true");
3055c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    }
3056c9b81a0c05128694c617fcdd67e73821895822feWink Saville
3057b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // While radio is up, grab provisioning URL.  The URL contains ICCID which
3058b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // disappears when radio is off.
3059b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mProvisionBroadcastReceiver = new ProvisionNotificationBroadcastReceiver(
30602b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                            cm.getMobileProvisioningUrl(),
30612b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                            TelephonyManager.getDefault().getNetworkOperatorName());
3062b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mPhone.getContext().registerReceiver(mProvisionBroadcastReceiver,
3063b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                            new IntentFilter(mProvisionActionName));
3064b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // Put up user notification that sign-in is required.
3065b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    cm.setProvisioningNotificationVisible(true, ConnectivityManager.TYPE_MOBILE,
3066b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                            mProvisionActionName);
3067b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // Turn off radio to save battery and avoid wasting carrier resources.
3068b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // The network isn't usable and network validation will just fail anyhow.
3069b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    setRadio(false);
3070c9b81a0c05128694c617fcdd67e73821895822feWink Saville                }
3071c9b81a0c05128694c617fcdd67e73821895822feWink Saville                if (DBG) {
3072c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    log("onDataSetupComplete: SETUP complete type=" + apnContext.getApnType()
3073c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        + ", reason:" + apnContext.getReason());
3074c9b81a0c05128694c617fcdd67e73821895822feWink Saville                }
30754c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                if (Build.IS_DEBUGGABLE) {
30764c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                    // adb shell setprop persist.radio.test.pco [pco_val]
30774c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                    String radioTestProperty = "persist.radio.test.pco";
3078cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    int pcoVal = SystemProperties.getInt(radioTestProperty, -1);
3079cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    if (pcoVal != -1) {
3080cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        log("PCO testing: read pco value from persist.radio.test.pco " + pcoVal);
3081cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        final byte[] value = new byte[1];
3082cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        value[0] = (byte) pcoVal;
3083cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        final Intent intent =
3084cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                                new Intent(TelephonyIntents.ACTION_CARRIER_SIGNAL_PCO_VALUE);
3085cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        intent.putExtra(TelephonyIntents.EXTRA_APN_TYPE_KEY, "default");
3086cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        intent.putExtra(TelephonyIntents.EXTRA_APN_PROTO_KEY, "IPV4V6");
3087cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        intent.putExtra(TelephonyIntents.EXTRA_PCO_ID_KEY, 0xFF00);
3088cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        intent.putExtra(TelephonyIntents.EXTRA_PCO_VALUE_KEY, value);
3089cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
3090cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    }
30914c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                }
3092c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3093cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
3094ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            cause = (DcFailCause) (ar.result);
3095cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
3096cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ApnSetting apn = apnContext.getApnSetting();
3097cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log(String.format("onDataSetupComplete: error apn=%s cause=%s",
3098cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        (apn == null ? "unknown" : apn.apn), cause));
3099c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3100cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cause.isEventLoggable()) {
3101cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Log this failure to the Event Logs.
3102cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                int cid = getCellLocationId();
3103cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                EventLog.writeEvent(EventLogTags.PDP_SETUP_FAIL,
3104cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        cause.ordinal(), cid, TelephonyManager.getDefault().getNetworkType());
3105c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
31060742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela            ApnSetting apn = apnContext.getApnSetting();
31070742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela            mPhone.notifyPreciseDataConnectionFailed(apnContext.getReason(),
31080742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela                    apnContext.getApnType(), apn != null ? apn.apn : "unknown", cause.toString());
3109cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
31104c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            // Compose broadcast intent send to the specific carrier signaling receivers
31114c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            Intent intent = new Intent(TelephonyIntents
31124c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                    .ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED);
31134c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            intent.putExtra(TelephonyIntents.EXTRA_ERROR_CODE_KEY, cause.getErrorCode());
31144c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            intent.putExtra(TelephonyIntents.EXTRA_APN_TYPE_KEY, apnContext.getApnType());
31154c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
3116a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
311731f84bf1a4f1c945f7ca4646095ef4717a261c98Jordan Liu            if (cause.isRestartRadioFail(mPhone.getContext(), mPhone.getSubId()) ||
311831f84bf1a4f1c945f7ca4646095ef4717a261c98Jordan Liu                    apnContext.restartOnError(cause.getErrorCode())) {
31190e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                if (DBG) log("Modem restarted.");
31200e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                sendRestartRadio();
31210e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            }
3122cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
31230e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // If the data call failure cause is a permanent failure, we mark the APN as permanent
31240e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // failed.
3125ccfe5ebaf81c1378e8dbe44e45df26b0dc462a21Jack Yu            if (isPermanentFailure(cause)) {
31260e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                log("cause = " + cause + ", mark apn as permanent failed. apn = " + apn);
31270e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                apnContext.markApnPermanentFailed(apn);
3128c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
31290e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
3130cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            handleError = true;
3131cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3132cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3133cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (handleError) {
3134ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            onDataSetupCompleteError(ar);
3135ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
3136a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3137a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        /* If flag is set to false after SETUP_DATA_CALL is invoked, we need
3138a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         * to clean data connections.
3139a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         */
3140a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        if (!mDataEnabledSettings.isInternalDataEnabled()) {
31414fdc57b9bf223c908474c4545cc6f63456117a3bSanket Padawe            cleanUpAllConnections(Phone.REASON_DATA_DISABLED);
3142a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
3143a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3144ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
3145cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3146ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
3147ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt     * check for obsolete messages.  Return ApnContext if valid, null if not
3148ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt     */
3149ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt    private ApnContext getValidApnContext(AsyncResult ar, String logString) {
3150ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (ar != null && ar.userObj instanceof Pair) {
3151ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            Pair<ApnContext, Integer>pair = (Pair<ApnContext, Integer>)ar.userObj;
3152ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            ApnContext apnContext = pair.first;
3153ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            if (apnContext != null) {
31541a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                final int generation = apnContext.getConnectionGeneration();
31551a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                if (DBG) {
31561a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                    log("getValidApnContext (" + logString + ") on " + apnContext + " got " +
31571a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                            generation + " vs " + pair.second);
31581a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                }
31591a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                if (generation == pair.second) {
3160ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                    return apnContext;
3161ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                } else {
3162ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                    log("ignoring obsolete " + logString);
3163ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                    return null;
3164ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                }
3165ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            }
3166ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        }
3167ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        throw new RuntimeException(logString + ": No apnContext");
3168ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt    }
3169ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt
3170ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt    /**
3171ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Error has occurred during the SETUP {aka bringUP} request and the DCT
3172ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * should either try the next waiting APN or start over from the
3173ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * beginning if the list is empty. Between each SETUP request there will
3174ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville     * be a delay defined by {@link #getApnDelay()}.
3175ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
31761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataSetupCompleteError(AsyncResult ar) {
31770e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
3178ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDataSetupCompleteError");
3179ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3180ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
3181ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
31820e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        long delay = apnContext.getDelayForNextApn(mFailFast);
3183ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
31840e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        // Check if we need to retry or not.
31850852a954be5937a1b0bca94df0c2007d7ee3c0c7Jack Yu        if (delay >= 0) {
31860e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (DBG) log("onDataSetupCompleteError: Try next APN. delay = " + delay);
3187ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext.setState(DctConstants.State.SCANNING);
3188ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // Wait a bit before trying the next APN, so that
3189ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // we're not tying up the RIL command channel
31900e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            startAlarmForReconnect(delay, apnContext);
31910e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        } else {
31920e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // If we are not going to retry any APN, set this APN context to failed state.
31930e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // This would be the final state of a data connection.
31940e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            apnContext.setState(DctConstants.State.FAILED);
31950e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType());
31960e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            apnContext.setDataConnectionAc(null);
31970e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            log("onDataSetupCompleteError: Stop retrying APNs.");
3198c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3199c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3200c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3201c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
3202a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu     * Called when EVENT_REDIRECTION_DETECTED is received.
3203a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu     */
32044c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu    private void onDataConnectionRedirected(String redirectUrl) {
3205a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        if (!TextUtils.isEmpty(redirectUrl)) {
32064c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            Intent intent = new Intent(TelephonyIntents.ACTION_CARRIER_SIGNAL_REDIRECTED);
32074c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu            intent.putExtra(TelephonyIntents.EXTRA_REDIRECTION_URL_KEY, redirectUrl);
32086a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu            mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
32096a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu            log("Notify carrier signal receivers with redirectUrl: " + redirectUrl);
3210a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        }
3211a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    }
3212a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
3213a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    /**
3214cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Called when EVENT_DISCONNECT_DONE is received.
3215c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
32161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDisconnectDone(AsyncResult ar) {
3217ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDisconnectDone");
3218ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
3219c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3220cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE apnContext=" + apnContext);
3221cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setState(DctConstants.State.IDLE);
3222cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3223cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
3224cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3225cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // if all data connection are gone, check whether Airplane mode request was
3226cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // pending.
3227cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isDisconnected()) {
3228cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPhone.getServiceStateTracker().processPendingRadioPowerOffAfterDataOff()) {
3229a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                if (DBG) log("onDisconnectDone: radio will be turned off, no retries");
3230cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Radio will be turned off. No need to retry data setup
3231cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setApnSetting(null);
3232cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setDataConnectionAc(null);
3233a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3234a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // Need to notify disconnect as well, in the case of switching Airplane mode.
3235a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // Otherwise, it would cause 30s delayed to turn on Airplane mode.
32360e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                if (mDisconnectPendingCount > 0) {
3237a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mDisconnectPendingCount--;
32380e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                }
3239a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3240a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mDisconnectPendingCount == 0) {
3241a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    notifyDataDisconnectComplete();
3242a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    notifyAllDataDisconnected();
3243a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
3244cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return;
3245cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3246c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3247cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // If APN is still enabled, try to bring it back up automatically
32483fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (mAttached.get() && apnContext.isReady() && retryAfterDisconnected(apnContext)) {
324927b650c406018355a88a41528db7859e232728a0Jack Yu            try {
325027b650c406018355a88a41528db7859e232728a0Jack Yu                SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
325127b650c406018355a88a41528db7859e232728a0Jack Yu            } catch (RuntimeException ex) {
325227b650c406018355a88a41528db7859e232728a0Jack Yu                log("Failed to set PUPPET_MASTER_RADIO_STRESS_TEST to false");
325327b650c406018355a88a41528db7859e232728a0Jack Yu            }
3254cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Wait a bit before trying the next APN, so that
3255cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // we're not tying up the RIL command channel.
3256cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // This also helps in any external dependency to turn off the context.
32570e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (DBG) log("onDisconnectDone: attached, ready and retry after disconnect");
32580e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            long delay = apnContext.getInterApnDelay(mFailFast);
32590e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (delay > 0) {
32600e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                // Data connection is in IDLE state, so when we reconnect later, we'll rebuild
32610e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                // the waiting APN list, which will also reset/reconfigure the retry manager.
32620e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                startAlarmForReconnect(delay, apnContext);
32630e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            }
3264c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
3265449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            boolean restartRadioAfterProvisioning = mPhone.getContext().getResources().getBoolean(
3266449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                    com.android.internal.R.bool.config_restartRadioAfterProvisioning);
3267449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville
3268449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            if (apnContext.isProvisioningApn() && restartRadioAfterProvisioning) {
3269449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                log("onDisconnectDone: restartRadio after provisioning");
3270449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                restartRadio();
3271449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            }
3272cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setApnSetting(null);
3273cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setDataConnectionAc(null);
32743fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())) {
3275449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                if(DBG) log("onDisconnectDone: isOnlySigneDcAllowed true so setup single apn");
32763fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                setupDataOnConnectableApns(Phone.REASON_SINGLE_PDN_ARBITRATION);
3277449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            } else {
3278449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                if(DBG) log("onDisconnectDone: not retrying");
32793fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
3280c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3281a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3282a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mDisconnectPendingCount > 0)
3283a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mDisconnectPendingCount--;
3284a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3285a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mDisconnectPendingCount == 0) {
3286c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt            apnContext.setConcurrentVoiceAndDataAllowed(
3287c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed());
3288a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyDataDisconnectComplete();
3289a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
3290a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
3291a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3292c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3293c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3294ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
3295ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Called when EVENT_DISCONNECT_DC_RETRYING is received.
3296ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
32971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDisconnectDcRetrying(AsyncResult ar) {
3298ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // We could just do this in DC!!!
3299ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDisconnectDcRetrying");
3300ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
3301ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3302ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setState(DctConstants.State.RETRYING);
3303ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if(DBG) log("onDisconnectDcRetrying: apnContext=" + apnContext);
3304ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3305ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
3306ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
3307ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
33081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onVoiceCallStarted() {
3309cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onVoiceCallStarted");
3310ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        mInVoiceCall = true;
3311cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnected() && ! mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
3312cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onVoiceCallStarted stop polling");
3313cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            stopNetStatPoll();
3314cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            stopDataStallAlarm();
3315cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
3316c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3317c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3318c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
33191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onVoiceCallEnded() {
3320cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onVoiceCallEnded");
3321ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        mInVoiceCall = false;
3322cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnected()) {
3323cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
3324cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                startNetStatPoll();
3325cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
3326cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
3327cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
3328cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // clean slate after call end.
3329cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                resetPollStats();
3330c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3331c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3332bda761320929f714951c328bfec6a51a1978db97Wink Saville        // reset reconnect timer
3333bda761320929f714951c328bfec6a51a1978db97Wink Saville        setupDataOnConnectableApns(Phone.REASON_VOICE_CALL_ENDED);
3334c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3335c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
33361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onCleanUpConnection(boolean tearDown, int apnId, String reason) {
3337cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onCleanUpConnection");
3338af5593594070f825032be46dced573cd195956e1Robert Greenwalt        ApnContext apnContext = mApnContextsById.get(apnId);
3339cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
3340cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setReason(reason);
3341cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpConnection(tearDown, apnContext);
3342c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3343c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3344c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
33451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean isConnected() {
3346cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
3347ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getState() == DctConstants.State.CONNECTED) {
3348cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // At least one context is connected, return true
3349cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return true;
3350c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3351c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3352cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // There are not any contexts connected, return false
3353cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return false;
3354c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3355c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3356cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isDisconnected() {
3357cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
3358cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!apnContext.isDisconnected()) {
3359cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // At least one context was not disconnected return false
3360cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
3361cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3362c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3363cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // All contexts were disconnected so return true
3364cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
3365c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3366c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
33671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyDataConnection(String reason) {
3368cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("notifyDataConnection: reason=" + reason);
3369cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
3370187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (mAttached.get() && apnContext.isReady()) {
3371187a39f896f88eb6c5e4306d9595546654825976Wink Saville                if (DBG) log("notifyDataConnection: type:" + apnContext.getApnType());
3372cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
3373cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.getApnType());
3374cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3375c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3376cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyOffApnsOfAvailability(reason);
3377c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3378c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
33791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void setDataProfilesAsNeeded() {
33801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("setDataProfilesAsNeeded");
33811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mAllApnSettings != null && !mAllApnSettings.isEmpty()) {
33821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            ArrayList<DataProfile> dps = new ArrayList<DataProfile>();
33831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (ApnSetting apn : mAllApnSettings) {
33841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (apn.modemCognitive) {
33858e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                    DataProfile dp = new DataProfile(apn);
33868e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                    if (!dps.contains(dp)) {
33871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        dps.add(dp);
33881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
33891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
33901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
33918e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu            if (dps.size() > 0) {
33928e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                mPhone.mCi.setDataProfile(dps.toArray(new DataProfile[0]),
33938e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                        mPhone.getServiceState().getDataRoaming(), null);
33941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
33951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
33961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
33971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3398c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
3399cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Based on the sim operator numeric, create a list for all possible
3400cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Data Connections and setup the preferredApn.
3401c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
3402cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void createAllApnList() {
34031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mMvnoMatched = false;
34048e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu        mAllApnSettings = new ArrayList<>();
3405cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
3406cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String operator = (r != null) ? r.getOperatorNumeric() : "";
3407cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (operator != null) {
34083c89e23cf33c3c7f795554b29cd926219f28fe34Sungmin Choi            String selection = Telephony.Carriers.NUMERIC + " = '" + operator + "'";
3409cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // query only enabled apn.
3410cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // carrier_enabled : 1 means enabled apn, 0 disabled apn.
34119d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan            // selection += " and carrier_enabled = 1";
3412cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: selection=" + selection);
3413cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
34143c89e23cf33c3c7f795554b29cd926219f28fe34Sungmin Choi            // ORDER BY Telephony.Carriers._ID ("_id")
3415cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            Cursor cursor = mPhone.getContext().getContentResolver().query(
34163c89e23cf33c3c7f795554b29cd926219f28fe34Sungmin Choi                    Telephony.Carriers.CONTENT_URI, null, selection, null, Telephony.Carriers._ID);
3417cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3418cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cursor != null) {
3419cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (cursor.getCount() > 0) {
3420ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    mAllApnSettings = createApnList(cursor);
3421cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3422cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cursor.close();
3423cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3424c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3425c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
342676f43316a5a6082d601bffd4b6898d0bd81e11fcram        addEmergencyApnSetting();
342776f43316a5a6082d601bffd4b6898d0bd81e11fcram
342829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        dedupeApnSettings();
342929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
3430ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings.isEmpty()) {
3431cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: No APN found for carrier: " + operator);
3432cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPreferredApn = null;
3433ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // TODO: What is the right behavior?
3434cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            //notifyNoData(DataConnection.FailCause.MISSING_UNKNOWN_APN);
3435c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
3436cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPreferredApn = getPreferredApn();
3437cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator)) {
3438cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn = null;
3439cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                setPreferredApn(-1);
3440cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3441cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: mPreferredApn=" + mPreferredApn);
3442c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3443ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("createAllApnList: X mAllApnSettings=" + mAllApnSettings);
34449d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan
34459d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        setDataProfilesAsNeeded();
3446c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3447c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
344829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    private void dedupeApnSettings() {
344929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        ArrayList<ApnSetting> resultApns = new ArrayList<ApnSetting>();
345029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
345129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        // coalesce APNs if they are similar enough to prevent
345229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        // us from bringing up two data calls with the same interface
345329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        int i = 0;
345429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        while (i < mAllApnSettings.size() - 1) {
345529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            ApnSetting first = mAllApnSettings.get(i);
345629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            ApnSetting second = null;
345729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            int j = i + 1;
345829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            while (j < mAllApnSettings.size()) {
345929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                second = mAllApnSettings.get(j);
346029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                if (apnsSimilar(first, second)) {
346129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    ApnSetting newApn = mergeApns(first, second);
346229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    mAllApnSettings.set(i, newApn);
346329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    first = newApn;
346429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    mAllApnSettings.remove(j);
346529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                } else {
346629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    j++;
346729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                }
346829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            }
346929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            i++;
347029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        }
347129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    }
347229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
3473d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe    //check whether the types of two APN same (even only one type of each APN is same)
3474d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe    private boolean apnTypeSameAny(ApnSetting first, ApnSetting second) {
3475d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe        if(VDBG) {
3476d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            StringBuilder apnType1 = new StringBuilder(first.apn + ": ");
3477d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            for(int index1 = 0; index1 < first.types.length; index1++) {
3478d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                apnType1.append(first.types[index1]);
3479d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                apnType1.append(",");
3480d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            }
3481d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe
3482d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            StringBuilder apnType2 = new StringBuilder(second.apn + ": ");
3483d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            for(int index1 = 0; index1 < second.types.length; index1++) {
3484d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                apnType2.append(second.types[index1]);
3485d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                apnType2.append(",");
3486d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            }
3487d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            log("APN1: is " + apnType1);
3488d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            log("APN2: is " + apnType2);
3489d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe        }
3490d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe
3491d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe        for(int index1 = 0; index1 < first.types.length; index1++) {
3492d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            for(int index2 = 0; index2 < second.types.length; index2++) {
3493d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                if(first.types[index1].equals(PhoneConstants.APN_TYPE_ALL) ||
3494d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                        second.types[index2].equals(PhoneConstants.APN_TYPE_ALL) ||
3495d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                        first.types[index1].equals(second.types[index2])) {
3496d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                    if(VDBG)log("apnTypeSameAny: return true");
3497d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                    return true;
3498d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                }
3499d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            }
3500d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe        }
3501d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe
3502d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe        if(VDBG)log("apnTypeSameAny: return false");
3503d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe        return false;
3504d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe    }
3505d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe
350629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    // Check if neither mention DUN and are substantially similar
350729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    private boolean apnsSimilar(ApnSetting first, ApnSetting second) {
3508055adfbf731fb951f34b62ccca3c39800626e0bdpkanwar        return (!first.canHandleType(PhoneConstants.APN_TYPE_DUN)
3509055adfbf731fb951f34b62ccca3c39800626e0bdpkanwar                && !second.canHandleType(PhoneConstants.APN_TYPE_DUN)
3510055adfbf731fb951f34b62ccca3c39800626e0bdpkanwar                && Objects.equals(first.apn, second.apn)
3511055adfbf731fb951f34b62ccca3c39800626e0bdpkanwar                && !apnTypeSameAny(first, second)
3512055adfbf731fb951f34b62ccca3c39800626e0bdpkanwar                && xorEquals(first.proxy, second.proxy)
3513055adfbf731fb951f34b62ccca3c39800626e0bdpkanwar                && xorEquals(first.port, second.port)
3514055adfbf731fb951f34b62ccca3c39800626e0bdpkanwar                && xorEquals(first.protocol, second.protocol)
3515055adfbf731fb951f34b62ccca3c39800626e0bdpkanwar                && xorEquals(first.roamingProtocol, second.roamingProtocol)
3516055adfbf731fb951f34b62ccca3c39800626e0bdpkanwar                && first.carrierEnabled == second.carrierEnabled
3517055adfbf731fb951f34b62ccca3c39800626e0bdpkanwar                && first.bearerBitmask == second.bearerBitmask
3518055adfbf731fb951f34b62ccca3c39800626e0bdpkanwar                && first.profileId == second.profileId
3519055adfbf731fb951f34b62ccca3c39800626e0bdpkanwar                && Objects.equals(first.mvnoType, second.mvnoType)
3520055adfbf731fb951f34b62ccca3c39800626e0bdpkanwar                && Objects.equals(first.mvnoMatchData, second.mvnoMatchData)
3521055adfbf731fb951f34b62ccca3c39800626e0bdpkanwar                && xorEquals(first.mmsc, second.mmsc)
3522055adfbf731fb951f34b62ccca3c39800626e0bdpkanwar                && xorEquals(first.mmsProxy, second.mmsProxy)
3523055adfbf731fb951f34b62ccca3c39800626e0bdpkanwar                && xorEquals(first.mmsPort, second.mmsPort));
352429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    }
352529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
352629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    // equal or one is not specified
352729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    private boolean xorEquals(String first, String second) {
352829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        return (Objects.equals(first, second) ||
352929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                TextUtils.isEmpty(first) ||
353029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                TextUtils.isEmpty(second));
353129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    }
353229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
353329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    private ApnSetting mergeApns(ApnSetting dest, ApnSetting src) {
3534bca51fc3a191d3ca30df627b75374db0941571c5Sungmin Choi        int id = dest.id;
353529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        ArrayList<String> resultTypes = new ArrayList<String>();
353629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        resultTypes.addAll(Arrays.asList(dest.types));
353729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        for (String srcType : src.types) {
353829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            if (resultTypes.contains(srcType) == false) resultTypes.add(srcType);
3539bca51fc3a191d3ca30df627b75374db0941571c5Sungmin Choi            if (srcType.equals(PhoneConstants.APN_TYPE_DEFAULT)) id = src.id;
354029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        }
354129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        String mmsc = (TextUtils.isEmpty(dest.mmsc) ? src.mmsc : dest.mmsc);
354229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        String mmsProxy = (TextUtils.isEmpty(dest.mmsProxy) ? src.mmsProxy : dest.mmsProxy);
354329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        String mmsPort = (TextUtils.isEmpty(dest.mmsPort) ? src.mmsPort : dest.mmsPort);
354461cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String proxy = (TextUtils.isEmpty(dest.proxy) ? src.proxy : dest.proxy);
354561cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String port = (TextUtils.isEmpty(dest.port) ? src.port : dest.port);
354661cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String protocol = src.protocol.equals("IPV4V6") ? src.protocol : dest.protocol;
354761cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String roamingProtocol = src.roamingProtocol.equals("IPV4V6") ? src.roamingProtocol :
354861cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                dest.roamingProtocol;
3549aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan        int bearerBitmask = (dest.bearerBitmask == 0 || src.bearerBitmask == 0) ?
3550aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                0 : (dest.bearerBitmask | src.bearerBitmask);
355129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
3552bca51fc3a191d3ca30df627b75374db0941571c5Sungmin Choi        return new ApnSetting(id, dest.numeric, dest.carrier, dest.apn,
355361cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                proxy, port, mmsc, mmsProxy, mmsPort, dest.user, dest.password,
355461cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                dest.authType, resultTypes.toArray(new String[0]), protocol,
3555aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                roamingProtocol, dest.carrierEnabled, 0, bearerBitmask, dest.profileId,
355629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                (dest.modemCognitive || src.modemCognitive), dest.maxConns, dest.waitTime,
355729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                dest.maxConnsTime, dest.mtu, dest.mvnoType, dest.mvnoMatchData);
355829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    }
355929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
3560ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /** Return the DC AsyncChannel for the new data connection */
3561454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel createDataConnection() {
3562cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createDataConnection E");
3563cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3564cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int id = mUniqueIdGenerator.getAndIncrement();
3565ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        DataConnection conn = DataConnection.makeDataConnection(mPhone, id,
3566ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                                this, mDcTesterFailBringUpAll, mDcc);
3567cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mDataConnections.put(id, conn);
3568454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac = new DcAsyncChannel(conn, LOG_TAG);
3569cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int status = dcac.fullyConnectSync(mPhone.getContext(), this, conn.getHandler());
3570cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (status == AsyncChannel.STATUS_SUCCESSFUL) {
3571ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            mDataConnectionAcHashMap.put(dcac.getDataConnectionIdSync(), dcac);
3572c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
3573ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            loge("createDataConnection: Could not connect to dcac=" + dcac + " status=" + status);
3574c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3575cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3576cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createDataConnection() X id=" + id + " dc=" + conn);
3577ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        return dcac;
3578c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3579c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3580cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void destroyDataConnections() {
3581cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(mDataConnections != null) {
3582cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("destroyDataConnections: clear mDataConnectionList");
3583cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mDataConnections.clear();
3584cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
3585cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("destroyDataConnections: mDataConnecitonList is empty, ignore");
3586c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3587c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3588c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3589c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
3590cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Build a list of APNs to be used to create PDP's.
3591c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
3592cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param requestedApnType
3593cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return waitingApns list to be used to create PDP
3594cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *          error when waitingApns.isEmpty()
3595c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
3596203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    private ArrayList<ApnSetting> buildWaitingApns(String requestedApnType, int radioTech) {
3597cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("buildWaitingApns: E requestedApnType=" + requestedApnType);
3598cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ArrayList<ApnSetting> apnList = new ArrayList<ApnSetting>();
3599cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3600cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (requestedApnType.equals(PhoneConstants.APN_TYPE_DUN)) {
3601cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ApnSetting dun = fetchDunApn();
3602cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dun != null) {
3603cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnList.add(dun);
3604cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: X added APN_TYPE_DUN apnList=" + apnList);
3605cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return apnList;
3606c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3607c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3608c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3609cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
3610cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String operator = (r != null) ? r.getOperatorNumeric() : "";
3611c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3612cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // This is a workaround for a bug (7305641) where we don't failover to other
3613cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // suitable APNs if our preferred APN fails.  On prepaid ATT sims we need to
3614cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // failover to a provisioning APN, but once we've used their default data
3615cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // connection we are locked to it for life.  This change allows ATT devices
3616cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // to say they don't want to use preferred at all.
3617cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean usePreferred = true;
3618cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        try {
3619cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            usePreferred = ! mPhone.getContext().getResources().getBoolean(com.android.
3620cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    internal.R.bool.config_dontPreferApn);
3621cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } catch (Resources.NotFoundException e) {
3622cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("buildWaitingApns: usePreferred NotFoundException set to true");
3623cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            usePreferred = true;
3624cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3625bf660a4647db8151609cdfa0ecc4c96e1518947fSungmin Choi        if (usePreferred) {
3626bf660a4647db8151609cdfa0ecc4c96e1518947fSungmin Choi            mPreferredApn = getPreferredApn();
3627bf660a4647db8151609cdfa0ecc4c96e1518947fSungmin Choi        }
3628cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
3629cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("buildWaitingApns: usePreferred=" + usePreferred
363022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    + " canSetPreferApn=" + mCanSetPreferApn
3631cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " mPreferredApn=" + mPreferredApn
3632cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " operator=" + operator + " radioTech=" + radioTech
3633cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " IccRecords r=" + r);
3634cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3635c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
363622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (usePreferred && mCanSetPreferApn && mPreferredApn != null &&
3637cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn.canHandleType(requestedApnType)) {
3638cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
3639cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("buildWaitingApns: Preferred APN:" + operator + ":"
3640cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        + mPreferredApn.numeric + ":" + mPreferredApn);
3641cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3642cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPreferredApn.numeric.equals(operator)) {
3643aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                if (ServiceState.bitmaskHasTech(mPreferredApn.bearerBitmask, radioTech)) {
3644cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnList.add(mPreferredApn);
3645cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
3646cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return apnList;
3647cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
3648cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("buildWaitingApns: no preferred APN");
3649cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    setPreferredApn(-1);
3650cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mPreferredApn = null;
3651c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
3652cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
3653cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: no preferred APN");
3654cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                setPreferredApn(-1);
3655cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn = null;
3656c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3657c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3658ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings != null) {
3659ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (DBG) log("buildWaitingApns: mAllApnSettings=" + mAllApnSettings);
3660ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for (ApnSetting apn : mAllApnSettings) {
3661cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn.canHandleType(requestedApnType)) {
3662aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                    if (ServiceState.bitmaskHasTech(apn.bearerBitmask, radioTech)) {
36639232dafa7ea833fc0b3a6024d6c7e23fc8e961eaRobert Greenwalt                        if (DBG) log("buildWaitingApns: adding apn=" + apn);
3664cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnList.add(apn);
3665c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else {
3666cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (DBG) {
3667aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                            log("buildWaitingApns: bearerBitmask:" + apn.bearerBitmask + " does " +
3668aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                                    "not include radioTech:" + radioTech);
3669cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
3670c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
36719232dafa7ea833fc0b3a6024d6c7e23fc8e961eaRobert Greenwalt                } else if (DBG) {
367227b650c406018355a88a41528db7859e232728a0Jack Yu                    log("buildWaitingApns: couldn't handle requested ApnType="
3673cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            + requestedApnType);
3674c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
3675c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3676cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
36774bd0ae43eb0cb9969dee4f30cddc18a71da68190Jack Yu            loge("mAllApnSettings is null!");
3678c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
36790e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        if (DBG) log("buildWaitingApns: " + apnList.size() + " APNs in the list: " + apnList);
3680cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return apnList;
3681c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3682c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3683cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private String apnListToString (ArrayList<ApnSetting> apns) {
3684cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        StringBuilder result = new StringBuilder();
3685cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (int i = 0, size = apns.size(); i < size; i++) {
3686cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result.append('[')
3687cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                  .append(apns.get(i).toString())
3688cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                  .append(']');
3689c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3690cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result.toString();
3691c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3692c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3693cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void setPreferredApn(int pos) {
369422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (!mCanSetPreferApn) {
3695cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("setPreferredApn: X !canSEtPreferApn");
3696cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
3697cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3698cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
36996bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        String subId = Long.toString(mPhone.getSubId());
37006bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        Uri uri = Uri.withAppendedPath(PREFERAPN_NO_UPDATE_URI_USING_SUBID, subId);
3701cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("setPreferredApn: delete");
3702cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ContentResolver resolver = mPhone.getContext().getContentResolver();
37036bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        resolver.delete(uri, null, null);
3704cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3705cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (pos >= 0) {
3706cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("setPreferredApn: insert");
3707cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ContentValues values = new ContentValues();
3708cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            values.put(APN_ID, pos);
37096bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville            resolver.insert(uri, values);
3710cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3711cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
3712cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3713cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ApnSetting getPreferredApn() {
37144bd0ae43eb0cb9969dee4f30cddc18a71da68190Jack Yu        if (mAllApnSettings == null || mAllApnSettings.isEmpty()) {
37154bd0ae43eb0cb9969dee4f30cddc18a71da68190Jack Yu            log("getPreferredApn: mAllApnSettings is " + ((mAllApnSettings == null)?"null":"empty"));
3716cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return null;
3717cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3718cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
37196bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        String subId = Long.toString(mPhone.getSubId());
37206bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        Uri uri = Uri.withAppendedPath(PREFERAPN_NO_UPDATE_URI_USING_SUBID, subId);
3721cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Cursor cursor = mPhone.getContext().getContentResolver().query(
37226bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville                uri, new String[] { "_id", "name", "apn" },
3723cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
3724cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3725cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor != null) {
372622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCanSetPreferApn = true;
3727cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
372822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCanSetPreferApn = false;
3729cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3730cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("getPreferredApn: mRequestedApnType=" + mRequestedApnType + " cursor=" + cursor
3731cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                + " cursor.count=" + ((cursor != null) ? cursor.getCount() : 0));
3732cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
373322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mCanSetPreferApn && cursor.getCount() > 0) {
3734cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            int pos;
3735cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cursor.moveToFirst();
3736cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            pos = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID));
3737ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for(ApnSetting p : mAllApnSettings) {
3738cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("getPreferredApn: apnSetting=" + p);
3739cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (p.id == pos && p.canHandleType(mRequestedApnType)) {
3740cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("getPreferredApn: X found apnSetting" + p);
3741cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    cursor.close();
3742cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return p;
3743cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3744cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
3745cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3746cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3747cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor != null) {
3748cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cursor.close();
3749cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3750cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3751cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("getPreferredApn: X not found");
3752cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
3753cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
3754cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3755cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
3756cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void handleMessage (Message msg) {
37571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) log("handleMessage msg=" + msg);
3758cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3759cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        switch (msg.what) {
3760cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_RECORDS_LOADED:
37611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // If onRecordsLoadedOrSubIdChanged() is not called here, it should be called on
37621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // onSubscriptionsChanged() when a valid subId is available.
37631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                int subId = mPhone.getSubId();
37641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (SubscriptionManager.isValidSubscriptionId(subId)) {
37651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onRecordsLoadedOrSubIdChanged();
37661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
37671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("Ignoring EVENT_RECORDS_LOADED as subId is not valid: " + subId);
37681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
3769cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3770cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3771cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_CONNECTION_DETACHED:
3772cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onDataConnectionDetached();
3773cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3774cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3775cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_CONNECTION_ATTACHED:
3776bda761320929f714951c328bfec6a51a1978db97Wink Saville                onDataConnectionAttached();
3777cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3778cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3779cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DO_RECOVERY:
3780cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                doRecovery();
3781cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3782cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3783cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_APN_CHANGED:
3784cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onApnChanged();
3785cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3786cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3787cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_PS_RESTRICT_ENABLED:
3788cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                /**
3789cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * We don't need to explicitly to tear down the PDP context
3790cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * when PS restricted is enabled. The base band will deactive
3791cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * PDP context and notify us with PDP_CONTEXT_CHANGED.
3792cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * But we should stop the network polling and prevent reset PDP.
3793cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 */
3794cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
3795cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                stopNetStatPoll();
3796cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                stopDataStallAlarm();
3797cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsPsRestricted = true;
3798cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
3799cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3800cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_PS_RESTRICT_DISABLED:
3801cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                /**
3802cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * When PS restrict is removed, we need setup PDP connection if
3803cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * PDP connection is down.
3804cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 */
3805cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_PS_RESTRICT_DISABLED " + mIsPsRestricted);
3806cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsPsRestricted  = false;
3807cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (isConnected()) {
3808cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    startNetStatPoll();
3809cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
3810cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
3811cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // TODO: Should all PDN states be checked to fail?
3812ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    if (mState == DctConstants.State.FAILED) {
3813cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        cleanUpAllConnections(false, Phone.REASON_PS_RESTRICT_ENABLED);
3814cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mReregisterOnReconnectFailure = false;
3815cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
3816af5593594070f825032be46dced573cd195956e1Robert Greenwalt                    ApnContext apnContext = mApnContextsById.get(DctConstants.APN_DEFAULT_ID);
38173fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (apnContext != null) {
38183fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        apnContext.setReason(Phone.REASON_PS_RESTRICT_ENABLED);
38193fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        trySetupData(apnContext);
38203fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    } else {
38213fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        loge("**** Default ApnContext not found ****");
38223fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        if (Build.IS_DEBUGGABLE) {
38233fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                            throw new RuntimeException("Default ApnContext not found");
38243fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        }
38253fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    }
3826cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3827cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
3828ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3829cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_TRY_SETUP_DATA:
3830cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (msg.obj instanceof ApnContext) {
3831cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    onTrySetupData((ApnContext)msg.obj);
3832cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else if (msg.obj instanceof String) {
3833cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    onTrySetupData((String)msg.obj);
3834cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
3835cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    loge("EVENT_TRY_SETUP request w/o apnContext or String");
3836cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3837cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
3838cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3839cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_CLEAN_UP_CONNECTION:
3840cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                boolean tearDown = (msg.arg1 == 0) ? false : true;
3841cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_CLEAN_UP_CONNECTION tearDown=" + tearDown);
3842cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (msg.obj instanceof ApnContext) {
3843cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    cleanUpConnection(tearDown, (ApnContext)msg.obj);
3844cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
38451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onCleanUpConnection(tearDown, msg.arg2, (String) msg.obj);
3846cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3847cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
38481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE: {
38491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
3850a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                onSetInternalDataEnabled(enabled, (Message) msg.obj);
3851a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
38521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
3853a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS:
38541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if ((msg.obj != null) && (msg.obj instanceof String == false)) {
38551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    msg.obj = null;
3856a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
38571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onCleanUpAllConnections((String) msg.obj);
3858a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
3859ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3860220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville            case DctConstants.EVENT_DATA_RAT_CHANGED:
3861220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville                //May new Network allow setupData, so try it here
3862c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                setupDataOnConnectableApns(Phone.REASON_NW_TYPE_CHANGED,
3863c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                        RetryFailures.ONLY_ON_CHANGE);
3864220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville                break;
3865220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville
38662b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            case DctConstants.CMD_CLEAR_PROVISIONING_SPINNER:
38672b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                // Check message sender intended to clear the current spinner.
38682b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                if (mProvisioningSpinner == msg.obj) {
38692b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner.dismiss();
38702b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner = null;
38712b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                }
38722b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                break;
38731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
38741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("DISCONNECTED_CONNECTED: msg=" + msg);
38751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DcAsyncChannel dcac = (DcAsyncChannel) msg.obj;
38761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mDataConnectionAcHashMap.remove(dcac.getDataConnectionIdSync());
38771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                dcac.disconnected();
38781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
38801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ENABLE_NEW_APN:
38811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onEnableApn(msg.arg1, msg.arg2);
38821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
38841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_STALL_ALARM:
38851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDataStallAlarm(msg.arg1);
38861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
38881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ROAMING_OFF:
38895b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu                onDataRoamingOff();
38901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
38921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ROAMING_ON:
38935b83d07ba19e20cf2811824cc2bed96953d1134dJack Yu                onDataRoamingOnOrSettingsChanged();
38941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3896f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            case DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE:
3897f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                onDeviceProvisionedChange();
3898f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                break;
3899f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
3900a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            case DctConstants.EVENT_REDIRECTION_DETECTED:
39014c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                String url = (String) msg.obj;
390268f4f4a0bc8d4060b5775e7a24a97ea5b485989efionaxu                log("dataConnectionTracker.handleMessage: EVENT_REDIRECTION_DETECTED=" + url);
39034c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu                onDataConnectionRedirected(url);
3904a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
39051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RADIO_AVAILABLE:
39061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onRadioAvailable();
39071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
39091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
39101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onRadioOffOrNotAvailable();
39111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
39131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_SETUP_COMPLETE:
39141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDataSetupComplete((AsyncResult) msg.obj);
39151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
39171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_SETUP_COMPLETE_ERROR:
39181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDataSetupCompleteError((AsyncResult) msg.obj);
39191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
3920a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
39211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DISCONNECT_DONE:
39221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("DataConnectionTracker.handleMessage: EVENT_DISCONNECT_DONE msg=" + msg);
39231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDisconnectDone((AsyncResult) msg.obj);
39241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
39261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DISCONNECT_DC_RETRYING:
39271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("DataConnectionTracker.handleMessage: EVENT_DISCONNECT_DC_RETRYING msg=" + msg);
39281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDisconnectDcRetrying((AsyncResult) msg.obj);
39291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
39311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_VOICE_CALL_STARTED:
39321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onVoiceCallStarted();
39331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
39351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_VOICE_CALL_ENDED:
39361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onVoiceCallEnded();
39371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
39391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RESET_DONE: {
39401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("EVENT_RESET_DONE");
39411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onResetDone((AsyncResult) msg.obj);
39421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_USER_DATA_ENABLE: {
39451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
39461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_SET_USER_DATA_ENABLE enabled=" + enabled);
39471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onSetUserDataEnabled(enabled);
39481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // TODO - remove
39511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_DEPENDENCY_MET: {
39521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                boolean met = (msg.arg1 == DctConstants.ENABLED) ? true : false;
39531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_SET_DEPENDENCY_MET met=" + met);
39541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Bundle bundle = msg.getData();
39551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (bundle != null) {
39561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    String apnType = (String)bundle.get(DctConstants.APN_TYPE_KEY);
39571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (apnType != null) {
39581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onSetDependencyMet(apnType, met);
39591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
39601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
39611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_POLICY_DATA_ENABLE: {
39641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
39651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onSetPolicyDataEnabled(enabled);
39661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: {
39691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                sEnableFailFastRefCounter += (msg.arg1 == DctConstants.ENABLED) ? 1 : -1;
39701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
39711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: "
39721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + " sEnableFailFastRefCounter=" + sEnableFailFastRefCounter);
39731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
39741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (sEnableFailFastRefCounter < 0) {
39751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    final String s = "CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: "
39761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + "sEnableFailFastRefCounter:" + sEnableFailFastRefCounter + " < 0";
39771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge(s);
39781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    sEnableFailFastRefCounter = 0;
39791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
39801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = sEnableFailFastRefCounter > 0;
39811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
39821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: enabled=" + enabled
39831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + " sEnableFailFastRefCounter=" + sEnableFailFastRefCounter);
39841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
39851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (mFailFast != enabled) {
39861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mFailFast = enabled;
39870e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
39881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mDataStallDetectionEnabled = !enabled;
39891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mDataStallDetectionEnabled
39901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            && (getOverallState() == DctConstants.State.CONNECTED)
39911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            && (!mInVoiceCall ||
39921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    mPhone.getServiceStateTracker()
39931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                        .isConcurrentVoiceAndDataAllowed())) {
39941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: start data stall");
39951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        stopDataStallAlarm();
39961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
39971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
39981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: stop data stall");
39991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        stopDataStallAlarm();
40001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
40011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
40022b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen
40031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
40041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
40051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_ENABLE_MOBILE_PROVISIONING: {
40061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Bundle bundle = msg.getData();
40071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (bundle != null) {
40081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    try {
40091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mProvisioningUrl = (String)bundle.get(DctConstants.PROVISIONING_URL_KEY);
40101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } catch(ClassCastException e) {
40111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioning url not a string" + e);
40121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mProvisioningUrl = null;
40131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
40141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
40151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (TextUtils.isEmpty(mProvisioningUrl)) {
40161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioning url is empty, ignoring");
40171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mIsProvisioning = false;
40181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mProvisioningUrl = null;
40191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
40201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioningUrl=" + mProvisioningUrl);
40211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mIsProvisioning = true;
40221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    startProvisioningApnAlarm();
40231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
40241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
40251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
40261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_PROVISIONING_APN_ALARM: {
40271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("EVENT_PROVISIONING_APN_ALARM");
4028af5593594070f825032be46dced573cd195956e1Robert Greenwalt                ApnContext apnCtx = mApnContextsById.get(DctConstants.APN_DEFAULT_ID);
40291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (apnCtx.isProvisioningApn() && apnCtx.isConnectedOrConnecting()) {
40301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mProvisioningApnAlarmTag == msg.arg1) {
40311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) log("EVENT_PROVISIONING_APN_ALARM: Disconnecting");
40321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mIsProvisioning = false;
40331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mProvisioningUrl = null;
40341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        stopProvisioningApnAlarm();
40351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        sendCleanUpConnection(true, apnCtx);
40361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
40371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) {
40381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            log("EVENT_PROVISIONING_APN_ALARM: ignore stale tag,"
40391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    + " mProvisioningApnAlarmTag:" + mProvisioningApnAlarmTag
40401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    + " != arg1:" + msg.arg1);
40411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        }
40421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
40431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
40441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (DBG) log("EVENT_PROVISIONING_APN_ALARM: Not connected ignore");
40451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
40461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
40471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
40481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_IS_PROVISIONING_APN: {
40491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_IS_PROVISIONING_APN");
40501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                boolean isProvApn;
40511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                try {
40521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    String apnType = null;
40531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    Bundle bundle = msg.getData();
40541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (bundle != null) {
40551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        apnType = (String)bundle.get(DctConstants.APN_TYPE_KEY);
40561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
40571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (TextUtils.isEmpty(apnType)) {
40581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        loge("CMD_IS_PROVISIONING_APN: apnType is empty");
40591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        isProvApn = false;
40601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
40611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        isProvApn = isProvisioningApn(apnType);
40621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
40631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } catch (ClassCastException e) {
40641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge("CMD_IS_PROVISIONING_APN: NO provisioning url ignoring");
40651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    isProvApn = false;
40661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
40671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_IS_PROVISIONING_APN: ret=" + isProvApn);
40681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mReplyAc.replyToMessage(msg, DctConstants.CMD_IS_PROVISIONING_APN,
40691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        isProvApn ? DctConstants.ENABLED : DctConstants.DISABLED);
40701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
40711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
40721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ICC_CHANGED: {
40731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onUpdateIcc();
40741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
40751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
40761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RESTART_RADIO: {
40771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartRadio();
40781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
40791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
40801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_NET_STAT_POLL: {
40811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (msg.arg1 == DctConstants.ENABLED) {
40821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    handleStartNetStatPoll((DctConstants.Activity)msg.obj);
40831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else if (msg.arg1 == DctConstants.DISABLED) {
40841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    handleStopNetStatPoll((DctConstants.Activity)msg.obj);
40851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
40861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
40871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
40881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_STATE_CHANGED: {
40891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // no longer do anything, but still registered - clean up log
40901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // TODO - why are we still registering?
40911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
40921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
40932e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            case DctConstants.EVENT_PCO_DATA_RECEIVED: {
40942e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt                handlePcoData((AsyncResult)msg.obj);
40952e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt                break;
40962e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            }
4097a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            case DctConstants.EVENT_SET_CARRIER_DATA_ENABLED:
40986a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu                onSetCarrierDataEnabled((AsyncResult) msg.obj);
4099a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                break;
4100cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            default:
41011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Rlog.e("DcTracker", "Unhandled event=" + msg);
4102cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
41031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4104cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
4105cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
4106cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
41071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int getApnProfileID(String apnType) {
4108cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IMS)) {
4109cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_IMS;
4110cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_FOTA)) {
4111cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_FOTA;
4112cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_CBS)) {
4113cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_CBS;
41141b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IA)) {
41151b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            return RILConstants.DATA_PROFILE_DEFAULT; // DEFAULT for now
411645df26444864daad60afdd4d121ab4043da3834bSungmin Choi        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_DUN)) {
411745df26444864daad60afdd4d121ab4043da3834bSungmin Choi            return RILConstants.DATA_PROFILE_TETHERED;
4118cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
4119cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_DEFAULT;
4120cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
4121cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
4122cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4123cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private int getCellLocationId() {
4124cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int cid = -1;
4125cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        CellLocation loc = mPhone.getCellLocation();
4126cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4127cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (loc != null) {
4128cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (loc instanceof GsmCellLocation) {
4129cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cid = ((GsmCellLocation)loc).getCid();
4130cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else if (loc instanceof CdmaCellLocation) {
4131cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cid = ((CdmaCellLocation)loc).getBaseStationId();
4132cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
4133cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
4134cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return cid;
4135cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
4136cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4137a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private IccRecords getUiccRecords(int appFamily) {
4138a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return mUiccController.getIccRecords(mPhone.getPhoneId(), appFamily);
4139a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4140a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4141a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
41421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onUpdateIcc() {
4143cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mUiccController == null ) {
4144cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            return;
4145cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
4146cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4147a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        IccRecords newIccRecords = getUiccRecords(UiccController.APP_FAM_3GPP);
4148cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4149cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
4150cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (r != newIccRecords) {
4151cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (r != null) {
4152cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("Removing stale icc objects.");
4153cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                r.unregisterForRecordsLoaded(this);
4154cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIccRecords.set(null);
41559aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan            }
4156cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (newIccRecords != null) {
41571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (SubscriptionManager.isValidSubscriptionId(mPhone.getSubId())) {
4158aa863054476b152fe9323defd197fa946a47033fSungmin Choi                    log("New records found.");
4159aa863054476b152fe9323defd197fa946a47033fSungmin Choi                    mIccRecords.set(newIccRecords);
4160aa863054476b152fe9323defd197fa946a47033fSungmin Choi                    newIccRecords.registerForRecordsLoaded(
4161aa863054476b152fe9323defd197fa946a47033fSungmin Choi                            this, DctConstants.EVENT_RECORDS_LOADED, null);
4162aa863054476b152fe9323defd197fa946a47033fSungmin Choi                }
41630469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal            } else {
41640469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal                onSimNotReady();
41659aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan            }
41669aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan        }
4167cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
4168cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4169a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void update() {
4170a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("update sub = " + mPhone.getSubId());
4171bda761320929f714951c328bfec6a51a1978db97Wink Saville        log("update(): Active DDS, register for all events now!");
4172bda761320929f714951c328bfec6a51a1978db97Wink Saville        onUpdateIcc();
4173a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4174a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        mDataEnabledSettings.setUserDataEnabled(getDataEnabled());
41750979b71e48405cab10bdf1d1b4170cfce72838a7Jack Yu        mAutoAttachOnCreation.set(false);
4176bda761320929f714951c328bfec6a51a1978db97Wink Saville
41771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ((GsmCdmaPhone)mPhone).updateCurrentCarrierInProvider();
4178a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4179a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4180a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void cleanUpAllConnections(String cause) {
4181a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cleanUpAllConnections(cause, null);
4182a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4183a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4184a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void updateRecords() {
4185bda761320929f714951c328bfec6a51a1978db97Wink Saville        onUpdateIcc();
4186a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4187a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4188a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void cleanUpAllConnections(String cause, Message disconnectAllCompleteMsg) {
4189a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("cleanUpAllConnections");
4190a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (disconnectAllCompleteMsg != null) {
4191a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mDisconnectAllCompleteMsgList.add(disconnectAllCompleteMsg);
4192a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4193a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4194a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Message msg = obtainMessage(DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS);
4195a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        msg.obj = cause;
4196a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sendMessage(msg);
4197a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4198a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
41991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyDataDisconnectComplete() {
4200a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("notifyDataDisconnectComplete");
4201a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        for (Message m: mDisconnectAllCompleteMsgList) {
4202a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            m.sendToTarget();
4203a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4204a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mDisconnectAllCompleteMsgList.clear();
4205a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4206a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4207a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
42081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyAllDataDisconnected() {
4209a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sEnableFailFastRefCounter = 0;
4210a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mFailFast = false;
4211a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.notifyRegistrants();
4212a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4213a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4214a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void registerForAllDataDisconnected(Handler h, int what, Object obj) {
4215a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.addUnique(h, what, obj);
4216a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4217a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (isDisconnected()) {
4218a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("notify All Data Disconnected");
4219a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
4220a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4221a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4222a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4223a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void unregisterForAllDataDisconnected(Handler h) {
4224a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.remove(h);
4225a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4226a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4227a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    public void registerForDataEnabledChanged(Handler h, int what, Object obj) {
4228a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        mDataEnabledSettings.registerForDataEnabledChanged(h, what, obj);
4229a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    }
4230a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
4231a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    public void unregisterForDataEnabledChanged(Handler h) {
4232a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        mDataEnabledSettings.unregisterForDataEnabledChanged(h);
4233a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu    }
4234a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
42351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetInternalDataEnabled(boolean enabled, Message onCompleteMsg) {
4236a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        synchronized (mDataEnabledSettings) {
4237a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            if (DBG) log("onSetInternalDataEnabled: enabled=" + enabled);
4238a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            boolean sendOnComplete = true;
4239a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4240a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            mDataEnabledSettings.setInternalDataEnabled(enabled);
4241a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (enabled) {
4242a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("onSetInternalDataEnabled: changed to enabled, try to setup data call");
4243a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                onTrySetupData(Phone.REASON_DATA_ENABLED);
4244a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
4245a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                sendOnComplete = false;
4246a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("onSetInternalDataEnabled: changed to disabled, cleanUpAllConnections");
42474fdc57b9bf223c908474c4545cc6f63456117a3bSanket Padawe                cleanUpAllConnections(Phone.REASON_DATA_DISABLED, onCompleteMsg);
4248a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
4249a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4250a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu            if (sendOnComplete) {
4251a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                if (onCompleteMsg != null) {
4252a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                    onCompleteMsg.sendToTarget();
4253a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu                }
4254a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
4255a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4256a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4257a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4258a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean setInternalDataEnabled(boolean enable) {
4259a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return setInternalDataEnabled(enable, null);
4260a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4261a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4262a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean setInternalDataEnabled(boolean enable, Message onCompleteMsg) {
42636bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        if (DBG) log("setInternalDataEnabled(" + enable + ")");
4264a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4265a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Message msg = obtainMessage(DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE, onCompleteMsg);
4266a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        msg.arg1 = (enable ? DctConstants.ENABLED : DctConstants.DISABLED);
4267a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sendMessage(msg);
4268a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return true;
4269a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4270a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
42711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void log(String s) {
4272a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Rlog.d(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s);
4273cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
4274cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
42751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void loge(String s) {
4276a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Rlog.e(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s);
4277cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
4278cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4279c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
42801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println("DcTracker:");
42811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" RADIO_TESTS=" + RADIO_TESTS);
4282a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        pw.println(" isInternalDataEnabled=" + mDataEnabledSettings.isInternalDataEnabled());
4283a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        pw.println(" isUserDataEnabled=" + mDataEnabledSettings.isUserDataEnabled());
4284a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        pw.println(" isPolicyDataEnabled=" + mDataEnabledSettings.isPolicyDataEnabled());
42851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
42861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mRequestedApnType=" + mRequestedApnType);
42871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mPhone=" + mPhone.getPhoneName());
42881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mActivity=" + mActivity);
42891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mState=" + mState);
42901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mTxPkts=" + mTxPkts);
42911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mRxPkts=" + mRxPkts);
42921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mNetStatPollPeriod=" + mNetStatPollPeriod);
42931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mNetStatPollEnabled=" + mNetStatPollEnabled);
42941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mDataStallTxRxSum=" + mDataStallTxRxSum);
42951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mDataStallAlarmTag=" + mDataStallAlarmTag);
4296a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu        pw.println(" mDataStallDetectionEnabled=" + mDataStallDetectionEnabled);
42971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mSentSinceLastRecv=" + mSentSinceLastRecv);
42981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mNoRecvPollCount=" + mNoRecvPollCount);
42991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mResolver=" + mResolver);
43001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsWifiConnected=" + mIsWifiConnected);
43011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mReconnectIntent=" + mReconnectIntent);
43021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mAutoAttachOnCreation=" + mAutoAttachOnCreation.get());
43031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsScreenOn=" + mIsScreenOn);
43041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mUniqueIdGenerator=" + mUniqueIdGenerator);
43051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
43061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
43071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        DcController dcc = mDcc;
43081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (dcc != null) {
43091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            dcc.dump(fd, pw, args);
43101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
43111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mDcc=null");
43121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
43131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
43141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        HashMap<Integer, DataConnection> dcs = mDataConnections;
43151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (dcs != null) {
43161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Set<Entry<Integer, DataConnection> > mDcSet = mDataConnections.entrySet();
43171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mDataConnections: count=" + mDcSet.size());
43181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (Entry<Integer, DataConnection> entry : mDcSet) {
43191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                pw.printf(" *** mDataConnection[%d] \n", entry.getKey());
43201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                entry.getValue().dump(fd, pw, args);
43211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
43221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
43231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println("mDataConnections=null");
43241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
43251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
43261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
43271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        HashMap<String, Integer> apnToDcId = mApnToDataConnectionId;
43281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (apnToDcId != null) {
43291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Set<Entry<String, Integer>> apnToDcIdSet = apnToDcId.entrySet();
43301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mApnToDataConnectonId size=" + apnToDcIdSet.size());
43311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (Entry<String, Integer> entry : apnToDcIdSet) {
43321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                pw.printf(" mApnToDataConnectonId[%s]=%d\n", entry.getKey(), entry.getValue());
43331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
43341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
43351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println("mApnToDataConnectionId=null");
43361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
43371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
43381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
43391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ConcurrentHashMap<String, ApnContext> apnCtxs = mApnContexts;
43401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (apnCtxs != null) {
43411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Set<Entry<String, ApnContext>> apnCtxsSet = apnCtxs.entrySet();
43421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mApnContexts size=" + apnCtxsSet.size());
43431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (Entry<String, ApnContext> entry : apnCtxsSet) {
43441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                entry.getValue().dump(fd, pw, args);
43451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
43461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" ***************************************");
43471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
43481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mApnContexts=null");
43491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
43501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
43511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ArrayList<ApnSetting> apnSettings = mAllApnSettings;
43521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (apnSettings != null) {
43531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mAllApnSettings size=" + apnSettings.size());
43541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (int i=0; i < apnSettings.size(); i++) {
43551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                pw.printf(" mAllApnSettings[%d]: %s\n", i, apnSettings.get(i));
43561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
43571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.flush();
43581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
43591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mAllApnSettings=null");
43601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
43611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mPreferredApn=" + mPreferredApn);
43621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsPsRestricted=" + mIsPsRestricted);
43631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsDisposed=" + mIsDisposed);
43641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIntentReceiver=" + mIntentReceiver);
4365cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mReregisterOnReconnectFailure=" + mReregisterOnReconnectFailure);
436622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" canSetPreferApn=" + mCanSetPreferApn);
4367cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mApnObserver=" + mApnObserver);
4368cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" getOverallState=" + getOverallState());
4369ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        pw.println(" mDataConnectionAsyncChannels=%s\n" + mDataConnectionAcHashMap);
4370187a39f896f88eb6c5e4306d9595546654825976Wink Saville        pw.println(" mAttached=" + mAttached.get());
43711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
4372c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
4373a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4374bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram    public String[] getPcscfAddress(String apnType) {
4375a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("getPcscfAddress()");
4376bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        ApnContext apnContext = null;
4377bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram
4378bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        if(apnType == null){
4379bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            log("apnType is null, return null");
4380bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            return null;
4381bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        }
4382a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4383bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_EMERGENCY)) {
4384af5593594070f825032be46dced573cd195956e1Robert Greenwalt            apnContext = mApnContextsById.get(DctConstants.APN_EMERGENCY_ID);
4385bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IMS)) {
4386af5593594070f825032be46dced573cd195956e1Robert Greenwalt            apnContext = mApnContextsById.get(DctConstants.APN_IMS_ID);
4387bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        } else {
4388bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            log("apnType is invalid, return null");
4389bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            return null;
4390bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        }
4391a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4392a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (apnContext == null) {
4393a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("apnContext is null, return null");
4394a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return null;
4395a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4396a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4397a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        DcAsyncChannel dcac = apnContext.getDcAc();
4398a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        String[] result = null;
4399a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4400a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (dcac != null) {
4401a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            result = dcac.getPcscfAddr();
4402a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4403a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            for (int i = 0; i < result.length; i++) {
4404a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("Pcscf[" + i + "]: " + result[i]);
4405a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
4406a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return result;
4407a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4408a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return null;
4409a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4410a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
441176f43316a5a6082d601bffd4b6898d0bd81e11fcram    /**
441276f43316a5a6082d601bffd4b6898d0bd81e11fcram     * Read APN configuration from Telephony.db for Emergency APN
441376f43316a5a6082d601bffd4b6898d0bd81e11fcram     * All opertors recognize the connection request for EPDN based on APN type
441476f43316a5a6082d601bffd4b6898d0bd81e11fcram     * PLMN name,APN name are not mandatory parameters
441576f43316a5a6082d601bffd4b6898d0bd81e11fcram     */
441676f43316a5a6082d601bffd4b6898d0bd81e11fcram    private void initEmergencyApnSetting() {
441776f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Operator Numeric is not available when sim records are not loaded.
441876f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Query Telephony.db with APN type as EPDN request does not
441976f43316a5a6082d601bffd4b6898d0bd81e11fcram        // require APN name, plmn and all operators support same APN config.
442076f43316a5a6082d601bffd4b6898d0bd81e11fcram        // DB will contain only one entry for Emergency APN
442176f43316a5a6082d601bffd4b6898d0bd81e11fcram        String selection = "type=\"emergency\"";
442276f43316a5a6082d601bffd4b6898d0bd81e11fcram        Cursor cursor = mPhone.getContext().getContentResolver().query(
442376f43316a5a6082d601bffd4b6898d0bd81e11fcram                Telephony.Carriers.CONTENT_URI, null, selection, null, null);
442476f43316a5a6082d601bffd4b6898d0bd81e11fcram
442576f43316a5a6082d601bffd4b6898d0bd81e11fcram        if (cursor != null) {
442676f43316a5a6082d601bffd4b6898d0bd81e11fcram            if (cursor.getCount() > 0) {
442776f43316a5a6082d601bffd4b6898d0bd81e11fcram                if (cursor.moveToFirst()) {
442876f43316a5a6082d601bffd4b6898d0bd81e11fcram                    mEmergencyApn = makeApnSetting(cursor);
442976f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
443076f43316a5a6082d601bffd4b6898d0bd81e11fcram            }
443176f43316a5a6082d601bffd4b6898d0bd81e11fcram            cursor.close();
443276f43316a5a6082d601bffd4b6898d0bd81e11fcram        }
443376f43316a5a6082d601bffd4b6898d0bd81e11fcram    }
443476f43316a5a6082d601bffd4b6898d0bd81e11fcram
443576f43316a5a6082d601bffd4b6898d0bd81e11fcram    /**
443676f43316a5a6082d601bffd4b6898d0bd81e11fcram     * Add the Emergency APN settings to APN settings list
443776f43316a5a6082d601bffd4b6898d0bd81e11fcram     */
443876f43316a5a6082d601bffd4b6898d0bd81e11fcram    private void addEmergencyApnSetting() {
443976f43316a5a6082d601bffd4b6898d0bd81e11fcram        if(mEmergencyApn != null) {
444076f43316a5a6082d601bffd4b6898d0bd81e11fcram            if(mAllApnSettings == null) {
444176f43316a5a6082d601bffd4b6898d0bd81e11fcram                mAllApnSettings = new ArrayList<ApnSetting>();
444276f43316a5a6082d601bffd4b6898d0bd81e11fcram            } else {
444376f43316a5a6082d601bffd4b6898d0bd81e11fcram                boolean hasEmergencyApn = false;
444476f43316a5a6082d601bffd4b6898d0bd81e11fcram                for (ApnSetting apn : mAllApnSettings) {
444576f43316a5a6082d601bffd4b6898d0bd81e11fcram                    if (ArrayUtils.contains(apn.types, PhoneConstants.APN_TYPE_EMERGENCY)) {
444676f43316a5a6082d601bffd4b6898d0bd81e11fcram                        hasEmergencyApn = true;
444776f43316a5a6082d601bffd4b6898d0bd81e11fcram                        break;
444876f43316a5a6082d601bffd4b6898d0bd81e11fcram                    }
444976f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
445076f43316a5a6082d601bffd4b6898d0bd81e11fcram
445176f43316a5a6082d601bffd4b6898d0bd81e11fcram                if(hasEmergencyApn == false) {
445276f43316a5a6082d601bffd4b6898d0bd81e11fcram                    mAllApnSettings.add(mEmergencyApn);
445376f43316a5a6082d601bffd4b6898d0bd81e11fcram                } else {
445476f43316a5a6082d601bffd4b6898d0bd81e11fcram                    log("addEmergencyApnSetting - E-APN setting is already present");
445576f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
445676f43316a5a6082d601bffd4b6898d0bd81e11fcram            }
445776f43316a5a6082d601bffd4b6898d0bd81e11fcram        }
445876f43316a5a6082d601bffd4b6898d0bd81e11fcram    }
44599a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
44609a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang    private void cleanUpConnectionsOnUpdatedApns(boolean tearDown) {
44619a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (DBG) log("cleanUpConnectionsOnUpdatedApns: tearDown=" + tearDown);
44629a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (mAllApnSettings.isEmpty()) {
44639a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            cleanUpAllConnections(tearDown, Phone.REASON_APN_CHANGED);
44649a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        } else {
44659a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            for (ApnContext apnContext : mApnContexts.values()) {
44669a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                if (VDBG) log("cleanUpConnectionsOnUpdatedApns for "+ apnContext);
44679a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
44689a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                boolean cleanUpApn = true;
44699a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                ArrayList<ApnSetting> currentWaitingApns = apnContext.getWaitingApns();
44709a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
44719a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                if ((currentWaitingApns != null) && (!apnContext.isDisconnected())) {
44729a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
44739a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    ArrayList<ApnSetting> waitingApns = buildWaitingApns(
44749a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                            apnContext.getApnType(), radioTech);
44759a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    if (VDBG) log("new waitingApns:" + waitingApns);
44769a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    if (waitingApns.size() == currentWaitingApns.size()) {
44779a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                        cleanUpApn = false;
44789a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                        for (int i = 0; i < waitingApns.size(); i++) {
44799a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                            if (!currentWaitingApns.get(i).equals(waitingApns.get(i))) {
44809a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                                if (VDBG) log("new waiting apn is different at " + i);
44819a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                                cleanUpApn = true;
44829a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                                apnContext.setWaitingApns(waitingApns);
44839a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                                break;
44849a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                            }
44859a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                        }
44869a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    }
44879a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                }
44889a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
44899a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                if (cleanUpApn) {
44909a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    apnContext.setReason(Phone.REASON_APN_CHANGED);
44919a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    cleanUpConnection(true, apnContext);
44929a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                }
44939a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            }
44949a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        }
44959a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
44969a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (!isConnected()) {
44979a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            stopNetStatPoll();
44989a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            stopDataStallAlarm();
44999a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        }
45009a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
45019a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
45029a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
45039a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (DBG) log("mDisconnectPendingCount = " + mDisconnectPendingCount);
45049a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (tearDown && mDisconnectPendingCount == 0) {
45059a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            notifyDataDisconnectComplete();
45069a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            notifyAllDataDisconnected();
45079a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        }
45089a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang    }
45091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
45111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Polling stuff
45121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
45131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void resetPollStats() {
45141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mTxPkts = -1;
45151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mRxPkts = -1;
45161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mNetStatPollPeriod = POLL_NETSTAT_MILLIS;
45171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void startNetStatPoll() {
45201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (getOverallState() == DctConstants.State.CONNECTED
45211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                && mNetStatPollEnabled == false) {
45221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
45231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("startNetStatPoll");
45241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
45251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            resetPollStats();
45261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mNetStatPollEnabled = true;
45271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPollNetStat.run();
45281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
45291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mPhone != null) {
45301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPhone.notifyDataActivity();
45311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
45321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void stopNetStatPoll() {
45351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mNetStatPollEnabled = false;
45361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        removeCallbacks(mPollNetStat);
45371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
45381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("stopNetStatPoll");
45391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
45401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // To sync data activity icon in the case of switching data connection to send MMS.
45421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mPhone != null) {
45431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPhone.notifyDataActivity();
45441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
45451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void sendStartNetStatPoll(DctConstants.Activity activity) {
45481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.CMD_NET_STAT_POLL);
45491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = DctConstants.ENABLED;
45501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.obj = activity;
45511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
45521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void handleStartNetStatPoll(DctConstants.Activity activity) {
45551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startNetStatPoll();
45561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
45571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        setActivity(activity);
45581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void sendStopNetStatPoll(DctConstants.Activity activity) {
45611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.CMD_NET_STAT_POLL);
45621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = DctConstants.DISABLED;
45631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.obj = activity;
45641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
45651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void handleStopNetStatPoll(DctConstants.Activity activity) {
45681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        stopNetStatPoll();
45691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        stopDataStallAlarm();
45701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        setActivity(activity);
45711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void updateDataActivity() {
45741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        long sent, received;
45751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        DctConstants.Activity newActivity;
45771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        TxRxSum preTxRxSum = new TxRxSum(mTxPkts, mRxPkts);
45791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        TxRxSum curTxRxSum = new TxRxSum();
45801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        curTxRxSum.updateTxRxSum();
45811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mTxPkts = curTxRxSum.txPkts;
45821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mRxPkts = curTxRxSum.rxPkts;
45831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) {
45851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("updateDataActivity: curTxRxSum=" + curTxRxSum + " preTxRxSum=" + preTxRxSum);
45861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
45871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mNetStatPollEnabled && (preTxRxSum.txPkts > 0 || preTxRxSum.rxPkts > 0)) {
45891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            sent = mTxPkts - preTxRxSum.txPkts;
45901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            received = mRxPkts - preTxRxSum.rxPkts;
45911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG)
45931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("updateDataActivity: sent=" + sent + " received=" + received);
45941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (sent > 0 && received > 0) {
45951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = DctConstants.Activity.DATAINANDOUT;
45961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (sent > 0 && received == 0) {
45971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = DctConstants.Activity.DATAOUT;
45981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (sent == 0 && received > 0) {
45991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = DctConstants.Activity.DATAIN;
46001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
46011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = (mActivity == DctConstants.Activity.DORMANT) ?
46021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mActivity : DctConstants.Activity.NONE;
46031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mActivity != newActivity && mIsScreenOn) {
46061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (VDBG)
46071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("updateDataActivity: newActivity=" + newActivity);
46081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mActivity = newActivity;
46091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mPhone.notifyDataActivity();
46101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
46131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46142e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt    private void handlePcoData(AsyncResult ar) {
46152e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        if (ar.exception != null) {
46162e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            Rlog.e(LOG_TAG, "PCO_DATA exception: " + ar.exception);
46172e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            return;
46182e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        }
46192e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        PcoData pcoData = (PcoData)(ar.result);
4620cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        ArrayList<DataConnection> dcList = new ArrayList<>();
4621cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        DataConnection temp = mDcc.getActiveDcByCid(pcoData.cid);
4622cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        if (temp != null) {
4623cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            dcList.add(temp);
4624cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        }
4625cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        if (dcList.size() == 0) {
4626cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            Rlog.e(LOG_TAG, "PCO_DATA for unknown cid: " + pcoData.cid + ", inferring");
4627cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            for (DataConnection dc : mDataConnections.values()) {
4628cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                final int cid = dc.getCid();
4629cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                if (cid == pcoData.cid) {
4630cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    if (VDBG) Rlog.d(LOG_TAG, "  found " + dc);
4631cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    dcList.clear();
4632cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    dcList.add(dc);
4633cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    break;
4634cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                }
4635cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                // check if this dc is still connecting
4636cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                if (cid == -1) {
4637cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    for (ApnContext apnContext : dc.mApnContexts.keySet()) {
4638cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        if (apnContext.getState() == DctConstants.State.CONNECTING) {
4639cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                            if (VDBG) Rlog.d(LOG_TAG, "  found potential " + dc);
4640cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                            dcList.add(dc);
4641cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                            break;
4642cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                        }
4643cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                    }
4644cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                }
4645cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            }
4646cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        }
4647cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        if (dcList.size() == 0) {
4648cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            Rlog.e(LOG_TAG, "PCO_DATA - couldn't infer cid");
46492e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt            return;
46502e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        }
4651cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt        for (DataConnection dc : dcList) {
4652cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            if (dc.mApnContexts.size() == 0) {
4653cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                break;
4654cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            }
4655cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            // send one out for each apn type in play
4656cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            for (ApnContext apnContext : dc.mApnContexts.keySet()) {
4657cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                String apnType = apnContext.getApnType();
4658cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt
4659cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                final Intent intent = new Intent(TelephonyIntents.ACTION_CARRIER_SIGNAL_PCO_VALUE);
4660cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                intent.putExtra(TelephonyIntents.EXTRA_APN_TYPE_KEY, apnType);
4661cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                intent.putExtra(TelephonyIntents.EXTRA_APN_PROTO_KEY, pcoData.bearerProto);
4662cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                intent.putExtra(TelephonyIntents.EXTRA_PCO_ID_KEY, pcoData.pcoId);
4663cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                intent.putExtra(TelephonyIntents.EXTRA_PCO_VALUE_KEY, pcoData.contents);
4664cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt                mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
4665cda5b321ceddda71d47ec2fe619d6624dd2ea3daRobert Greenwalt            }
46662e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt        }
46672e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt    }
46682e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt
46691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
46701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Data-Stall
46711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
46721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Recovery action taken in case of data stall
46731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static class RecoveryAction {
46741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int GET_DATA_CALL_LIST      = 0;
46751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int CLEANUP                 = 1;
46761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int REREGISTER              = 2;
46771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int RADIO_RESTART           = 3;
46781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int RADIO_RESTART_WITH_PROP = 4;
46791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        private static boolean isAggressiveRecovery(int value) {
46811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return ((value == RecoveryAction.CLEANUP) ||
46821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    (value == RecoveryAction.REREGISTER) ||
46831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    (value == RecoveryAction.RADIO_RESTART) ||
46841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    (value == RecoveryAction.RADIO_RESTART_WITH_PROP));
46851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
46871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int getRecoveryAction() {
46891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int action = Settings.System.getInt(mResolver,
46901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                "radio.data.stall.recovery.action", RecoveryAction.GET_DATA_CALL_LIST);
46911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("getRecoveryAction: " + action);
46921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return action;
46931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
46941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void putRecoveryAction(int action) {
46961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Settings.System.putInt(mResolver, "radio.data.stall.recovery.action", action);
46971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("putRecoveryAction: " + action);
46981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
46991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void doRecovery() {
47011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (getOverallState() == DctConstants.State.CONNECTED) {
47021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Go through a series of recovery steps, each action transitions to the next action
47030a39f581e11eb7b040a5412229164ef72044279fRobert Greenwalt            final int recoveryAction = getRecoveryAction();
4704f2d0fa64860a12423fb8709766d6af90fba5e6cfJack Yu            TelephonyMetrics.getInstance().writeDataStallEvent(mPhone.getPhoneId(), recoveryAction);
47051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            switch (recoveryAction) {
47061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case RecoveryAction.GET_DATA_CALL_LIST:
47071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_GET_DATA_CALL_LIST,
47081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mSentSinceLastRecv);
47091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("doRecovery() get data call list");
47101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mPhone.mCi.getDataCallList(obtainMessage(DctConstants.EVENT_DATA_STATE_CHANGED));
47111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                putRecoveryAction(RecoveryAction.CLEANUP);
47121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
47131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case RecoveryAction.CLEANUP:
47141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_CLEANUP, mSentSinceLastRecv);
47151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("doRecovery() cleanup all connections");
47161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                cleanUpAllConnections(Phone.REASON_PDP_RESET);
47171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                putRecoveryAction(RecoveryAction.REREGISTER);
47181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
47191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case RecoveryAction.REREGISTER:
47201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_REREGISTER,
47211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mSentSinceLastRecv);
47221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("doRecovery() re-register");
47231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mPhone.getServiceStateTracker().reRegisterNetwork(null);
47241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                putRecoveryAction(RecoveryAction.RADIO_RESTART);
47251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
47261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case RecoveryAction.RADIO_RESTART:
47271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART,
47281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mSentSinceLastRecv);
47291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("restarting radio");
47301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                putRecoveryAction(RecoveryAction.RADIO_RESTART_WITH_PROP);
47311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartRadio();
47321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
47331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case RecoveryAction.RADIO_RESTART_WITH_PROP:
47341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // This is in case radio restart has not recovered the data.
47351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // It will set an additional "gsm.radioreset" property to tell
47361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // RIL or system to take further action.
47371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // The implementation of hard reset recovery action is up to OEM product.
47381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // Once RADIO_RESET property is consumed, it is expected to set back
47391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // to false by RIL.
47401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART_WITH_PROP, -1);
47411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("restarting radio with gsm.radioreset to true");
47421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                SystemProperties.set(RADIO_RESET_PROPERTY, "true");
47431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // give 1 sec so property change can be notified.
47441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                try {
47451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    Thread.sleep(1000);
47461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } catch (InterruptedException e) {}
47471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartRadio();
47481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
47491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
47501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            default:
47511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                throw new RuntimeException("doRecovery: Invalid recoveryAction=" +
47521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    recoveryAction);
47531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSentSinceLastRecv = 0;
47551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void updateDataStallInfo() {
47591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        long sent, received;
47601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        TxRxSum preTxRxSum = new TxRxSum(mDataStallTxRxSum);
47621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDataStallTxRxSum.updateTxRxSum();
47631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) {
47651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("updateDataStallInfo: mDataStallTxRxSum=" + mDataStallTxRxSum +
47661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " preTxRxSum=" + preTxRxSum);
47671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sent = mDataStallTxRxSum.txPkts - preTxRxSum.txPkts;
47701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        received = mDataStallTxRxSum.rxPkts - preTxRxSum.rxPkts;
47711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (RADIO_TESTS) {
47731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (SystemProperties.getBoolean("radio.test.data.stall", false)) {
47741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("updateDataStallInfo: radio.test.data.stall true received = 0;");
47751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                received = 0;
47761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if ( sent > 0 && received > 0 ) {
47791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) log("updateDataStallInfo: IN/OUT");
47801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSentSinceLastRecv = 0;
47811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
47821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (sent > 0 && received == 0) {
4783828a110000eca870560ead99186d5727e96e64f8Sandeep Gutta            if (isPhoneStateIdle()) {
47841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mSentSinceLastRecv += sent;
47851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
47861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mSentSinceLastRecv = 0;
47871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
47891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("updateDataStallInfo: OUT sent=" + sent +
47901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        " mSentSinceLastRecv=" + mSentSinceLastRecv);
47911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (sent == 0 && received > 0) {
47931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) log("updateDataStallInfo: IN");
47941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSentSinceLastRecv = 0;
47951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
47961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
47971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) log("updateDataStallInfo: NONE");
47981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
48001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4801828a110000eca870560ead99186d5727e96e64f8Sandeep Gutta    private boolean isPhoneStateIdle() {
4802828a110000eca870560ead99186d5727e96e64f8Sandeep Gutta        for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
4803828a110000eca870560ead99186d5727e96e64f8Sandeep Gutta            Phone phone = PhoneFactory.getPhone(i);
4804828a110000eca870560ead99186d5727e96e64f8Sandeep Gutta            if (phone != null && phone.getState() != PhoneConstants.State.IDLE) {
4805828a110000eca870560ead99186d5727e96e64f8Sandeep Gutta                log("isPhoneStateIdle false: Voice call active on phone " + i);
4806828a110000eca870560ead99186d5727e96e64f8Sandeep Gutta                return false;
4807828a110000eca870560ead99186d5727e96e64f8Sandeep Gutta            }
4808828a110000eca870560ead99186d5727e96e64f8Sandeep Gutta        }
4809828a110000eca870560ead99186d5727e96e64f8Sandeep Gutta        return true;
4810828a110000eca870560ead99186d5727e96e64f8Sandeep Gutta    }
4811828a110000eca870560ead99186d5727e96e64f8Sandeep Gutta
48121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataStallAlarm(int tag) {
48131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mDataStallAlarmTag != tag) {
48141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
48151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("onDataStallAlarm: ignore, tag=" + tag + " expecting " + mDataStallAlarmTag);
48161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
48171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return;
48181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
48191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        updateDataStallInfo();
48201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
48211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int hangWatchdogTrigger = Settings.Global.getInt(mResolver,
48221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Settings.Global.PDP_WATCHDOG_TRIGGER_PACKET_COUNT,
48231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                NUMBER_SENT_PACKETS_OF_HANG);
48241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
48251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        boolean suspectedStall = DATA_STALL_NOT_SUSPECTED;
48261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mSentSinceLastRecv >= hangWatchdogTrigger) {
48271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
48281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("onDataStallAlarm: tag=" + tag + " do recovery action=" + getRecoveryAction());
48291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
48301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            suspectedStall = DATA_STALL_SUSPECTED;
48311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            sendMessage(obtainMessage(DctConstants.EVENT_DO_RECOVERY));
48321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
48331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) {
48341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("onDataStallAlarm: tag=" + tag + " Sent " + String.valueOf(mSentSinceLastRecv) +
48351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " pkts since last received, < watchdogTrigger=" + hangWatchdogTrigger);
48361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
48371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
48381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startDataStallAlarm(suspectedStall);
48391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
48401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
48411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void startDataStallAlarm(boolean suspectedStall) {
48421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int nextAction = getRecoveryAction();
48431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int delayInMs;
48441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
48451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mDataStallDetectionEnabled && getOverallState() == DctConstants.State.CONNECTED) {
48461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // If screen is on or data stall is currently suspected, set the alarm
48470e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // with an aggressive timeout.
48481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mIsScreenOn || suspectedStall || RecoveryAction.isAggressiveRecovery(nextAction)) {
48491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                delayInMs = Settings.Global.getInt(mResolver,
48501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS,
48511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
48521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
48531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                delayInMs = Settings.Global.getInt(mResolver,
48541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS,
48551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
48561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
48571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
48581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mDataStallAlarmTag += 1;
48591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) {
48601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("startDataStallAlarm: tag=" + mDataStallAlarmTag +
48611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        " delay=" + (delayInMs / 1000) + "s");
48621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
48631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Intent intent = new Intent(INTENT_DATA_STALL_ALARM);
48641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            intent.putExtra(DATA_STALL_ALARM_TAG_EXTRA, mDataStallAlarmTag);
48651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mDataStallAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
48661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    PendingIntent.FLAG_UPDATE_CURRENT);
4867128f3f36854fe183a6dd4d9917906b4723dd234fAjay Dudani            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME,
48681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    SystemClock.elapsedRealtime() + delayInMs, mDataStallAlarmIntent);
48691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
48701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) {
48711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("startDataStallAlarm: NOT started, no connection tag=" + mDataStallAlarmTag);
48721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
48731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
48741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
48751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
48761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void stopDataStallAlarm() {
48771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) {
48781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("stopDataStallAlarm: current tag=" + mDataStallAlarmTag +
48791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " mDataStallAlarmIntent=" + mDataStallAlarmIntent);
48801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
48811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDataStallAlarmTag += 1;
48821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mDataStallAlarmIntent != null) {
48831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mAlarmManager.cancel(mDataStallAlarmIntent);
48841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mDataStallAlarmIntent = null;
48851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
48861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
48871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
48881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void restartDataStallAlarm() {
48891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (isConnected() == false) return;
48901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // To be called on screen status change.
48911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // Do not cancel the alarm if it is set with aggressive timeout.
48921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int nextAction = getRecoveryAction();
48931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
48941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (RecoveryAction.isAggressiveRecovery(nextAction)) {
48951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("restartDataStallAlarm: action is pending. not resetting the alarm.");
48961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return;
48971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
48981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("restartDataStallAlarm: stop then start.");
48991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        stopDataStallAlarm();
49001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
49011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
49021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
49031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
49041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Provisioning APN
49051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
49061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onActionIntentProvisioningApnAlarm(Intent intent) {
49071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("onActionIntentProvisioningApnAlarm: action=" + intent.getAction());
49081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_PROVISIONING_APN_ALARM,
49091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                intent.getAction());
49101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = intent.getIntExtra(PROVISIONING_APN_ALARM_TAG_EXTRA, 0);
49111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
49121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
49131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
49141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void startProvisioningApnAlarm() {
49151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int delayInMs = Settings.Global.getInt(mResolver,
49161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                Settings.Global.PROVISIONING_APN_ALARM_DELAY_IN_MS,
49171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                PROVISIONING_APN_ALARM_DELAY_IN_MS_DEFAULT);
49181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (Build.IS_DEBUGGABLE) {
49191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Allow debug code to use a system property to provide another value
49201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            String delayInMsStrg = Integer.toString(delayInMs);
49211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            delayInMsStrg = System.getProperty(DEBUG_PROV_APN_ALARM, delayInMsStrg);
49221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            try {
49231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                delayInMs = Integer.parseInt(delayInMsStrg);
49241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } catch (NumberFormatException e) {
49251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                loge("startProvisioningApnAlarm: e=" + e);
49261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
49271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
49281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisioningApnAlarmTag += 1;
49291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
49301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("startProvisioningApnAlarm: tag=" + mProvisioningApnAlarmTag +
49311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " delay=" + (delayInMs / 1000) + "s");
49321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
49331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Intent intent = new Intent(INTENT_PROVISIONING_APN_ALARM);
49341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        intent.putExtra(PROVISIONING_APN_ALARM_TAG_EXTRA, mProvisioningApnAlarmTag);
49351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisioningApnAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
49361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                PendingIntent.FLAG_UPDATE_CURRENT);
49371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
49381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                SystemClock.elapsedRealtime() + delayInMs, mProvisioningApnAlarmIntent);
49391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
49401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
49411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void stopProvisioningApnAlarm() {
49421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
49431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("stopProvisioningApnAlarm: current tag=" + mProvisioningApnAlarmTag +
49441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " mProvsioningApnAlarmIntent=" + mProvisioningApnAlarmIntent);
49451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
49461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisioningApnAlarmTag += 1;
49471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mProvisioningApnAlarmIntent != null) {
49481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mAlarmManager.cancel(mProvisioningApnAlarmIntent);
49491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mProvisioningApnAlarmIntent = null;
49501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
49511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
49521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4953c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville}
4954