DcTracker.java revision 3d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3c
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;
30a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxuimport android.content.pm.PackageManager;
31cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.content.res.Resources;
32c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.database.ContentObserver;
33cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.database.Cursor;
34cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.ConnectivityManager;
35a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxuimport android.net.ConnectivityManager.NetworkCallback;
36c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.net.LinkProperties;
3796cce86cf08e37e0f09ed5057b1196e26b302743Robert Greenwaltimport android.net.NetworkCapabilities;
38cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.NetworkConfig;
391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.net.NetworkInfo;
40af5593594070f825032be46dced573cd195956e1Robert Greenwaltimport android.net.NetworkRequest;
41cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.NetworkUtils;
429c180aedfc9f0d20525c0128487d3500e6c0a715Jason Monkimport android.net.ProxyInfo;
431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.net.TrafficStats;
44cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.Uri;
451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.net.wifi.WifiManager;
46c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.AsyncResult;
473fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwaltimport android.os.Build;
48b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensenimport android.os.Bundle;
49a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.Handler;
501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.os.HandlerThread;
51af5593594070f825032be46dced573cd195956e1Robert Greenwaltimport android.os.Looper;
52c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Message;
53a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxuimport android.os.PersistableBundle;
54a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.RegistrantList;
55b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensenimport android.os.ServiceManager;
56c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemClock;
57c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemProperties;
581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.preference.PreferenceManager;
59c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.provider.Settings;
601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.provider.Settings.SettingNotFoundException;
61cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.provider.Telephony;
62a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxuimport android.telephony.CarrierConfigManager;
63cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.CellLocation;
640e776303ca82b5bec5db19bb44e0f13b0c7c6400Etan Cohenimport android.telephony.ServiceState;
65a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxuimport android.telephony.SubscriptionInfo;
66c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.telephony.TelephonyManager;
67a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.SubscriptionManager;
681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
69cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.cdma.CdmaCellLocation;
70cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.gsm.GsmCellLocation;
71c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.text.TextUtils;
72cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kallaimport android.util.EventLog;
732dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwaltimport android.util.LocalLog;
74ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwaltimport android.util.Pair;
75af5593594070f825032be46dced573cd195956e1Robert Greenwaltimport android.util.SparseArray;
762b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensenimport android.view.WindowManager;
7799c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Savilleimport android.telephony.Rlog;
78c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport com.android.internal.R;
80af5593594070f825032be46dced573cd195956e1Robert Greenwaltimport com.android.internal.annotations.VisibleForTesting;
811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport com.android.internal.telephony.GsmCdmaPhone;
824918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savilleimport com.android.internal.telephony.Phone;
83cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.DctConstants;
84cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.EventLogTags;
85b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensenimport com.android.internal.telephony.ITelephony;
864918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savilleimport com.android.internal.telephony.PhoneConstants;
87cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.RILConstants;
88a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxuimport com.android.internal.telephony.SubscriptionController;
89a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxuimport com.android.internal.telephony.TelephonyIntents;
90d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccRecords;
91bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenkaimport com.android.internal.telephony.uicc.UiccController;
92c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.util.AsyncChannel;
9376f43316a5a6082d601bffd4b6898d0bd81e11fcramimport com.android.internal.util.ArrayUtils;
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;
1011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.List;
1021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.Map.Entry;
10329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwaltimport java.util.Objects;
1041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.PriorityQueue;
1051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.Set;
1063d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxuimport java.util.HashSet;
1073d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
1081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.concurrent.ConcurrentHashMap;
1091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.concurrent.atomic.AtomicBoolean;
1101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.concurrent.atomic.AtomicInteger;
1111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.concurrent.atomic.AtomicReference;
112d86df358b8fe07160caa12147b6e4ad34d378ce6xinheimport java.lang.StringBuilder;
113c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
114a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.ServiceStateTracker;
115c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/**
116c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * {@hide}
117c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
1180c3ec24396bb8c21b4d89f743b626c13dd35ba7bAmit Mahajanpublic class DcTracker extends Handler {
1191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String LOG_TAG = "DCT";
1201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean DBG = true;
1211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean VDBG = false; // STOPSHIP if true
1221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean VDBG_STALL = false; // STOPSHIP if true
1231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean RADIO_TESTS = false;
1241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1250e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    public AtomicBoolean isCleanupRequired = new AtomicBoolean(false);
1261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final AlarmManager mAlarmManager;
1281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private Object mDataEnabledLock = new Object();
1301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // responds to the setInternalDataEnabled call - used internally to turn off data
1321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // for example during emergency calls
1331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mInternalDataEnabled = true;
1341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // responds to public (user) API to enable/disable data use
1361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // independent of mInternalDataEnabled and requests for APN access
1371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // persisted
1381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mUserDataEnabled = true;
1391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // TODO: move away from static state once 5587429 is fixed.
1411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static boolean sPolicyDataEnabled = true;
1421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Currently requested APN type (TODO: This should probably be a parameter not a member) */
1441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private String mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
1451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
1471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * After detecting a potential connection problem, this is the max number
1481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * of subsequent polls before attempting recovery.
1491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
1501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // 1 sec. default polling interval when screen is on.
1511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int POLL_NETSTAT_MILLIS = 1000;
1521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // 10 min. default polling interval when screen is off.
1531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int POLL_NETSTAT_SCREEN_OFF_MILLIS = 1000*60*10;
1541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Default sent packets without ack which triggers initial recovery steps
1551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int NUMBER_SENT_PACKETS_OF_HANG = 10;
1561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Default for the data stall alarm while non-aggressive stall detection
1581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60 * 6;
1591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Default for the data stall alarm for aggressive stall detection
1601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60;
1611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Tag for tracking stale alarms
1621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String DATA_STALL_ALARM_TAG_EXTRA = "data.stall.alram.tag";
1631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean DATA_STALL_SUSPECTED = true;
1651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean DATA_STALL_NOT_SUSPECTED = false;
1661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private String RADIO_RESET_PROPERTY = "gsm.radioreset";
1681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_RECONNECT_ALARM =
1701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "com.android.internal.telephony.data-reconnect";
1711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_RECONNECT_ALARM_EXTRA_TYPE = "reconnect_alarm_extra_type";
1721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_RECONNECT_ALARM_EXTRA_REASON =
1731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "reconnect_alarm_extra_reason";
1741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_DATA_STALL_ALARM =
1761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "com.android.internal.telephony.data-stall";
1771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
178a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    private static final String REDIRECTION_URL_KEY = "redirectionUrl";
179a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    private static final String ERROR_CODE_KEY = "errorCode";
180a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    private static final String APN_TYPE_KEY = "apnType";
181a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
1823d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu    @VisibleForTesting
1833d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu    public static class DataAllowFailReason {
1843d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        private HashSet<DataAllowFailReasonType> mDataAllowFailReasonSet = new HashSet<>();
1853d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
1863d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        public void addDataAllowFailReason(DataAllowFailReasonType type) {
1873d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            mDataAllowFailReasonSet.add(type);
1883d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
1893d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
1903d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        public String getDataAllowFailReason() {
1913d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            StringBuilder failureReason = new StringBuilder();
1923d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            failureReason.append("isDataAllowed: No");
1933d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            for(DataAllowFailReasonType reason : mDataAllowFailReasonSet) {
1943d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                failureReason.append(reason.mFailReasonStr);
1953d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            }
1963d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            return failureReason.toString();
1973d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
1983d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
1993d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        public boolean isFailForSingleReason(DataAllowFailReasonType failReasonType) {
2003d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            return (mDataAllowFailReasonSet.size() == 1) &&
2013d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                    (mDataAllowFailReasonSet.contains(failReasonType));
2023d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
2033d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
2043d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        public void clearAllReasons() {
2053d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            mDataAllowFailReasonSet.clear();
2063d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
2073d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
2083d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        public boolean isFailed() {
2093d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            return mDataAllowFailReasonSet.size() > 0;
2103d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
2113d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu    }
2123d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
2133d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu    @VisibleForTesting
2143d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu    public enum DataAllowFailReasonType {
2153d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        NOT_ATTACHED(" - Not attached"),
2163d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        RECORD_NOT_LOADED(" - SIM not loaded"),
2173d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        ROAMING_DISABLED(" - Roaming and data roaming not enabled"),
2183d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        INVALID_PHONE_STATE(" - PhoneState is not idle"),
2193d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        CONCURRENT_VOICE_DATA_NOT_ALLOWED(" - Concurrent voice and data not allowed"),
2203d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        PS_RESTRICTED(" - mIsPsRestricted= true"),
2213d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        UNDESIRED_POWER_STATE(" - desiredPowerState= false"),
2223d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        INTERNAL_DATA_DISABLED(" - mInternalDataEnabled= false"),
2233d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        DEFAULT_DATA_UNSELECTED(" - defaultDataSelected= false");
2243d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
2253d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        public String mFailReasonStr;
2263d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
2273d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        DataAllowFailReasonType(String reason) {
2283d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            mFailReasonStr = reason;
2293d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
2303d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu    }
2313d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
2321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DcTesterFailBringUpAll mDcTesterFailBringUpAll;
2331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DcController mDcc;
2341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** kept in sync with mApnContexts
2361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Higher numbers are higher priority and sorted so highest priority is first */
2371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final PriorityQueue<ApnContext>mPrioritySortedApnContexts =
2381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new PriorityQueue<ApnContext>(5,
2391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new Comparator<ApnContext>() {
2401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                public int compare(ApnContext c1, ApnContext c2) {
2411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    return c2.priority - c1.priority;
2421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
2431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } );
2441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** allApns holds all apns */
2461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ArrayList<ApnSetting> mAllApnSettings = null;
2471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** preferred apn */
2491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ApnSetting mPreferredApn = null;
2501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Is packet service restricted by network */
2521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsPsRestricted = false;
2531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** emergency apn Setting*/
2551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ApnSetting mEmergencyApn = null;
2561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Once disposed dont handle any messages */
2581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsDisposed = false;
2591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ContentResolver mResolver;
2611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Set to true with CMD_ENABLE_MOBILE_PROVISIONING */
2631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsProvisioning = false;
2641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* The Url passed as object parameter in CMD_ENABLE_MOBILE_PROVISIONING */
2661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private String mProvisioningUrl = null;
2671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Intent for the provisioning apn alarm */
2691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_PROVISIONING_APN_ALARM =
2701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "com.android.internal.telephony.provisioning_apn_alarm";
2711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Tag for tracking stale alarms */
2731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String PROVISIONING_APN_ALARM_TAG_EXTRA = "provisioning.apn.alarm.tag";
2741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Debug property for overriding the PROVISIONING_APN_ALARM_DELAY_IN_MS */
2761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String DEBUG_PROV_APN_ALARM = "persist.debug.prov_apn_alarm";
2771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Default for the provisioning apn alarm timeout */
2791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int PROVISIONING_APN_ALARM_DELAY_IN_MS_DEFAULT = 1000 * 60 * 15;
2801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* The provision apn alarm intent used to disable the provisioning apn */
2821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private PendingIntent mProvisioningApnAlarmIntent = null;
2831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Used to track stale provisioning apn alarms */
2851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mProvisioningApnAlarmTag = (int) SystemClock.elapsedRealtime();
2861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private AsyncChannel mReplyAc = new AsyncChannel();
2881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver () {
2901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
2911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void onReceive(Context context, Intent intent) {
2921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            String action = intent.getAction();
293c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu
2941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (action.equals(Intent.ACTION_SCREEN_ON)) {
295c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("screen on");
2961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mIsScreenOn = true;
2971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                stopNetStatPoll();
2981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                startNetStatPoll();
2991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartDataStallAlarm();
3001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
301c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("screen off");
3021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mIsScreenOn = false;
3031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                stopNetStatPoll();
3041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                startNetStatPoll();
3051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartDataStallAlarm();
3061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.startsWith(INTENT_RECONNECT_ALARM)) {
3071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("Reconnect alarm. Previous state was " + mState);
3081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onActionIntentReconnectAlarm(intent);
3091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(INTENT_DATA_STALL_ALARM)) {
310c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("Data stall alarm");
3111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onActionIntentDataStallAlarm(intent);
3121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(INTENT_PROVISIONING_APN_ALARM)) {
313c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("Provisioning apn alarm");
3141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onActionIntentProvisioningApnAlarm(intent);
3151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
3161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final android.net.NetworkInfo networkInfo = (NetworkInfo)
3171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
3181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mIsWifiConnected = (networkInfo != null && networkInfo.isConnected());
3191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("NETWORK_STATE_CHANGED_ACTION: mIsWifiConnected=" + mIsWifiConnected);
3201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
321c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("Wifi state changed");
3221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
3231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
3241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (!enabled) {
3251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // when WiFi got disabled, the NETWORK_STATE_CHANGED_ACTION
3261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // quit and won't report disconnected until next enabling.
3271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mIsWifiConnected = false;
3281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
3291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
3301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("WIFI_STATE_CHANGED_ACTION: enabled=" + enabled
3311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + " mIsWifiConnected=" + mIsWifiConnected);
3321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
333c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            } else {
334c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("onReceive: Unknown action=" + action);
3351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
3361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    };
3381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final Runnable mPollNetStat = new Runnable() {
3401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
3411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void run() {
3421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            updateDataActivity();
3431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mIsScreenOn) {
3451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mNetStatPollPeriod = Settings.Global.getInt(mResolver,
3461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.PDP_WATCHDOG_POLL_INTERVAL_MS, POLL_NETSTAT_MILLIS);
3471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
3481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mNetStatPollPeriod = Settings.Global.getInt(mResolver,
3491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS,
3501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        POLL_NETSTAT_SCREEN_OFF_MILLIS);
3511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
3521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mNetStatPollEnabled) {
3541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mDataConnectionTracker.postDelayed(this, mNetStatPollPeriod);
3551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
3561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    };
3581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private SubscriptionManager mSubscriptionManager;
3601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final OnSubscriptionsChangedListener mOnSubscriptionsChangedListener =
3611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new OnSubscriptionsChangedListener() {
3621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                public final AtomicInteger mPreviousSubId =
3631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        new AtomicInteger(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
3641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                /**
3661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                 * Callback invoked when there is any change to any SubscriptionInfo. Typically
3671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                 * this method invokes {@link SubscriptionManager#getActiveSubscriptionInfoList}
3681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                 */
3691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                @Override
3701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                public void onSubscriptionsChanged() {
3711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (DBG) log("SubscriptionListener.onSubscriptionInfoChanged");
3721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // Set the network type, in case the radio does not restore it.
3731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    int subId = mPhone.getSubId();
3741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (SubscriptionManager.isValidSubscriptionId(subId)) {
375f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                        registerSettingsObserver();
376a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                         /* check if sim is un-provisioned due to cold sim detection */
377a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                        applyColdSimDetected(subId);
3781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
3791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mPreviousSubId.getAndSet(subId) != subId &&
3801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            SubscriptionManager.isValidSubscriptionId(subId)) {
3811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onRecordsLoadedOrSubIdChanged();
3821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
3831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
3841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            };
3851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
386f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    private static class SettingsObserver extends ContentObserver {
387f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        final private HashMap<Uri, Integer> mUriEventMap;
388f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        final private Context mContext;
389f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        final private Handler mHandler;
390f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        final private static String TAG = "DcTracker.SettingsObserver";
3911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
392f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        SettingsObserver(Context context, Handler handler) {
393f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            super(null);
394f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            mUriEventMap = new HashMap<Uri, Integer>();
395f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            mContext = context;
396f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            mHandler = handler;
3971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
399f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        void observe(Uri uri, int what) {
400f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            mUriEventMap.put(uri, what);
401f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            final ContentResolver resolver = mContext.getContentResolver();
402f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            resolver.registerContentObserver(uri, false, this);
4031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
405f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        void unobserve() {
406f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            final ContentResolver resolver = mContext.getContentResolver();
407f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            resolver.unregisterContentObserver(this);
4081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
4111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void onChange(boolean selfChange) {
412f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            Rlog.e(TAG, "Should never be reached.");
413f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        }
414f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
415f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        @Override
416f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        public void onChange(boolean selfChange, Uri uri) {
417f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            final Integer what = mUriEventMap.get(uri);
418f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            if (what != null) {
419f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                mHandler.obtainMessage(what.intValue()).sendToTarget();
420f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            } else {
421f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                Rlog.e(TAG, "No matching event to send for URI=" + uri);
4221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
4231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
425f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
426f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    private final SettingsObserver mSettingsObserver;
427f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
428f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    private void registerSettingsObserver() {
429f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.unobserve();
430f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        String simSuffix = "";
431f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        if (TelephonyManager.getDefault().getSimCount() == 1) {
432f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            simSuffix = Integer.toString(mPhone.getSubId());
433f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        }
434f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.observe(
435f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                Settings.Global.getUriFor(Settings.Global.DATA_ROAMING + simSuffix),
436f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                DctConstants.EVENT_ROAMING_ON);
437f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
438f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.observe(
439f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
440f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE);
441f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.observe(
442f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED),
443f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE);
444f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    }
4451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
4471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Maintain the sum of transmit and receive packets.
4481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     *
4491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * The packet counts are initialized and reset to -1 and
4501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * remain -1 until they can be updated.
4511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
4521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public static class TxRxSum {
4531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public long txPkts;
4541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public long rxPkts;
4551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public TxRxSum() {
4571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            reset();
4581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public TxRxSum(long txPkts, long rxPkts) {
4611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.txPkts = txPkts;
4621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.rxPkts = rxPkts;
4631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public TxRxSum(TxRxSum sum) {
4661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            txPkts = sum.txPkts;
4671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            rxPkts = sum.rxPkts;
4681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void reset() {
4711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            txPkts = -1;
4721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            rxPkts = -1;
4731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
4761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public String toString() {
4771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return "{txSum=" + txPkts + " rxSum=" + rxPkts + "}";
4781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void updateTxRxSum() {
4811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.txPkts = TrafficStats.getMobileTcpTxPackets();
4821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.rxPkts = TrafficStats.getMobileTcpRxPackets();
4831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
4851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onActionIntentReconnectAlarm(Intent intent) {
4871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON);
4881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        String apnType = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE);
4891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int phoneSubId = mPhone.getSubId();
4911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int currSubId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
4921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
4931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("onActionIntentReconnectAlarm: currSubId = " + currSubId + " phoneSubId=" + phoneSubId);
4941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // Stop reconnect if not current subId is not correct.
4961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // FIXME STOPSHIP - phoneSubId is coming up as -1 way after boot and failing this?
4971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (!SubscriptionManager.isValidSubscriptionId(currSubId) || (currSubId != phoneSubId)) {
4981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("receive ReconnectAlarm but subId incorrect, ignore");
4991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return;
5001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
5011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnContext apnContext = mApnContexts.get(apnType);
5031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
5051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("onActionIntentReconnectAlarm: mState=" + mState + " reason=" + reason +
5061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " apnType=" + apnType + " apnContext=" + apnContext +
5071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " mDataConnectionAsyncChannels=" + mDataConnectionAcHashMap);
5081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
5091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if ((apnContext != null) && (apnContext.isEnabled())) {
5111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            apnContext.setReason(reason);
5121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            DctConstants.State apnContextState = apnContext.getState();
5131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
5141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("onActionIntentReconnectAlarm: apnContext state=" + apnContextState);
5151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
5161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if ((apnContextState == DctConstants.State.FAILED)
5171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    || (apnContextState == DctConstants.State.IDLE)) {
5181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
5191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("onActionIntentReconnectAlarm: state is FAILED|IDLE, disassociate");
5201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
5211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DcAsyncChannel dcac = apnContext.getDcAc();
5221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (dcac != null) {
5231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (DBG) {
5241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        log("onActionIntentReconnectAlarm: tearDown apnContext=" + apnContext);
5251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
5261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    dcac.tearDown(apnContext, "", null);
5271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
5281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                apnContext.setDataConnectionAc(null);
5291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                apnContext.setState(DctConstants.State.IDLE);
5301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
5311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("onActionIntentReconnectAlarm: keep associated");
5321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
5331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // TODO: IF already associated should we send the EVENT_TRY_SETUP_DATA???
5341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            sendMessage(obtainMessage(DctConstants.EVENT_TRY_SETUP_DATA, apnContext));
5351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            apnContext.setReconnectIntent(null);
5371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
5381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
5391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onActionIntentDataStallAlarm(Intent intent) {
5411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("onActionIntentDataStallAlarm: action=" + intent.getAction());
5421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_DATA_STALL_ALARM,
5431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                intent.getAction());
5441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = intent.getIntExtra(DATA_STALL_ALARM_TAG_EXTRA, 0);
5451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
5461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
5471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final ConnectivityManager mCm;
549c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
550b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla    /**
551a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * List of messages that are waiting to be posted, when data call disconnect
552a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * is complete
553a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
554a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ArrayList<Message> mDisconnectAllCompleteMsgList = new ArrayList<Message>();
555a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
556a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private RegistrantList mAllDataDisconnectedRegistrants = new RegistrantList();
557a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
5581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // member variables
5591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final Phone mPhone;
5601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final UiccController mUiccController;
5611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
5621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DctConstants.Activity mActivity = DctConstants.Activity.NONE;
5631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DctConstants.State mState = DctConstants.State.IDLE;
5641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final Handler mDataConnectionTracker;
5651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private long mTxPkts;
5671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private long mRxPkts;
5681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mNetStatPollPeriod;
5691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mNetStatPollEnabled = false;
5701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private TxRxSum mDataStallTxRxSum = new TxRxSum(0, 0);
5721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Used to track stale data stall alarms.
5731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mDataStallAlarmTag = (int) SystemClock.elapsedRealtime();
5741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // The current data stall alarm intent
5751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private PendingIntent mDataStallAlarmIntent = null;
5761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Number of packets sent since the last received packet
5771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private long mSentSinceLastRecv;
5781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Controls when a simple recovery attempt it to be tried
5791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mNoRecvPollCount = 0;
5800e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    // Reference counter for enabling fail fast
5811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static int sEnableFailFastRefCounter = 0;
5821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // True if data stall detection is enabled
5831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private volatile boolean mDataStallDetectionEnabled = true;
5841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private volatile boolean mFailFast = false;
5861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // True when in voice call
5881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mInVoiceCall = false;
5891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // wifi connection status will be updated by sticky intent
5911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsWifiConnected = false;
5921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Intent sent when the reconnect alarm fires. */
5941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private PendingIntent mReconnectIntent = null;
5951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // When false we will not auto attach and manually attaching is required.
5971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mAutoAttachOnCreationConfig = false;
5981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private AtomicBoolean mAutoAttachOnCreation = new AtomicBoolean(false);
5991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // State of screen
6011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // (TODO: Reconsider tying directly to screen, maybe this is
6021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    //        really a lower power mode")
6031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsScreenOn = true;
6041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Indicates if we found mvno-specific APNs in the full APN list.
6061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // used to determine if we can accept mno-specific APN for tethering.
6071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mMvnoMatched = false;
6081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Allows the generation of unique Id's for DataConnection objects */
6101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private AtomicInteger mUniqueIdGenerator = new AtomicInteger(0);
6111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** The data connections. */
6131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private HashMap<Integer, DataConnection> mDataConnections =
6141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new HashMap<Integer, DataConnection>();
6151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** The data connection async channels */
6171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private HashMap<Integer, DcAsyncChannel> mDataConnectionAcHashMap =
6181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new HashMap<Integer, DcAsyncChannel>();
6191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Convert an ApnType string to Id (TODO: Use "enumeration" instead of String for ApnType) */
6211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private HashMap<String, Integer> mApnToDataConnectionId = new HashMap<String, Integer>();
6221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Phone.APN_TYPE_* ===> ApnContext */
6241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final ConcurrentHashMap<String, ApnContext> mApnContexts =
6251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new ConcurrentHashMap<String, ApnContext>();
6261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
627af5593594070f825032be46dced573cd195956e1Robert Greenwalt    private final SparseArray<ApnContext> mApnContextsById = new SparseArray<ApnContext>();
628af5593594070f825032be46dced573cd195956e1Robert Greenwalt
6291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mDisconnectPendingCount = 0;
630a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
631a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    /** mRedirected is set to true when we first got the validation failure with the redirection URL
632a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu     * based on this value we start the Carrier App to check the sim state */
633a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    private boolean mRedirected = false;
634a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
635a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    /** mColdSimDetected is set to true when we received SubInfoChanged &&
636a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu     * SubscriptionInfo.simProvisioningStatus equals to SIM_UNPROVISIONED_COLD */
637a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    private boolean mColdSimDetected = false;
638a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
639a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
640cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Handles changes to the APN db.
641b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla     */
642cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private class ApnChangeObserver extends ContentObserver {
643cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public ApnChangeObserver () {
644cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            super(mDataConnectionTracker);
645cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
646c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
647cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
648cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public void onChange(boolean selfChange) {
649cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            sendMessage(obtainMessage(DctConstants.EVENT_APN_CHANGED));
650cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
651cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
652c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
653cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Instance Variables
654c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
655cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean mReregisterOnReconnectFailure = false;
656c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
657c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
658cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Constants
659c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
660ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    // Used by puppetmaster/*/radio_stress.py
661ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private static final String PUPPET_MASTER_RADIO_STRESS_TEST = "gsm.defaultpdpcontext.active";
662c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
663ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private static final int POLL_PDP_MILLIS = 5 * 1000;
664c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
6652b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen    private static final int PROVISIONING_SPINNER_TIMEOUT_MILLIS = 120 * 1000;
6662b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen
6676bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville    static final Uri PREFERAPN_NO_UPDATE_URI_USING_SUBID =
6686bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville                        Uri.parse("content://telephony/carriers/preferapn_no_update/subId/");
669cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final String APN_ID = "apn_id";
670cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
671ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private boolean mCanSetPreferApn = false;
672c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
673187a39f896f88eb6c5e4306d9595546654825976Wink Saville    private AtomicBoolean mAttached = new AtomicBoolean(false);
674187a39f896f88eb6c5e4306d9595546654825976Wink Saville
675cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** Watches for changes to the APN db. */
676cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ApnChangeObserver mApnObserver;
677cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
678b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private final String mProvisionActionName;
679b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private BroadcastReceiver mProvisionBroadcastReceiver;
6802b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen    private ProgressDialog mProvisioningSpinner;
681b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
682a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean mImsRegistrationState = false;
683a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
684cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Constructor
6851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public DcTracker(Phone phone) {
6861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        super();
6871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone = phone;
6881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("DCT.constructor");
6901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mResolver = mPhone.getContext().getContentResolver();
6921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mUiccController = UiccController.getInstance();
6931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mUiccController.registerForIccChanged(this, DctConstants.EVENT_ICC_CHANGED, null);
6941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mAlarmManager =
6951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
6961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mCm = (ConnectivityManager) mPhone.getContext().getSystemService(
6971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Context.CONNECTIVITY_SERVICE);
6981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        IntentFilter filter = new IntentFilter();
7011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(Intent.ACTION_SCREEN_ON);
7021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(Intent.ACTION_SCREEN_OFF);
7031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
7041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
7051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(INTENT_DATA_STALL_ALARM);
7061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(INTENT_PROVISIONING_APN_ALARM);
7071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // TODO - redundent with update call below?
7091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mUserDataEnabled = getDataEnabled();
7101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
7121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
7141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mAutoAttachOnCreation.set(sp.getBoolean(Phone.DATA_DISABLED_ON_BOOT_KEY, false));
7151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mSubscriptionManager = SubscriptionManager.from(mPhone.getContext());
7171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
7181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        HandlerThread dcHandlerThread = new HandlerThread("DcHandlerThread");
7201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        dcHandlerThread.start();
7211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Handler dcHandler = new Handler(dcHandlerThread.getLooper());
7221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcc = DcController.makeDcc(mPhone, this, dcHandler);
7231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcTesterFailBringUpAll = new DcTesterFailBringUpAll(mPhone, dcHandler);
724cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
725cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mDataConnectionTracker = this;
726c374098c17a81f73f51e9d7df99eba574882949bYifan Bai        registerForAllEvents();
727a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        update();
728cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mApnObserver = new ApnChangeObserver();
7291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        phone.getContext().getContentResolver().registerContentObserver(
730cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                Telephony.Carriers.CONTENT_URI, true, mApnObserver);
731cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
732d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        initApnContexts();
733d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
734d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        for (ApnContext apnContext : mApnContexts.values()) {
735d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            // Register the reconnect and restart actions.
7361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            filter = new IntentFilter();
737d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            filter.addAction(INTENT_RECONNECT_ALARM + '.' + apnContext.getApnType());
738d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
739d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        }
740d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
74176f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Add Emergency APN to APN setting list by default to support EPDN in sim absent cases
74276f43316a5a6082d601bffd4b6898d0bd81e11fcram        initEmergencyApnSetting();
74376f43316a5a6082d601bffd4b6898d0bd81e11fcram        addEmergencyApnSetting();
744b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
7451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisionActionName = "com.android.internal.telephony.PROVISION" + phone.getPhoneId();
746f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
747f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver = new SettingsObserver(mPhone.getContext(), this);
748f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        registerSettingsObserver();
7491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
7501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
751af5593594070f825032be46dced573cd195956e1Robert Greenwalt    @VisibleForTesting
752af5593594070f825032be46dced573cd195956e1Robert Greenwalt    public DcTracker() {
753af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mAlarmManager = null;
754af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mCm = null;
755af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mPhone = null;
756af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mUiccController = null;
757af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mDataConnectionTracker = null;
758af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mProvisionActionName = null;
759f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver = new SettingsObserver(null, this);
760af5593594070f825032be46dced573cd195956e1Robert Greenwalt    }
761af5593594070f825032be46dced573cd195956e1Robert Greenwalt
7621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void registerServiceStateTrackerEvents() {
7631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataConnectionAttached(this,
7641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null);
7651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataConnectionDetached(this,
7661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_DATA_CONNECTION_DETACHED, null);
7671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataRoamingOn(this,
7681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_ROAMING_ON, null);
7691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataRoamingOff(this,
7701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_ROAMING_OFF, null);
7711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForPsRestrictedEnabled(this,
7721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_PS_RESTRICT_ENABLED, null);
7731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForPsRestrictedDisabled(this,
7741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_PS_RESTRICT_DISABLED, null);
7751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(this,
7761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_DATA_RAT_CHANGED, null);
777cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
778c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
7791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void unregisterServiceStateTrackerEvents() {
7801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataConnectionAttached(this);
7811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataConnectionDetached(this);
7821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataRoamingOn(this);
7831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataRoamingOff(this);
7841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForPsRestrictedEnabled(this);
7851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForPsRestrictedDisabled(this);
7861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged(this);
7871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
7881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void registerForAllEvents() {
790a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.mCi.registerForAvailable(this, DctConstants.EVENT_RADIO_AVAILABLE, null);
791a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.mCi.registerForOffOrNotAvailable(this,
7929c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
793a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.mCi.registerForDataNetworkStateChanged(this,
7949c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                DctConstants.EVENT_DATA_STATE_CHANGED, null);
7950710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // Note, this is fragile - the Phone is now presenting a merged picture
7960710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // of PS (volte) & CS and by diving into its internals you're just seeing
7970710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // the CS data.  This works well for the purposes this is currently used for
7980710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // but that may not always be the case.  Should probably be redesigned to
7990710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // accurately reflect what we're really interested in (registerForCSVoiceCallEnded).
8001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getCallTracker().registerForVoiceCallEnded(this,
8011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_VOICE_CALL_ENDED, null);
8021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getCallTracker().registerForVoiceCallStarted(this,
8031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_VOICE_CALL_STARTED, null);
8041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        registerServiceStateTrackerEvents();
805a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     //   SubscriptionManager.registerForDdsSwitch(this,
806a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     //          DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS, null);
807a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
8081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
809cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void dispose() {
8101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("DCT.dispose");
8114dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt
812b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        if (mProvisionBroadcastReceiver != null) {
813b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            mPhone.getContext().unregisterReceiver(mProvisionBroadcastReceiver);
814b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            mProvisionBroadcastReceiver = null;
815b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
8162b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        if (mProvisioningSpinner != null) {
8172b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.dismiss();
8182b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner = null;
8192b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        }
820b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
821cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, null);
822cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
8231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
8241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            dcac.disconnect();
8251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
8261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDataConnectionAcHashMap.clear();
8271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mIsDisposed = true;
8281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getContext().unregisterReceiver(mIntentReceiver);
8291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mUiccController.unregisterForIccChanged(this);
830f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        mSettingsObserver.unobserve();
831f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
8321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mSubscriptionManager
8331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                .removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
8341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcc.dispose();
8351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcTesterFailBringUpAll.dispose();
836cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
837a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getContext().getContentResolver().unregisterContentObserver(mApnObserver);
838a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mApnContexts.clear();
839af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mApnContextsById.clear();
840a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPrioritySortedApnContexts.clear();
841c374098c17a81f73f51e9d7df99eba574882949bYifan Bai        unregisterForAllEvents();
842a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
843a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        destroyDataConnections();
844a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
8451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void unregisterForAllEvents() {
847a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         //Unregister for all events
84822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.unregisterForAvailable(this);
84922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.unregisterForOffOrNotAvailable(this);
850cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
851a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (r != null) {
852a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            r.unregisterForRecordsLoaded(this);
853a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mIccRecords.set(null);
854a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
85522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.unregisterForDataNetworkStateChanged(this);
856cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getCallTracker().unregisterForVoiceCallEnded(this);
857cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getCallTracker().unregisterForVoiceCallStarted(this);
8581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        unregisterServiceStateTrackerEvents();
859a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        //SubscriptionManager.unregisterForDdsSwitch(this);
860cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
861cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
8621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
8631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Called when EVENT_RESET_DONE is received so goto
8641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * IDLE state and send notifications to those interested.
8651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     *
8661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * TODO - currently unused.  Needs to be hooked into DataConnection cleanup
8671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * TODO - needs to pass some notion of which connection is reset..
8681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
8691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onResetDone(AsyncResult ar) {
8701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("EVENT_RESET_DONE");
8711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        String reason = null;
8721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (ar.userObj instanceof String) {
8731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            reason = (String) ar.userObj;
8741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
8751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        gotoIdleAndNotifyDataConnection(reason);
8761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
8771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
8791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Modify {@link android.provider.Settings.Global#MOBILE_DATA} value.
8801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
8811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void setDataEnabled(boolean enable) {
8821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.CMD_SET_USER_DATA_ENABLE);
8831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = enable ? 1 : 0;
8841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("setDataEnabled: sendMessage: enable=" + enable);
8851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
8861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
8871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetUserDataEnabled(boolean enabled) {
8891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        synchronized (mDataEnabledLock) {
8901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mUserDataEnabled != enabled) {
8911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mUserDataEnabled = enabled;
8921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // For single SIM phones, this is a per phone property.
8941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (TelephonyManager.getDefault().getSimCount() == 1) {
8951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    Settings.Global.putInt(mResolver, Settings.Global.MOBILE_DATA, enabled ? 1 : 0);
8961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
8971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    int phoneSubId = mPhone.getSubId();
8981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    Settings.Global.putInt(mResolver, Settings.Global.MOBILE_DATA + phoneSubId,
8991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            enabled ? 1 : 0);
9001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
9011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (getDataOnRoamingEnabled() == false &&
9021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mPhone.getServiceState().getDataRoaming() == true) {
9031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (enabled) {
9041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
9051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
9061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        notifyOffApnsOfAvailability(Phone.REASON_DATA_DISABLED);
9071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
9081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
9091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
9101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (enabled) {
9111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onTrySetupData(Phone.REASON_DATA_ENABLED);
9121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
9131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);
9141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
9151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
9161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
9171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
9181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
919f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    private void onDeviceProvisionedChange() {
920f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        if (getDataEnabled()) {
92180d38fe5c8f18997623b1133e4650c4a9a6e299cRobert Greenwalt            mUserDataEnabled = true;
922f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            onTrySetupData(Phone.REASON_DATA_ENABLED);
923f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        } else {
92480d38fe5c8f18997623b1133e4650c4a9a6e299cRobert Greenwalt            mUserDataEnabled = false;
925f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);
926f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        }
927f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt    }
9281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
9291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
9301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public long getSubId() {
9311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mPhone.getSubId();
9321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
9331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
9341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public DctConstants.Activity getActivity() {
9351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mActivity;
9361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
9371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
9381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void setActivity(DctConstants.Activity activity) {
9391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("setActivity = " + activity);
9401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mActivity = activity;
9411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.notifyDataActivity();
9421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
9431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
944af5593594070f825032be46dced573cd195956e1Robert Greenwalt    public void requestNetwork(NetworkRequest networkRequest, LocalLog log) {
945af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final int apnId = ApnContext.apnIdForNetworkRequest(networkRequest);
946af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final ApnContext apnContext = mApnContextsById.get(apnId);
947af5593594070f825032be46dced573cd195956e1Robert Greenwalt        log.log("DcTracker.requestNetwork for " + networkRequest + " found " + apnContext);
948af5593594070f825032be46dced573cd195956e1Robert Greenwalt        if (apnContext != null) apnContext.incRefCount(log);
949af5593594070f825032be46dced573cd195956e1Robert Greenwalt    }
950af5593594070f825032be46dced573cd195956e1Robert Greenwalt
951af5593594070f825032be46dced573cd195956e1Robert Greenwalt    public void releaseNetwork(NetworkRequest networkRequest, LocalLog log) {
952af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final int apnId = ApnContext.apnIdForNetworkRequest(networkRequest);
953af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final ApnContext apnContext = mApnContextsById.get(apnId);
954af5593594070f825032be46dced573cd195956e1Robert Greenwalt        log.log("DcTracker.releaseNetwork for " + networkRequest + " found " + apnContext);
955af5593594070f825032be46dced573cd195956e1Robert Greenwalt        if (apnContext != null) apnContext.decRefCount(log);
956af5593594070f825032be46dced573cd195956e1Robert Greenwalt    }
957af5593594070f825032be46dced573cd195956e1Robert Greenwalt
958bda761320929f714951c328bfec6a51a1978db97Wink Saville    public boolean isApnSupported(String name) {
95991bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal        if (name == null) {
96091bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal            loge("isApnSupported: name=null");
96191bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal            return false;
96291bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal        }
963bda761320929f714951c328bfec6a51a1978db97Wink Saville        ApnContext apnContext = mApnContexts.get(name);
964bda761320929f714951c328bfec6a51a1978db97Wink Saville        if (apnContext == null) {
965bda761320929f714951c328bfec6a51a1978db97Wink Saville            loge("Request for unsupported mobile name: " + name);
966bda761320929f714951c328bfec6a51a1978db97Wink Saville            return false;
967071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
968bda761320929f714951c328bfec6a51a1978db97Wink Saville        return true;
969bda761320929f714951c328bfec6a51a1978db97Wink Saville    }
970071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
971a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    /**
972a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu     * Called when there is any change to any SubscriptionInfo Typically
973a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu     * this method invokes {@link SubscriptionManager#getActiveSubscriptionInfoList}
974a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu     */
975a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    private boolean isColdSimDetected(int subId) {
976a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        final SubscriptionInfo subInfo = mSubscriptionManager.getActiveSubscriptionInfo(subId);
977a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        if (subInfo != null) {
978a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            final int simProvisioningStatus = subInfo.getSimProvisioningStatus();
979a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            if(simProvisioningStatus == SubscriptionManager.SIM_UNPROVISIONED_COLD) {
980a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                log("Cold Sim Detected on SubId: " + subId);
981a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                return true;
982a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            }
983a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        }
984a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        return false;
985a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    }
986a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
987bda761320929f714951c328bfec6a51a1978db97Wink Saville    public int getApnPriority(String name) {
988071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        ApnContext apnContext = mApnContexts.get(name);
989071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (apnContext == null) {
990bda761320929f714951c328bfec6a51a1978db97Wink Saville            loge("Request for unsupported mobile name: " + name);
991071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
992bda761320929f714951c328bfec6a51a1978db97Wink Saville        return apnContext.priority;
993071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt    }
994071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
995b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    // Turn telephony radio on or off.
996b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private void setRadio(boolean on) {
997b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        final ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
998b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        try {
999b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            phone.setRadio(on);
1000b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        } catch (Exception e) {
1001b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            // Ignore.
1002b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
1003b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    }
1004b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
1005b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    // Class to handle Intent dispatched with user selects the "Sign-in to network"
1006b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    // notification.
1007b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private class ProvisionNotificationBroadcastReceiver extends BroadcastReceiver {
10082b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        private final String mNetworkOperator;
1009b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        // Mobile provisioning URL.  Valid while provisioning notification is up.
1010b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        // Set prior to notification being posted as URL contains ICCID which
1011b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        // disappears when radio is off (which is the case when notification is up).
1012b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        private final String mProvisionUrl;
1013b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
10142b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        public ProvisionNotificationBroadcastReceiver(String provisionUrl, String networkOperator) {
10152b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mNetworkOperator = networkOperator;
1016b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            mProvisionUrl = provisionUrl;
1017b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
1018b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
1019b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        private void setEnableFailFastMobileData(int enabled) {
10206395443719ec3ee0257085945e753d02f603886bRobert Greenwalt            sendMessage(obtainMessage(DctConstants.CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA, enabled, 0));
1021b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
1022b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
1023b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        private void enableMobileProvisioning() {
1024b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            final Message msg = obtainMessage(DctConstants.CMD_ENABLE_MOBILE_PROVISIONING);
1025b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            msg.setData(Bundle.forPair(DctConstants.PROVISIONING_URL_KEY, mProvisionUrl));
1026b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            sendMessage(msg);
1027b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
1028b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
1029b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        @Override
1030b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        public void onReceive(Context context, Intent intent) {
10312b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // Turning back on the radio can take time on the order of a minute, so show user a
10322b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // spinner so they know something is going on.
10332b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner = new ProgressDialog(context);
10342b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setTitle(mNetworkOperator);
10352b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setMessage(
10362b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    // TODO: Don't borrow "Connecting..." i18n string; give Telephony a version.
10372b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    context.getText(com.android.internal.R.string.media_route_status_connecting));
10382b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setIndeterminate(true);
10392b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setCancelable(true);
10402b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // Allow non-Activity Service Context to create a View.
10412b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.getWindow().setType(
10422b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
10432b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.show();
10442b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // After timeout, hide spinner so user can at least use their device.
10452b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // TODO: Indicate to user that it is taking an unusually long time to connect?
10462b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            sendMessageDelayed(obtainMessage(DctConstants.CMD_CLEAR_PROVISIONING_SPINNER,
10472b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner), PROVISIONING_SPINNER_TIMEOUT_MILLIS);
1048b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            // This code is almost identical to the old
1049b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            // ConnectivityService.handleMobileProvisioningAction code.
1050b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            setRadio(true);
1051b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            setEnableFailFastMobileData(DctConstants.ENABLED);
1052b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            enableMobileProvisioning();
1053b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
1054b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    }
1055b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
1056cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isApnTypeActive(String type) {
1057cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(type);
1058cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) return false;
1059cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1060ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        return (apnContext.getDcAc() != null);
1061cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1062cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1063cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isDataPossible(String apnType) {
1064cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1065cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
1066cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
1067cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1068cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean apnContextIsEnabled = apnContext.isEnabled();
1069cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        DctConstants.State apnContextState = apnContext.getState();
1070cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean apnTypePossible = !(apnContextIsEnabled &&
1071cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                (apnContextState == DctConstants.State.FAILED));
1072cf5205f70eb1eac497164124187a088ecb03fff5Ram        boolean isEmergencyApn = apnContext.getApnType().equals(PhoneConstants.APN_TYPE_EMERGENCY);
1073cf5205f70eb1eac497164124187a088ecb03fff5Ram        // Set the emergency APN availability status as TRUE irrespective of conditions checked in
1074cf5205f70eb1eac497164124187a088ecb03fff5Ram        // isDataAllowed() like IN_SERVICE, MOBILE DATA status etc.
10759c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        boolean dataAllowed = isEmergencyApn || isDataAllowed(null);
1076cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean possible = dataAllowed && apnTypePossible;
1077cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
10780e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        if ((apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
10790e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                    || apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IA))
10800e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                && (mPhone.getServiceState().getRilDataRadioTechnology()
10810e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN)) {
10820e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            log("Default data call activation not possible in iwlan.");
10830e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            possible = false;
10840e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        }
10850e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh
1086ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (VDBG) {
1087cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log(String.format("isDataPossible(%s): possible=%b isDataAllowed=%b " +
1088a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                            "apnTypePossible=%b apnContextisEnabled=%b apnContextState()=%s",
1089cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnType, possible, dataAllowed, apnTypePossible,
1090cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContextIsEnabled, apnContextState));
1091cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1092cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return possible;
1093cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1094cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1095cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1096cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void finalize() {
1097cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(DBG) log("finalize");
1098cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1099cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
11004a9b3afeb2ec4d573eca335a3706392ecf9f281eWink Saville    private ApnContext addApnContext(String type, NetworkConfig networkConfig) {
11010e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        ApnContext apnContext = new ApnContext(mPhone, type, LOG_TAG, networkConfig, this);
1102cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mApnContexts.put(type, apnContext);
1103af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mApnContextsById.put(ApnContext.apnIdForApnName(type), apnContext);
11043fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        mPrioritySortedApnContexts.add(apnContext);
1105bce3d2575122929bb27ec8a37d56e96da39a3ca2Robert Greenwalt        return apnContext;
1106cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1107c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
11081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void initApnContexts() {
1109d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        log("initApnContexts: E");
1110d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        // Load device network attributes from resources
1111d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        String[] networkConfigStrings = mPhone.getContext().getResources().getStringArray(
1112d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                com.android.internal.R.array.networkAttributes);
1113d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        for (String networkConfigString : networkConfigStrings) {
1114d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            NetworkConfig networkConfig = new NetworkConfig(networkConfigString);
1115d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            ApnContext apnContext = null;
1116d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
1117d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            switch (networkConfig.type) {
1118d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE:
1119d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_DEFAULT, networkConfig);
1120d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1121d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_MMS:
1122d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_MMS, networkConfig);
1123d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1124d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_SUPL:
1125d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_SUPL, networkConfig);
1126d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1127d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_DUN:
1128d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_DUN, networkConfig);
1129d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1130d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_HIPRI:
1131d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_HIPRI, networkConfig);
1132d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1133d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_FOTA:
1134d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_FOTA, networkConfig);
1135d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1136d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_IMS:
1137d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_IMS, networkConfig);
1138d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1139d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_CBS:
1140d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_CBS, networkConfig);
1141d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1142d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_IA:
1143d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_IA, networkConfig);
1144d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1145cf5205f70eb1eac497164124187a088ecb03fff5Ram            case ConnectivityManager.TYPE_MOBILE_EMERGENCY:
1146cf5205f70eb1eac497164124187a088ecb03fff5Ram                apnContext = addApnContext(PhoneConstants.APN_TYPE_EMERGENCY, networkConfig);
1147cf5205f70eb1eac497164124187a088ecb03fff5Ram                break;
1148d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            default:
1149d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                log("initApnContexts: skipping unknown type=" + networkConfig.type);
1150d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                continue;
1151d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            }
1152d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            log("initApnContexts: apnContext=" + apnContext);
1153d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        }
1154092e6bd60f1a4a3a55fb73ad0efca1122b8e15e2Jack Yu
1155092e6bd60f1a4a3a55fb73ad0efca1122b8e15e2Jack Yu        if (VDBG) log("initApnContexts: X mApnContexts=" + mApnContexts);
1156d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt    }
1157d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
1158cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public LinkProperties getLinkProperties(String apnType) {
1159cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1160cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
1161454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = apnContext.getDcAc();
1162cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac != null) {
1163cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("return link properites for " + apnType);
1164cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return dcac.getLinkPropertiesSync();
1165cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1166cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1167cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("return new LinkProperties");
1168cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return new LinkProperties();
1169cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1170cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1171608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt    public NetworkCapabilities getNetworkCapabilities(String apnType) {
1172608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        ApnContext apnContext = mApnContexts.get(apnType);
1173608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        if (apnContext!=null) {
1174608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            DcAsyncChannel dataConnectionAc = apnContext.getDcAc();
1175608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            if (dataConnectionAc != null) {
1176608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                if (DBG) {
1177608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                    log("get active pdp is not null, return NetworkCapabilities for " + apnType);
1178608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                }
1179608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                return dataConnectionAc.getNetworkCapabilitiesSync();
1180608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            }
1181608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        }
1182608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        if (DBG) log("return new NetworkCapabilities");
1183608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        return new NetworkCapabilities();
1184608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt    }
1185cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1186cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return all active apn types
1187cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public String[] getActiveApnTypes() {
1188cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("get all active apn types");
1189cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ArrayList<String> result = new ArrayList<String>();
1190cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1191cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1192187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (mAttached.get() && apnContext.isReady()) {
1193cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                result.add(apnContext.getApnType());
1194cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
1195cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1196c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1197cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result.toArray(new String[0]);
1198cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1199cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1200cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return active apn of specific apn type
1201cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public String getActiveApnString(String apnType) {
1202ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (VDBG) log( "get active apn string for type:" + apnType);
1203cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1204cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
1205cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ApnSetting apnSetting = apnContext.getApnSetting();
1206cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnSetting != null) {
1207cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return apnSetting.apn;
1208cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1209cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1210cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
1211cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1212cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1213cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isApnTypeEnabled(String apnType) {
1214cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1215cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
1216cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
1217cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1218cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return apnContext.isEnabled();
1219cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1220cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
12211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void setState(DctConstants.State s) {
1222cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setState should not be used in GSM" + s);
1223cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1224cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1225cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return state of specific apn type
1226cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public DctConstants.State getState(String apnType) {
1227cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1228cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
1229cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return apnContext.getState();
1230c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1231cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return DctConstants.State.FAILED;
1232cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1233c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1234c9b81a0c05128694c617fcdd67e73821895822feWink Saville    // Return if apn type is a provisioning apn.
12351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean isProvisioningApn(String apnType) {
1236c9b81a0c05128694c617fcdd67e73821895822feWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1237c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (apnContext != null) {
1238c9b81a0c05128694c617fcdd67e73821895822feWink Saville            return apnContext.isProvisioningApn();
1239c9b81a0c05128694c617fcdd67e73821895822feWink Saville        }
1240c9b81a0c05128694c617fcdd67e73821895822feWink Saville        return false;
1241c9b81a0c05128694c617fcdd67e73821895822feWink Saville    }
1242c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1243cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return state of overall
1244cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public DctConstants.State getOverallState() {
1245cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isConnecting = false;
1246cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isFailed = true; // All enabled Apns should be FAILED.
1247cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isAnyEnabled = false;
1248cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1249cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1250cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.isEnabled()) {
1251cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                isAnyEnabled = true;
1252cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                switch (apnContext.getState()) {
1253cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case CONNECTED:
1254cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case DISCONNECTING:
12551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (VDBG) log("overall state is CONNECTED");
1256cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return DctConstants.State.CONNECTED;
1257ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                case RETRYING:
1258cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case CONNECTING:
1259cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isConnecting = true;
1260cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isFailed = false;
1261cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
1262cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case IDLE:
1263cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case SCANNING:
1264cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isFailed = false;
1265cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
1266cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                default:
1267cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isAnyEnabled = true;
1268cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
1269cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1270cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1271c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1272c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1273cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (!isAnyEnabled) { // Nothing enabled. return IDLE.
12741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is IDLE");
1275cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.IDLE;
1276c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1277c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1278cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnecting) {
12791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is CONNECTING");
1280cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.CONNECTING;
1281cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (!isFailed) {
12821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is IDLE");
1283cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.IDLE;
1284cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
12851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is FAILED");
1286cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.FAILED;
1287c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1288c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1289c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1290cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1291cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Report on whether data connectivity is enabled for any APN.
1292cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return {@code false} if data connectivity has been explicitly disabled,
1293cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * {@code true} otherwise.
1294cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1295cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean getAnyDataEnabled() {
12963d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!isDataEnabled(true)) return false;
12973d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        DataAllowFailReason failureReason = new DataAllowFailReason();
12983d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!isDataAllowed(failureReason)) {
12993d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if (DBG) log(failureReason.getDataAllowFailReason());
1300cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
1301c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
13023d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        for (ApnContext apnContext : mApnContexts.values()) {
13033d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            // Make sure we don't have a context that is going down
13043d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            // and is explicitly disabled.
13053d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if (isDataAllowedForApn(apnContext)) {
13063d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                return true;
13073d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            }
13083d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13093d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        return false;
1310c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1311c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1312a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean getAnyDataEnabled(boolean checkUserDataEnabled) {
13133d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!isDataEnabled(checkUserDataEnabled)) return false;
13143d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
13153d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        DataAllowFailReason failureReason = new DataAllowFailReason();
13163d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!isDataAllowed(failureReason)) {
13173d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if (DBG) log(failureReason.getDataAllowFailReason());
13183d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            return false;
13193d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13203d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        for (ApnContext apnContext : mApnContexts.values()) {
13213d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            // Make sure we dont have a context that going down
13223d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            // and is explicitly disabled.
13233d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if (isDataAllowedForApn(apnContext)) {
13243d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                return true;
13253d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            }
13263d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
13273d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        return false;
13283d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu    }
13293d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
13303d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu    private boolean isDataEnabled(boolean checkUserDataEnabled) {
1331a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        synchronized (mDataEnabledLock) {
1332a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (!(mInternalDataEnabled && (!checkUserDataEnabled || mUserDataEnabled)
13333d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                    && (!checkUserDataEnabled || sPolicyDataEnabled)))
13349c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                return false;
1335a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
13363d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        return true;
1337a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1338a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
13399c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu    private boolean isDataAllowedForApn(ApnContext apnContext) {
13400e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        //If RAT is iwlan then dont allow default/IA PDP at all.
13410e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        //Rest of APN types can be evaluated for remaining conditions.
13420e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        if ((apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
13430e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                    || apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IA))
13440e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                && (mPhone.getServiceState().getRilDataRadioTechnology()
13450e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN)) {
13460e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            log("Default data call activation not allowed in iwlan.");
13470e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            return false;
13480e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        }
13499c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu
13509c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        return apnContext.isReady();
1351c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1352c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1353cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //****** Called from ServiceStateTracker
1354c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1355cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Invoked when ServiceStateTracker observes a transition from GPRS
1356cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * attach to detach.
1357c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
13581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataConnectionDetached() {
1359cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        /*
1360cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * We presently believe it is unnecessary to tear down the PDP context
1361cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * when GPRS detaches, but we should stop the network polling.
1362cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         */
1363cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log ("onDataConnectionDetached: stop polling and notify detached");
1364cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopNetStatPoll();
1365cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopDataStallAlarm();
1366cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyDataConnection(Phone.REASON_DATA_DETACHED);
1367187a39f896f88eb6c5e4306d9595546654825976Wink Saville        mAttached.set(false);
1368cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1369c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1370cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onDataConnectionAttached() {
1371cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onDataConnectionAttached");
13727ab10e4710bdb54c6d9a5ee01cd443a42a2689f5Sungmin Choi        mAttached.set(true);
1373cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getOverallState() == DctConstants.State.CONNECTED) {
1374cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onDataConnectionAttached: start polling notify attached");
1375cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            startNetStatPoll();
1376cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
1377cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_DATA_ATTACHED);
1378cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1379cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // update APN availability so that APN can be enabled.
1380cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_DATA_ATTACHED);
1381cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
138212fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        if (mAutoAttachOnCreationConfig) {
1383aacc11b299ac047e73e1e712aa396ea0a6a80158Robert Greenwalt            mAutoAttachOnCreation.set(true);
138412fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        }
1385ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(Phone.REASON_DATA_ATTACHED);
1386cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1387c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
13883d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu    private boolean isDataAllowed(DataAllowFailReason failureReason) {
1389cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        final boolean internalDataEnabled;
1390cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        synchronized (mDataEnabledLock) {
1391cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            internalDataEnabled = mInternalDataEnabled;
1392cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1393cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
13949894b3fb2f35e21d9cfd45f233ed093589e14c26sy.yun        boolean attachedState = mAttached.get();
1395cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
13960e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
13970e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        if (radioTech == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN) {
13980e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            desiredPowerState = true;
13990e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        }
14000e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh
1401cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
14022b0f0da4f9fe8449c578632b491e2f158c201bd5Stuart Scott        boolean recordsLoaded = false;
14032b0f0da4f9fe8449c578632b491e2f158c201bd5Stuart Scott        if (r != null) {
14042b0f0da4f9fe8449c578632b491e2f158c201bd5Stuart Scott            recordsLoaded = r.getRecordsLoaded();
14059232dafa7ea833fc0b3a6024d6c7e23fc8e961eaRobert Greenwalt            if (DBG && !recordsLoaded) log("isDataAllowed getRecordsLoaded=" + recordsLoaded);
14062b0f0da4f9fe8449c578632b491e2f158c201bd5Stuart Scott        }
1407cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
140838ca51d0f643405df51e78fce6c546424e9f410dShishir Agrawal        int dataSub = SubscriptionManager.getDefaultDataSubscriptionId();
1409434fa420329b093f68d83862a637c7ded93a4dafCraig Lafayette        boolean defaultDataSelected = SubscriptionManager.isValidSubscriptionId(dataSub);
14103d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
1411b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com        PhoneConstants.State state = PhoneConstants.State.IDLE;
14120710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // Note this is explicitly not using mPhone.getState.  See b/19090488.
14130710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // mPhone.getState reports the merge of CS and PS (volte) voice call state
14140710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // but we only care about CS calls here for data/voice concurrency issues.
14150710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // Calling getCallTracker currently gives you just the CS side where the
14160710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // ImsCallTracker is held internally where applicable.
14170710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // This should be redesigned to ask explicitly what we want:
14180710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // voiceCallStateAllowDataCall, or dataCallAllowed or something similar.
1419b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com        if (mPhone.getCallTracker() != null) {
1420b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com            state = mPhone.getCallTracker().getState();
1421b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com        }
14221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
14233d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (failureReason != null) failureReason.clearAllReasons();
14243d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!(attachedState || mAutoAttachOnCreation.get())) {
14253d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if(failureReason == null) return false;
14263d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            failureReason.addDataAllowFailReason(DataAllowFailReasonType.NOT_ATTACHED);
14273d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
14283d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!recordsLoaded) {
14293d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if(failureReason == null) return false;
14303d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            failureReason.addDataAllowFailReason(DataAllowFailReasonType.RECORD_NOT_LOADED);
14313d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
14323d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (state != PhoneConstants.State.IDLE &&
14333d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
14343d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if(failureReason == null) return false;
14353d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            failureReason.addDataAllowFailReason(DataAllowFailReasonType.INVALID_PHONE_STATE);
14363d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            failureReason.addDataAllowFailReason(
14373d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                    DataAllowFailReasonType.CONCURRENT_VOICE_DATA_NOT_ALLOWED);
14383d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
14393d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!internalDataEnabled) {
14403d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if(failureReason == null) return false;
14413d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            failureReason.addDataAllowFailReason(DataAllowFailReasonType.INTERNAL_DATA_DISABLED);
14423d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
14433d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!defaultDataSelected) {
14443d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if(failureReason == null) return false;
14453d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            failureReason.addDataAllowFailReason(
14463d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                    DataAllowFailReasonType.DEFAULT_DATA_UNSELECTED);
14473d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
14483d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (mPhone.getServiceState().getDataRoaming() && !getDataOnRoamingEnabled()) {
14493d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if(failureReason == null) return false;
14503d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            failureReason.addDataAllowFailReason(DataAllowFailReasonType.ROAMING_DISABLED);
1451c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
14523d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (mIsPsRestricted) {
14533d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if(failureReason == null) return false;
14543d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            failureReason.addDataAllowFailReason(DataAllowFailReasonType.PS_RESTRICTED);
14553d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
14563d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        if (!desiredPowerState) {
14573d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if(failureReason == null) return false;
14583d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            failureReason.addDataAllowFailReason(DataAllowFailReasonType.UNDESIRED_POWER_STATE);
14593d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        }
14603d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
14613d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        return failureReason == null || !failureReason.isFailed();
1462cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1463c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1464c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    // arg for setupDataOnConnectableApns
1465c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    private enum RetryFailures {
1466c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        // retry failed networks always (the old default)
1467c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        ALWAYS,
14680e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        // retry only when a substantial change has occurred.  Either:
1469c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        // 1) we were restricted by voice/data concurrency and aren't anymore
1470c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        // 2) our apn list has change
1471c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        ONLY_ON_CHANGE
1472c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    };
1473c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt
1474ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void setupDataOnConnectableApns(String reason) {
1475c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        setupDataOnConnectableApns(reason, RetryFailures.ALWAYS);
1476c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    }
1477c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt
1478c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    private void setupDataOnConnectableApns(String reason, RetryFailures retryFailures) {
14799c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        if (VDBG) log("setupDataOnConnectableApns: " + reason);
14803fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
1481c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu        if (DBG && !VDBG) {
1482c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            StringBuilder sb = new StringBuilder(120);
1483c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            for (ApnContext apnContext : mPrioritySortedApnContexts) {
1484c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(apnContext.getApnType());
1485c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(":[state=");
1486c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(apnContext.getState());
1487c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(",enabled=");
1488c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(apnContext.isEnabled());
1489c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append("] ");
1490c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            }
14919c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            log("setupDataOnConnectableApns: " + reason + " " + sb);
1492c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu        }
1493c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu
14943fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        for (ApnContext apnContext : mPrioritySortedApnContexts) {
1495735bc2f4524d68155765351912ffae11306c3bd5Chris Manton            ArrayList<ApnSetting> waitingApns = null;
1496735bc2f4524d68155765351912ffae11306c3bd5Chris Manton
1497c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            if (VDBG) log("setupDataOnConnectableApns: apnContext " + apnContext);
1498c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu
1499735bc2f4524d68155765351912ffae11306c3bd5Chris Manton            if (apnContext.getState() == DctConstants.State.FAILED
15000e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                    || apnContext.getState() == DctConstants.State.SCANNING) {
1501c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                if (retryFailures == RetryFailures.ALWAYS) {
1502ee665b78ad648abd98b019a9c9047f206ed22994Robert Greenwalt                    apnContext.releaseDataConnection(reason);
1503c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                } else if (apnContext.isConcurrentVoiceAndDataAllowed() == false &&
15040e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                        mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
1505c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    // RetryFailures.ONLY_ON_CHANGE - check if voice concurrency has changed
1506ee665b78ad648abd98b019a9c9047f206ed22994Robert Greenwalt                    apnContext.releaseDataConnection(reason);
1507c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                } else {
1508c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    // RetryFailures.ONLY_ON_CHANGE - check if the apns have changed
1509c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
15100e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                    ArrayList<ApnSetting> originalApns = apnContext.getWaitingApns();
1511c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    if (originalApns != null && originalApns.isEmpty() == false) {
1512c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                        waitingApns = buildWaitingApns(apnContext.getApnType(), radioTech);
1513c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                        if (originalApns.size() != waitingApns.size() ||
1514c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                                originalApns.containsAll(waitingApns) == false) {
1515ee665b78ad648abd98b019a9c9047f206ed22994Robert Greenwalt                            apnContext.releaseDataConnection(reason);
1516b290ce3d172215e5ab7cd43c8e7bbee9551ab29eRobert Greenwalt                        } else {
1517b290ce3d172215e5ab7cd43c8e7bbee9551ab29eRobert Greenwalt                            continue;
1518c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                        }
1519b290ce3d172215e5ab7cd43c8e7bbee9551ab29eRobert Greenwalt                    } else {
1520b290ce3d172215e5ab7cd43c8e7bbee9551ab29eRobert Greenwalt                        continue;
1521c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    }
1522c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                }
1523cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1524ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.isConnectable()) {
15259c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                log("isConnectable() call trySetupData");
1526ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setReason(reason);
1527c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                trySetupData(apnContext, waitingApns);
1528cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1529cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1530c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1531c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
15321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    boolean isEmergency() {
15331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        final boolean result;
15341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        synchronized (mDataEnabledLock) {
15351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            result = mPhone.isInEcm() || mPhone.isInEmergencyCall();
15361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
15371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("isEmergency: result=" + result);
15381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return result;
15391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
15401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1541cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean trySetupData(ApnContext apnContext) {
1542c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        return trySetupData(apnContext, null);
1543c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    }
1544c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt
1545c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    private boolean trySetupData(ApnContext apnContext, ArrayList<ApnSetting> waitingApns) {
1546cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
1547cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("trySetupData for type:" + apnContext.getApnType() +
15489c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                    " due to " + apnContext.getReason() + ", mIsPsRestricted=" + mIsPsRestricted);
1549cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
15502dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog("trySetupData due to " + apnContext.getReason());
1551cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1552cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
1553cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
1554cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
1555cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setState(DctConstants.State.CONNECTED);
1556cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1557cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1558cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("trySetupData: X We're on the simulator; assuming connected retValue=true");
1559cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return true;
1560cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1561cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1562cf5205f70eb1eac497164124187a088ecb03fff5Ram        // Allow SETUP_DATA request for E-APN to be completed during emergency call
1563cf5205f70eb1eac497164124187a088ecb03fff5Ram        // and MOBILE DATA On/Off cases as well.
1564cf5205f70eb1eac497164124187a088ecb03fff5Ram        boolean isEmergencyApn = apnContext.getApnType().equals(PhoneConstants.APN_TYPE_EMERGENCY);
1565c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        final ServiceStateTracker sst = mPhone.getServiceStateTracker();
15660e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
1567783061ca03572618c01ce244d70d82fa4328d45ffionaxu        // set to false if apn type is non-metered.
1568a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean checkUserDataEnabled =
1569c77a3b8bdf96f1486753689898b04d9de325d8d8fionaxu                (ApnSetting.isMeteredApnType(apnContext.getApnType(), mPhone.getContext(),
15703d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                        mPhone.getSubId(), mPhone.getServiceState().getDataRoaming()));
15713d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
15723d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        DataAllowFailReason failureReason = new DataAllowFailReason();
15733d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
15743d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        // allow data if currently in roaming service, roaming setting disabled
15753d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        // and requested apn type is non-metered for roaming.
15763d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        boolean isDataAllowed = isDataAllowed(failureReason) ||
15773d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                (failureReason.isFailForSingleReason(DataAllowFailReasonType.ROAMING_DISABLED) &&
15783d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                !(ApnSetting.isMeteredApnType(apnContext.getApnType(), mPhone.getContext(),
15793d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                mPhone.getSubId(), mPhone.getServiceState().getDataRoaming())));
1580cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1581cf5205f70eb1eac497164124187a088ecb03fff5Ram        if (apnContext.isConnectable() && (isEmergencyApn ||
15823d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                (isDataAllowed && isDataAllowedForApn(apnContext) &&
15833d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                isDataEnabled(checkUserDataEnabled) && !isEmergency())) && !mColdSimDetected ) {
1584ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getState() == DctConstants.State.FAILED) {
15853d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                String str = "trySetupData: make a FAILED ApnContext IDLE so its reusable";
15862dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                if (DBG) log(str);
15872dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                apnContext.requestLog(str);
1588ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setState(DctConstants.State.IDLE);
1589ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1590203e588e3c42a81aa8a56f595119c181a63b12caWink Saville            int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
1591c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt            apnContext.setConcurrentVoiceAndDataAllowed(sst.isConcurrentVoiceAndDataAllowed());
1592cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.getState() == DctConstants.State.IDLE) {
1593c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                if (waitingApns == null) {
1594c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    waitingApns = buildWaitingApns(apnContext.getApnType(), radioTech);
1595c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                }
1596cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (waitingApns.isEmpty()) {
1597ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    notifyNoData(DcFailCause.MISSING_UNKNOWN_APN, apnContext);
1598cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    notifyOffApnsOfAvailability(apnContext.getReason());
15992dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    String str = "trySetupData: X No APN found retValue=false";
16002dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    if (DBG) log(str);
16012dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    apnContext.requestLog(str);
1602cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return false;
1603cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1604cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setWaitingApns(waitingApns);
1605cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) {
1606ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        log ("trySetupData: Create from mAllApnSettings : "
1607ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                    + apnListToString(mAllApnSettings));
1608cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1609cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1610cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1611cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1612203e588e3c42a81aa8a56f595119c181a63b12caWink Saville            boolean retValue = setupData(apnContext, radioTech);
1613cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(apnContext.getReason());
1614cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1615cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("trySetupData: X retValue=" + retValue);
1616cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return retValue;
1617cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1618cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
1619ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    && apnContext.isConnectable()) {
1620cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
1621ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1622cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(apnContext.getReason());
16232e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
16242e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            StringBuilder str = new StringBuilder();
16252e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
16262e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            str.append("trySetupData failed. apnContext = [type=" + apnContext.getApnType() +
16272e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu                    ", mState=" + apnContext.getState() + ", mDataEnabled=" +
16282e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu                    apnContext.isEnabled() + ", mDependencyMet=" +
16292e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu                    apnContext.getDependencyMet() + "] ");
16302e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
16312e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            if (!apnContext.isConnectable()) {
16322e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu                str.append("isConnectable = false. ");
16332dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt            }
16343d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if (!isDataAllowed) {
16353d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                str.append("data not allowed: " + failureReason.getDataAllowFailReason() + ". ");
16362e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            }
16372e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            if (!isDataAllowedForApn(apnContext)) {
16382e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu                str.append("isDataAllowedForApn = false. RAT = " +
16392e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu                        mPhone.getServiceState().getRilDataRadioTechnology());
16402e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            }
16413d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if (!isDataEnabled(checkUserDataEnabled)) {
16423d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                str.append("isDataEnabled(" + checkUserDataEnabled + ") = false. " +
16432e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu                        "mInternalDataEnabled = " + mInternalDataEnabled + " , mUserDataEnabled = "
16442e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu                        + mUserDataEnabled + ", sPolicyDataEnabled = " + sPolicyDataEnabled + " ");
16452e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            }
16462e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            if (isEmergency()) {
16472e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu                str.append("emergency = true");
16482e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            }
1649a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            if(mColdSimDetected) {
1650a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                str.append("coldSimDetected = true");
1651a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            }
16522e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
16532e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            if (DBG) log(str.toString());
16542e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu            apnContext.requestLog(str.toString());
16552e3470722434dbc91dcc2095f5a410f6aaad620aJack Yu
1656cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
1657cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1658c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1659c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
16600e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    // Disabled apn's still need avail/unavail notifications - send them out
16611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyOffApnsOfAvailability(String reason) {
16629c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        if (DBG) {
16633d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            DataAllowFailReason failureReason = new DataAllowFailReason();
16643d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if (!isDataAllowed(failureReason)) {
16653d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                log(failureReason.getDataAllowFailReason());
16669c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            }
16679c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        }
1668cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1669187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (!mAttached.get() || !apnContext.isReady()) {
1670ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) log("notifyOffApnOfAvailability type:" + apnContext.getApnType());
1671cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
1672cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                            apnContext.getApnType(),
1673cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                            PhoneConstants.DataState.DISCONNECTED);
1674cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1675ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) {
1676187a39f896f88eb6c5e4306d9595546654825976Wink Saville                    log("notifyOffApnsOfAvailability skipped apn due to attached && isReady " +
1677cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            apnContext.toString());
1678cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1679c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1680c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1681c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1682c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1683cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1684cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * If tearDown is true, this only tears down a CONNECTED session. Presently,
1685cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * there is no mechanism for abandoning an CONNECTING session,
1686cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * but would likely involve cancelling pending async requests or
1687cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * setting a flag or new state to ignore them when they came in
1688cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param tearDown true if the underlying DataConnection should be
1689cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * disconnected.
1690cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param reason reason for the clean up.
16913fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return boolean - true if we did cleanup any connections, false if they
16923fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     *                   were already all disconnected.
1693cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
16941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean cleanUpAllConnections(boolean tearDown, String reason) {
1695cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("cleanUpAllConnections: tearDown=" + tearDown + " reason=" + reason);
16963fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        boolean didDisconnect = false;
16973d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        boolean specificDisable = false;
1698a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
16993d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu        // Either user disable mobile data or under roaming service and user disabled roaming
1700a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (!TextUtils.isEmpty(reason)) {
17013d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            specificDisable = reason.equals(Phone.REASON_DATA_SPECIFIC_DISABLED) ||
17023d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                    reason.equals(Phone.REASON_ROAMING_ON);
1703a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1704cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1705cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
17063fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (apnContext.isDisconnected() == false) didDisconnect = true;
17073d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu            if (specificDisable) {
1708783061ca03572618c01ce244d70d82fa4328d45ffionaxu                // Use ApnSetting to decide metered or non-metered.
1709783061ca03572618c01ce244d70d82fa4328d45ffionaxu                // Tear down all metered data connections.
1710783061ca03572618c01ce244d70d82fa4328d45ffionaxu                ApnSetting apnSetting = apnContext.getApnSetting();
1711783061ca03572618c01ce244d70d82fa4328d45ffionaxu                if (apnSetting != null && apnSetting.isMetered(mPhone.getContext(),
17123d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu                        mPhone.getSubId(), mPhone.getServiceState().getDataRoaming())) {
1713783061ca03572618c01ce244d70d82fa4328d45ffionaxu                    if (DBG) log("clean up metered ApnContext Type: " + apnContext.getApnType());
1714a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    apnContext.setReason(reason);
1715a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    cleanUpConnection(tearDown, apnContext);
1716a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1717a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
1718a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // TODO - only do cleanup if not disconnected
1719a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                apnContext.setReason(reason);
1720a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                cleanUpConnection(tearDown, apnContext);
1721a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1722c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1723cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1724cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopNetStatPoll();
1725cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopDataStallAlarm();
1726cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1727cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: Do we need mRequestedApnType?
1728cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
1729a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1730a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("cleanUpConnection: mDisconnectPendingCount = " + mDisconnectPendingCount);
1731a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (tearDown && mDisconnectPendingCount == 0) {
1732a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyDataDisconnectComplete();
1733a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
1734a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1735a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
17363fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return didDisconnect;
1737cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1738cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1739cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1740cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Cleanup all connections.
1741cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1742cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * TODO: Cleanup only a specified connection passed as a parameter.
1743cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *       Also, make sure when you clean up a conn, if it is last apply
1744cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *       logic as though it is cleanupAllConnections
1745cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1746cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param cause for the clean up.
1747cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
17481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onCleanUpAllConnections(String cause) {
1749cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, cause);
1750cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1751cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
17521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    void sendCleanUpConnection(boolean tearDown, ApnContext apnContext) {
17531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("sendCleanUpConnection: tearDown=" + tearDown + " apnContext=" + apnContext);
17541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_CLEAN_UP_CONNECTION);
17551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = tearDown ? 1 : 0;
17561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg2 = 0;
17571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.obj = apnContext;
17581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
17591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
1760cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
17611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void cleanUpConnection(boolean tearDown, ApnContext apnContext) {
1762cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
1763cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("cleanUpConnection: apn context is null");
1764cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
1765cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1766cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1767454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac = apnContext.getDcAc();
17682dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        String str = "cleanUpConnection: tearDown=" + tearDown + " reason=" +
17692dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                apnContext.getReason();
17709c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        if (VDBG) log(str + " apnContext=" + apnContext);
17712dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog(str);
1772cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (tearDown) {
1773cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.isDisconnected()) {
1774cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // The request is tearDown and but ApnContext is not connected.
1775cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // If apnContext is not enabled anymore, break the linkage to the DCAC/DC.
1776cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setState(DctConstants.State.IDLE);
1777cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (!apnContext.isReady()) {
17784750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                    if (dcac != null) {
17790e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                        str = "cleanUpConnection: teardown, disconnected, !ready";
17802dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        if (DBG) log(str + " apnContext=" + apnContext);
17812dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        apnContext.requestLog(str);
17824750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                        dcac.tearDown(apnContext, "", null);
17834750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                    }
1784cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setDataConnectionAc(null);
1785cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1786cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1787cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Connection is still there. Try to clean up.
1788cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (dcac != null) {
1789cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (apnContext.getState() != DctConstants.State.DISCONNECTING) {
1790cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        boolean disconnectAll = false;
1791cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (PhoneConstants.APN_TYPE_DUN.equals(apnContext.getApnType())) {
1792a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            // CAF_MSIM is this below condition required.
1793a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            // if (PhoneConstants.APN_TYPE_DUN.equals(PhoneConstants.APN_TYPE_DEFAULT)) {
17941484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                            if (teardownForDun()) {
179545eaa2335e64a8ff1ad8d5e8224c580ef996f370Wink Saville                                if (DBG) {
179645eaa2335e64a8ff1ad8d5e8224c580ef996f370Wink Saville                                    log("cleanUpConnection: disconnectAll DUN connection");
179745eaa2335e64a8ff1ad8d5e8224c580ef996f370Wink Saville                                }
1798cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // we need to tear it down - we brought it up just for dun and
1799cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // other people are camped on it and now dun is done.  We need
1800cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // to stop using it and let the normal apn list get used to find
1801cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // connections for the remaining desired connections
1802cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                disconnectAll = true;
1803cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            }
1804cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
18051a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                        final int generation = apnContext.getConnectionGeneration();
18061a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                        str = "cleanUpConnection: tearing down" + (disconnectAll ? " all" : "") +
18071a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                                " using gen#" + generation;
18082dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        if (DBG) log(str + "apnContext=" + apnContext);
18092dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        apnContext.requestLog(str);
181037cacdfe7ed079d89fb9e80317b5dfd2acb975e5Robert Greenwalt                        Pair<ApnContext, Integer> pair =
18111a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                                new Pair<ApnContext, Integer>(apnContext, generation);
181237cacdfe7ed079d89fb9e80317b5dfd2acb975e5Robert Greenwalt                        Message msg = obtainMessage(DctConstants.EVENT_DISCONNECT_DONE, pair);
1813cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (disconnectAll) {
1814ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            apnContext.getDcAc().tearDownAll(apnContext.getReason(), msg);
1815cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        } else {
1816ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            apnContext.getDcAc()
1817cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                .tearDown(apnContext, apnContext.getReason(), msg);
1818cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
1819cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.setState(DctConstants.State.DISCONNECTING);
1820a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        mDisconnectPendingCount++;
1821cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1822cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1823cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // apn is connected but no reference to dcac.
1824cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // Should not be happen, but reset the state in case.
1825cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setState(DctConstants.State.IDLE);
18262dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    apnContext.requestLog("cleanUpConnection: connected, bug no DCAC");
1827cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mPhone.notifyDataConnection(apnContext.getReason(),
1828cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                                apnContext.getApnType());
1829cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1830cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1831cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1832cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // force clean up the data connection.
1833ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac != null) dcac.reqReset();
1834cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setState(DctConstants.State.IDLE);
1835cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1836cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setDataConnectionAc(null);
1837cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1838cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1839ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // Make sure reconnection alarm is cleaned up if there is no ApnContext
1840cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // associated to the connection.
1841cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (dcac != null) {
1842ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            cancelReconnectAlarm(apnContext);
1843c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
18442dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        str = "cleanUpConnection: X tearDown=" + tearDown + " reason=" + apnContext.getReason();
18452dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        if (DBG) log(str + " apnContext=" + apnContext + " dcac=" + apnContext.getDcAc());
18462dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog(str);
1847cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1848c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
18491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    ApnSetting fetchDunApn() {
18501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (SystemProperties.getBoolean("net.tethering.noprovisioning", false)) {
18511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("fetchDunApn: net.tethering.noprovisioning=true ret: null");
18521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return null;
18531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
18541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int bearer = mPhone.getServiceState().getRilDataRadioTechnology();
18551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting retDunSetting = null;
18561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        String apnData = Settings.Global.getString(mResolver, Settings.Global.TETHER_DUN_APN);
18571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        List<ApnSetting> dunSettings = ApnSetting.arrayFromString(apnData);
18581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        IccRecords r = mIccRecords.get();
18591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        for (ApnSetting dunSetting : dunSettings) {
18601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            String operator = (r != null) ? r.getOperatorNumeric() : "";
18611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (!ServiceState.bitmaskHasTech(dunSetting.bearerBitmask, bearer)) continue;
18621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (dunSetting.numeric.equals(operator)) {
18631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (dunSetting.hasMvnoParams()) {
18641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (r != null && ApnSetting.mvnoMatches(r, dunSetting.mvnoType,
18651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            dunSetting.mvnoMatchData)) {
18661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (VDBG) {
18671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            log("fetchDunApn: global TETHER_DUN_APN dunSetting=" + dunSetting);
18681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        }
18691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        return dunSetting;
18701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
18711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else if (mMvnoMatched == false) {
18721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (VDBG) log("fetchDunApn: global TETHER_DUN_APN dunSetting=" + dunSetting);
18731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    return dunSetting;
18741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
18751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
18761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
18771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
18781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Context c = mPhone.getContext();
18791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        String[] apnArrayData = c.getResources().getStringArray(R.array.config_tether_apndata);
18801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        for (String apn : apnArrayData) {
18811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            ApnSetting dunSetting = ApnSetting.fromString(apn);
18821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (dunSetting != null) {
18831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (!ServiceState.bitmaskHasTech(dunSetting.bearerBitmask, bearer)) continue;
18841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (dunSetting.hasMvnoParams()) {
18851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (r != null && ApnSetting.mvnoMatches(r, dunSetting.mvnoType,
18861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            dunSetting.mvnoMatchData)) {
18871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (VDBG) {
18881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            log("fetchDunApn: config_tether_apndata mvno dunSetting=" + dunSetting);
18891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        }
18901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        return dunSetting;
18911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
18921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else if (mMvnoMatched == false) {
18931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    retDunSetting = dunSetting;
18941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
18951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
18961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
18971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
18981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) log("fetchDunApn: config_tether_apndata dunSetting=" + retDunSetting);
18991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return retDunSetting;
19001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
19011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
19021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public boolean hasMatchedTetherApnSetting() {
19031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting matched = fetchDunApn();
19041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("hasMatchedTetherApnSetting: APN=" + matched);
19051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return matched != null;
19061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
19071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1908cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
19091484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt     * Determine if DUN connection is special and we need to teardown on start/stop
19101484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt     */
19111484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt    private boolean teardownForDun() {
19121484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // CDMA always needs to do this the profile id is correct
19131484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        final int rilRat = mPhone.getServiceState().getRilDataRadioTechnology();
19141484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        if (ServiceState.isCdma(rilRat)) return true;
19151484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt
19161484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        return (fetchDunApn() != null);
19171484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt    }
19181484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt
19191484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt    /**
1920ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Cancels the alarm associated with apnContext.
1921cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1922ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * @param apnContext on which the alarm should be stopped.
1923cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1924ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void cancelReconnectAlarm(ApnContext apnContext) {
1925ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnContext == null) return;
1926cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1927ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        PendingIntent intent = apnContext.getReconnectIntent();
1928cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1929cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (intent != null) {
1930cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                AlarmManager am =
1931cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
1932cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                am.cancel(intent);
1933ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setReconnectIntent(null);
1934cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1935c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1936c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1937cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1938cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param types comma delimited list of APN types
1939cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return array of APN types
1940cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1941cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private String[] parseTypes(String types) {
1942c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String[] result;
1943cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // If unset, set to DEFAULT.
1944cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (types == null || types.equals("")) {
1945c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            result = new String[1];
1946cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result[0] = PhoneConstants.APN_TYPE_ALL;
1947cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1948cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result = types.split(",");
1949c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1950c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
1951c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1952c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
19531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    boolean isPermanentFail(DcFailCause dcFailCause) {
1954796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan        return (dcFailCause.isPermanentFail() &&
1955796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan                (mAttached.get() == false || dcFailCause != DcFailCause.SIGNAL_LOST));
1956796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan    }
1957796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan
1958fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    private ApnSetting makeApnSetting(Cursor cursor) {
1959fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        String[] types = parseTypes(
1960fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.TYPE)));
1961fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        ApnSetting apn = new ApnSetting(
1962fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID)),
1963fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NUMERIC)),
1964fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NAME)),
1965fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN)),
1966fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1967fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1968fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY))),
1969fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PORT)),
1970fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1971fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1972fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC))),
1973fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1974fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1975fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY))),
1976fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPORT)),
1977fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)),
1978fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)),
19791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.AUTH_TYPE)),
1980fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                types,
1981fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROTOCOL)),
1982fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(
1983fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        Telephony.Carriers.ROAMING_PROTOCOL)),
1984fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(
1985fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        Telephony.Carriers.CARRIER_ENABLED)) == 1,
19869d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.BEARER)),
1987aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.BEARER_BITMASK)),
19889d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROFILE_ID)),
19899d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(
19909d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                        Telephony.Carriers.MODEM_COGNITIVE)) == 1,
19919d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MAX_CONNS)),
19929d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(
19939d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                        Telephony.Carriers.WAIT_TIME)),
1994e9701717e43cc5aacbcf624f77a53be92350662cw                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MAX_CONNS_TIME)),
19953262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MTU)),
19963262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_TYPE)),
19973262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_MATCH_DATA)));
1998fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        return apn;
1999fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    }
2000fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
2001cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ArrayList<ApnSetting> createApnList(Cursor cursor) {
20023262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        ArrayList<ApnSetting> mnoApns = new ArrayList<ApnSetting>();
20033262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        ArrayList<ApnSetting> mvnoApns = new ArrayList<ApnSetting>();
2004fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        IccRecords r = mIccRecords.get();
2005fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
2006cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor.moveToFirst()) {
2007cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            do {
20083262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                ApnSetting apn = makeApnSetting(cursor);
20093262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                if (apn == null) {
20103262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                    continue;
20113262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                }
20123262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
20133262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                if (apn.hasMvnoParams()) {
201463913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan                    if (r != null && ApnSetting.mvnoMatches(r, apn.mvnoType, apn.mvnoMatchData)) {
20153262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                        mvnoApns.add(apn);
2016fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    }
2017fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                } else {
20183262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                    mnoApns.add(apn);
2019fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                }
2020cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } while (cursor.moveToNext());
2021cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
20223262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
20231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ArrayList<ApnSetting> result;
20241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mvnoApns.isEmpty()) {
20251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            result = mnoApns;
20261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mMvnoMatched = false;
20271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
20281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            result = mvnoApns;
20291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mMvnoMatched = true;
20301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
2031cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createApnList: X result=" + result);
2032c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
2033c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2034c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2035454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private boolean dataConnectionNotInUse(DcAsyncChannel dcac) {
2036ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("dataConnectionNotInUse: check if dcac is inuse dcac=" + dcac);
2037cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
2038ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getDcAc() == dcac) {
2039cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("dataConnectionNotInUse: in use by apnContext=" + apnContext);
2040cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
2041cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2042cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2043cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: Fix retry handling so free DataConnections have empty apnlists.
2044cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Probably move retry handling into DataConnections and reduce complexity
2045cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // of DCT.
2046cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("dataConnectionNotInUse: tearDownAll");
2047ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        dcac.tearDownAll("No connection", null);
2048cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("dataConnectionNotInUse: not in use return true");
2049cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
2050cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2051cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2052454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel findFreeDataConnection() {
2053454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
2054cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac.isInactiveSync() && dataConnectionNotInUse(dcac)) {
2055cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
2056cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("findFreeDataConnection: found free DataConnection=" +
2057ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        " dcac=" + dcac);
2058cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2059ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                return dcac;
2060cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2061cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2062cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("findFreeDataConnection: NO free DataConnection");
2063cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
2064cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2065cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2066203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    private boolean setupData(ApnContext apnContext, int radioTech) {
2067cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setupData: apnContext=" + apnContext);
20682dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog("setupData");
2069ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnSetting apnSetting;
20701484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        DcAsyncChannel dcac = null;
2071cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
20720e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        apnSetting = apnContext.getNextApnSetting();
20730e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
2074ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnSetting == null) {
2075cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("setupData: return for no apn found!");
2076cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
2077cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2078cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2079231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        int profileId = apnSetting.profileId;
2080231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        if (profileId == 0) {
2081231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen            profileId = getApnProfileID(apnContext.getApnType());
2082231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        }
2083231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen
20841484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // On CDMA, if we're explicitly asking for DUN, we need have
20851484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // a dun-profiled connection so we can't share an existing one
20861484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // On GSM/LTE we can share existing apn connections provided they support
20871484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // this type.
20881484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        if (apnContext.getApnType() != PhoneConstants.APN_TYPE_DUN ||
20891484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                teardownForDun() == false) {
20901484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt            dcac = checkForCompatibleConnectedApnContext(apnContext);
20911484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt            if (dcac != null) {
20921484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // Get the dcacApnSetting for the connection we want to share.
20931484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                ApnSetting dcacApnSetting = dcac.getApnSettingSync();
20941484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                if (dcacApnSetting != null) {
20951484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    // Setting is good, so use it.
20961484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    apnSetting = dcacApnSetting;
20971484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                }
2098ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
2099ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
2100ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (dcac == null) {
21013fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (isOnlySingleDcAllowed(radioTech)) {
21023fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (isHigherPriorityApnContextActive(apnContext)) {
21033fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (DBG) {
21043fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        log("setupData: Higher priority ApnContext active.  Ignoring call");
21053fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    }
21063fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    return false;
21073fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                }
21083fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
21093fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // Only lower priority calls left.  Disconnect them all in this single PDP case
21103fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // so that we can bring up the requested higher priority call (once we receive
21110e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                // response for deactivate request for the calls we are about to disconnect
21123fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (cleanUpAllConnections(true, Phone.REASON_SINGLE_PDN_ARBITRATION)) {
21133fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // If any call actually requested to be disconnected, means we can't
21143fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // bring up this connection yet as we need to wait for those data calls
21153fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // to be disconnected.
21163fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (DBG) log("setupData: Some calls are disconnecting first.  Wait and retry");
21173fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    return false;
21183fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                }
21193fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
21203fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // No other calls are active, so proceed
21213fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (DBG) log("setupData: Single pdp. Continue setting up data call.");
21223fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
21233fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
2124ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            dcac = findFreeDataConnection();
2125cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2126ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac == null) {
2127ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                dcac = createDataConnection();
2128cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2129cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2130ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac == null) {
2131ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) log("setupData: No free DataConnection and couldn't create one, WEIRD");
2132cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
2133cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2134cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
21351a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        final int generation = apnContext.incAndGetConnectionGeneration();
21361a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        if (DBG) {
21371a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt            log("setupData: dcac=" + dcac + " apnSetting=" + apnSetting + " gen#=" + generation);
21381a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        }
2139cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2140cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setDataConnectionAc(dcac);
2141ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setApnSetting(apnSetting);
2142cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setState(DctConstants.State.CONNECTING);
2143cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
2144cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2145cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Message msg = obtainMessage();
2146cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        msg.what = DctConstants.EVENT_DATA_SETUP_COMPLETE;
21471a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        msg.obj = new Pair<ApnContext, Integer>(apnContext, generation);
21480e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        dcac.bringUp(apnContext, profileId, radioTech, msg, generation);
2149cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2150cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setupData: initing!");
2151cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
2152cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2153cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
21541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void setInitialAttachApn() {
21551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting iaApnSetting = null;
21561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting defaultApnSetting = null;
21571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting firstApnSetting = null;
21581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
21591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("setInitialApn: E mPreferredApn=" + mPreferredApn);
21601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
21611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mAllApnSettings != null && !mAllApnSettings.isEmpty()) {
21621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            firstApnSetting = mAllApnSettings.get(0);
21631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("setInitialApn: firstApnSetting=" + firstApnSetting);
21641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
21651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Search for Initial APN setting and the first apn that can handle default
21661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (ApnSetting apn : mAllApnSettings) {
21671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // Can't use apn.canHandleType(), as that returns true for APNs that have no type.
21681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (ArrayUtils.contains(apn.types, PhoneConstants.APN_TYPE_IA) &&
21691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        apn.carrierEnabled) {
21701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // The Initial Attach APN is highest priority so use it if there is one
21711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("setInitialApn: iaApnSetting=" + apn);
21721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    iaApnSetting = apn;
21731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    break;
21741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else if ((defaultApnSetting == null)
21751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        && (apn.canHandleType(PhoneConstants.APN_TYPE_DEFAULT))) {
21761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // Use the first default apn if no better choice
21771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("setInitialApn: defaultApnSetting=" + apn);
21781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    defaultApnSetting = apn;
21791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
21801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
21811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
21821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
21831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // The priority of apn candidates from highest to lowest is:
21840e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        //   1) APN_TYPE_IA (Initial Attach)
21851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        //   2) mPreferredApn, i.e. the current preferred apn
21861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        //   3) The first apn that than handle APN_TYPE_DEFAULT
21871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        //   4) The first APN we can find.
21881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
21891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting initialAttachApnSetting = null;
21901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (iaApnSetting != null) {
21911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using iaApnSetting");
21921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = iaApnSetting;
21931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (mPreferredApn != null) {
21941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using mPreferredApn");
21951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = mPreferredApn;
21961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (defaultApnSetting != null) {
21971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using defaultApnSetting");
21981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = defaultApnSetting;
21991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (firstApnSetting != null) {
22001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using firstApnSetting");
22011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = firstApnSetting;
22021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
22031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
22041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (initialAttachApnSetting == null) {
22051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: X There in no available apn");
22061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
22071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: X selected Apn=" + initialAttachApnSetting);
22081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
22091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPhone.mCi.setInitialAttachApn(initialAttachApnSetting.apn,
22101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    initialAttachApnSetting.protocol, initialAttachApnSetting.authType,
22111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    initialAttachApnSetting.user, initialAttachApnSetting.password, null);
22121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
22131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
22141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2215c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
2216cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Handles changes to the APN database.
2217c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
2218cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onApnChanged() {
2219cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        DctConstants.State overallState = getOverallState();
2220cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isDisconnected = (overallState == DctConstants.State.IDLE ||
2221cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                overallState == DctConstants.State.FAILED);
2222cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
22231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mPhone instanceof GsmCdmaPhone) {
2224cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // The "current" may no longer be valid.  MMS depends on this to send properly. TBD
22251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            ((GsmCdmaPhone)mPhone).updateCurrentCarrierInProvider();
2226cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2227cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2228cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: It'd be nice to only do this if the changed entrie(s)
2229cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // match the current operator.
2230cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onApnChanged: createAllApnList and cleanUpAllConnections");
2231cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        createAllApnList();
22325d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi        setInitialAttachApn();
22339a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        cleanUpConnectionsOnUpdatedApns(!isDisconnected);
2234bda761320929f714951c328bfec6a51a1978db97Wink Saville
22358f6f52e4f7598e44cea1f9e5f4781291f9060d1dWink Saville        // FIXME: See bug 17426028 maybe no conditional is needed.
223638ca51d0f643405df51e78fce6c546424e9f410dShishir Agrawal        if (mPhone.getSubId() == SubscriptionManager.getDefaultDataSubscriptionId()) {
2237ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_APN_CHANGED);
2238c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2239c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2240c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2241c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
2242cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param cid Connection id provided from RIL.
2243cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return DataConnectionAc associated with specified cid.
2244c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
2245454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel findDataConnectionAcByCid(int cid) {
2246454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
2247cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac.getCidSync() == cid) {
2248cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return dcac;
2249cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2250c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2251cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
2252c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2253c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2254cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // TODO: For multiple Active APNs not exactly sure how to do this.
22551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void gotoIdleAndNotifyDataConnection(String reason) {
2256cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("gotoIdleAndNotifyDataConnection: reason=" + reason);
2257cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyDataConnection(reason);
2258cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2259cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
22603fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    /**
22613fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * "Active" here means ApnContext isEnabled() and not in FAILED state
22623fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @param apnContext to compare with
22633fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return true if higher priority active apn found
22643fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     */
22653fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean isHigherPriorityApnContextActive(ApnContext apnContext) {
22663fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        for (ApnContext otherContext : mPrioritySortedApnContexts) {
22673fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (apnContext.getApnType().equalsIgnoreCase(otherContext.getApnType())) return false;
22683fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (otherContext.isEnabled() && otherContext.getState() != DctConstants.State.FAILED) {
22693fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                return true;
22703fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
22713fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
22723fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return false;
22733fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    }
22743fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
22753fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    /**
22763fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * Reports if we support multiple connections or not.
22773fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * This is a combination of factors, based on carrier and RAT.
22783fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @param rilRadioTech the RIL Radio Tech currently in use
22793fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return true if only single DataConnection is allowed
22803fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     */
22813fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean isOnlySingleDcAllowed(int rilRadioTech) {
22823fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        int[] singleDcRats = mPhone.getContext().getResources().getIntArray(
22833fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                com.android.internal.R.array.config_onlySingleDcAllowed);
22843fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        boolean onlySingleDcAllowed = false;
22853fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (Build.IS_DEBUGGABLE &&
22863fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                SystemProperties.getBoolean("persist.telephony.test.singleDc", false)) {
22873fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            onlySingleDcAllowed = true;
22883fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
22893fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (singleDcRats != null) {
22903fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            for (int i=0; i < singleDcRats.length && onlySingleDcAllowed == false; i++) {
22913fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (rilRadioTech == singleDcRats[i]) onlySingleDcAllowed = true;
22923fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
22933fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
22943fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
22953fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (DBG) log("isOnlySingleDcAllowed(" + rilRadioTech + "): " + onlySingleDcAllowed);
22963fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return onlySingleDcAllowed;
22973fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    }
22983fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
22991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    void sendRestartRadio() {
23001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG)log("sendRestartRadio:");
23011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_RESTART_RADIO);
23021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
23031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
23041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
23051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void restartRadio() {
2306cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("restartRadio: ************TURN OFF RADIO**************");
2307cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, Phone.REASON_RADIO_TURNED_OFF);
2308cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().powerOffRadioSafely(this);
2309cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        /* Note: no need to call setRadioPower(true).  Assuming the desired
2310cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * radio power state is still ON (as tracked by ServiceStateTracker),
2311cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * ServiceStateTracker will call setRadioPower when it receives the
2312cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * RADIO_STATE_CHANGED notification for the power off.  And if the
2313cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * desired power state has changed in the interim, we don't want to
2314cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * override it with an unconditional power on.
2315cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         */
2316cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2317cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int reset = Integer.parseInt(SystemProperties.get("net.ppp.reset-by-timeout", "0"));
23180e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        SystemProperties.set("net.ppp.reset-by-timeout", String.valueOf(reset + 1));
2319cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2320cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2321cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
2322cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Return true if data connection need to be setup after disconnected due to
2323cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * reason.
2324cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
23250e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu     * @param apnContext APN context
2326cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return true if try setup data connection is need for this reason
2327cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
23283fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean retryAfterDisconnected(ApnContext apnContext) {
2329cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean retry = true;
23303fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        String reason = apnContext.getReason();
2331cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
23323fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) ||
23333fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())
23343fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                 && isHigherPriorityApnContextActive(apnContext))) {
2335cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            retry = false;
2336cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2337cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return retry;
2338cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2339cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
23400e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    private void startAlarmForReconnect(long delay, ApnContext apnContext) {
2341cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String apnType = apnContext.getApnType();
234274672e8ee972f12406b72551261b4cc7e0651933Wink Saville
234374672e8ee972f12406b72551261b4cc7e0651933Wink Saville        Intent intent = new Intent(INTENT_RECONNECT_ALARM + "." + apnType);
234474672e8ee972f12406b72551261b4cc7e0651933Wink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, apnContext.getReason());
2345cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, apnType);
234667d43cfed4b996c20780bfec8fde1ae8c1391779Junda Liu        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
2347cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2348a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // Get current sub id.
234938ca51d0f643405df51e78fce6c546424e9f410dShishir Agrawal        int subId = SubscriptionManager.getDefaultDataSubscriptionId();
2350a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
2351a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
235274672e8ee972f12406b72551261b4cc7e0651933Wink Saville        if (DBG) {
235374672e8ee972f12406b72551261b4cc7e0651933Wink Saville            log("startAlarmForReconnect: delay=" + delay + " action=" + intent.getAction()
235474672e8ee972f12406b72551261b4cc7e0651933Wink Saville                    + " apn=" + apnContext);
235574672e8ee972f12406b72551261b4cc7e0651933Wink Saville        }
235674672e8ee972f12406b72551261b4cc7e0651933Wink Saville
23570e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        PendingIntent alarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0,
2358cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                        intent, PendingIntent.FLAG_UPDATE_CURRENT);
2359ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setReconnectIntent(alarmIntent);
23607d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu
23617d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu        // Use the exact timer instead of the inexact one to provide better user experience.
23627d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu        // In some extreme cases, we saw the retry was delayed for few minutes.
23630852a954be5937a1b0bca94df0c2007d7ee3c0c7Jack Yu        // Note that if the stated trigger time is in the past, the alarm will be triggered
23640852a954be5937a1b0bca94df0c2007d7ee3c0c7Jack Yu        // immediately.
23657d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu        mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
2366cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                SystemClock.elapsedRealtime() + delay, alarmIntent);
2367cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2368cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2369ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void notifyNoData(DcFailCause lastFailCauseCode,
2370cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                              ApnContext apnContext) {
2371cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log( "notifyNoData: type=" + apnContext.getApnType());
2372796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan        if (isPermanentFail(lastFailCauseCode)
2373cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            && (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT))) {
2374cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
2375cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2376cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2377cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
23781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public boolean getAutoAttachOnCreation() {
23791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mAutoAttachOnCreation.get();
23801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
23811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
23821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRecordsLoadedOrSubIdChanged() {
23831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("onRecordsLoadedOrSubIdChanged: createAllApnList");
238412fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        mAutoAttachOnCreationConfig = mPhone.getContext().getResources()
238512fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao                .getBoolean(com.android.internal.R.bool.config_auto_attach_data_on_creation);
2386bda761320929f714951c328bfec6a51a1978db97Wink Saville
2387cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        createAllApnList();
23885d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi        setInitialAttachApn();
238922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPhone.mCi.getRadioState().isOn()) {
23901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("onRecordsLoadedOrSubIdChanged: notifying data availability");
2391cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_SIM_LOADED);
2392cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2393bda761320929f714951c328bfec6a51a1978db97Wink Saville        setupDataOnConnectableApns(Phone.REASON_SIM_LOADED);
2394cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2395cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2396a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    private void applyColdSimDetected(int subId) {
2397a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        if(isColdSimDetected(subId)) {
2398a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            if(!mColdSimDetected) {
2399a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                if(DBG) {
2400a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                    log("onColdSimDetected on subId " + subId +": cleanUpAllDataConnections");
2401a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                }
2402a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                cleanUpAllConnections(null);
2403a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                //send otasp_sim_unprovisioned so that SuW is able to proceed and notify users
2404a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                mPhone.notifyOtaspChanged(ServiceStateTracker.OTASP_SIM_UNPROVISIONED);
2405a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                mColdSimDetected = true;
2406a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            }
2407a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        } else {
2408a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            if (DBG) log("onColdSimDetected on subId: " + + subId + " reset coldSimDetected");
2409a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            mColdSimDetected = false;
2410a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            mRedirected = false;
2411a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        }
2412a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    }
2413a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
24140469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal    private void onSimNotReady() {
24150469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        if (DBG) log("onSimNotReady");
24160469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal
24170469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        cleanUpAllConnections(true, Phone.REASON_SIM_NOT_READY);
24180469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        mAllApnSettings = null;
24190469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        mAutoAttachOnCreationConfig = false;
24200469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal    }
24210469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal
24221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetDependencyMet(String apnType, boolean met) {
2423cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // don't allow users to tweak hipri to work around default dependency not met
2424cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_HIPRI.equals(apnType)) return;
2425cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2426cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
2427cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
2428cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onSetDependencyMet: ApnContext not found in onSetDependencyMet(" +
2429cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnType + ", " + met + ")");
2430cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
2431cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2432cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        applyNewState(apnContext, apnContext.isEnabled(), met);
2433cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_DEFAULT.equals(apnType)) {
2434cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // tie actions on default to similar actions on HIPRI regarding dependencyMet
2435cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext = mApnContexts.get(PhoneConstants.APN_TYPE_HIPRI);
2436cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext != null) applyNewState(apnContext, apnContext.isEnabled(), met);
2437cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2438cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2439c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
24401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetPolicyDataEnabled(boolean enabled) {
24411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        synchronized (mDataEnabledLock) {
24421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            final boolean prevEnabled = getAnyDataEnabled();
24431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (sPolicyDataEnabled != enabled) {
24441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                sPolicyDataEnabled = enabled;
24451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (prevEnabled != getAnyDataEnabled()) {
24461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (!prevEnabled) {
24471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onTrySetupData(Phone.REASON_DATA_ENABLED);
24481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
24491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);
24501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
24511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
24521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
24531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
24541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
24551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
24561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2457cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void applyNewState(ApnContext apnContext, boolean enabled, boolean met) {
2458cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean cleanup = false;
2459cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean trySetup = false;
24602dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        String str ="applyNewState(" + apnContext.getApnType() + ", " + enabled +
24612dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                "(" + apnContext.isEnabled() + "), " + met + "(" +
24622dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                apnContext.getDependencyMet() +"))";
24632dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        if (DBG) log(str);
24642dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog(str);
24652dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt
2466cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext.isReady()) {
2467305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt            cleanup = true;
24682428693913ae731d4ace3414429f5e91af24ea36Wink Saville            if (enabled && met) {
24692428693913ae731d4ace3414429f5e91af24ea36Wink Saville                DctConstants.State state = apnContext.getState();
24702428693913ae731d4ace3414429f5e91af24ea36Wink Saville                switch(state) {
24712428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case CONNECTING:
24722428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case SCANNING:
24732428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case CONNECTED:
24742428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case DISCONNECTING:
24752428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // We're "READY" and active so just return
24762428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        if (DBG) log("applyNewState: 'ready' so return");
24772dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        apnContext.requestLog("applyNewState state=" + state + ", so return");
24782428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        return;
24792428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case IDLE:
24802428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // fall through: this is unexpected but if it happens cleanup and try setup
24812428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case FAILED:
24822428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case RETRYING: {
24832428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // We're "READY" but not active so disconnect (cleanup = true) and
24842428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // connect (trySetup = true) to be sure we retry the connection.
24852428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        trySetup = true;
24862428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        apnContext.setReason(Phone.REASON_DATA_ENABLED);
24872428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        break;
24882428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    }
24892428693913ae731d4ace3414429f5e91af24ea36Wink Saville                }
2490305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt            } else if (met) {
2491cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setReason(Phone.REASON_DATA_DISABLED);
2492305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // If ConnectivityService has disabled this network, stop trying to bring
2493305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // it up, but do not tear it down - ConnectivityService will do that
2494305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // directly by talking with the DataConnection.
24951484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                //
24961484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // This doesn't apply to DUN, however.  Those connections have special
24971484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // requirements from carriers and we need stop using them when the dun
24981484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // request goes away.  This applies to both CDMA and GSM because they both
24991484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // can declare the DUN APN sharable by default traffic, thus still satisfying
25001484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // those requests and not torn down organically.
25011484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                if (apnContext.getApnType() == PhoneConstants.APN_TYPE_DUN && teardownForDun()) {
25021484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    cleanup = true;
25031484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                } else {
25041484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    cleanup = false;
25051484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                }
2506cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
2507cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_UNMET);
2508cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2509cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2510cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (enabled && met) {
2511cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apnContext.isEnabled()) {
2512cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_MET);
2513cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2514cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setReason(Phone.REASON_DATA_ENABLED);
2515c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
2516cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apnContext.getState() == DctConstants.State.FAILED) {
2517cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setState(DctConstants.State.IDLE);
2518cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2519cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                trySetup = true;
2520cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2521cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2522cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setEnabled(enabled);
2523cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setDependencyMet(met);
2524cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cleanup) cleanUpConnection(true, apnContext);
25250d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt        if (trySetup) {
25260d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt            apnContext.resetErrorCodeRetries();
25270d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt            trySetupData(apnContext);
25280d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt        }
2529cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2530c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2531454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel checkForCompatibleConnectedApnContext(ApnContext apnContext) {
2532cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String apnType = apnContext.getApnType();
2533cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnSetting dunSetting = null;
2534cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2535cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_DUN.equals(apnType)) {
2536cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            dunSetting = fetchDunApn();
2537cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2538ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) {
2539ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            log("checkForCompatibleConnectedApnContext: apnContext=" + apnContext );
2540ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
2541cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2542454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel potentialDcac = null;
2543ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnContext potentialApnCtx = null;
2544ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        for (ApnContext curApnCtx : mApnContexts.values()) {
2545454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel curDcac = curApnCtx.getDcAc();
2546ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (curDcac != null) {
2547ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                ApnSetting apnSetting = curApnCtx.getApnSetting();
2548a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("apnSetting: " + apnSetting);
2549cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (dunSetting != null) {
2550cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (dunSetting.equals(apnSetting)) {
2551ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        switch (curApnCtx.getState()) {
2552cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            case CONNECTED:
2553cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                if (DBG) {
2554ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                    log("checkForCompatibleConnectedApnContext:"
2555ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                            + " found dun conn=" + curDcac
2556ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                            + " curApnCtx=" + curApnCtx);
2557cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                }
2558ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                return curDcac;
2559ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            case RETRYING:
2560cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            case CONNECTING:
2561ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                potentialDcac = curDcac;
2562ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                potentialApnCtx = curApnCtx;
2563cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            default:
2564cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // Not connected, potential unchanged
2565cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                break;
2566cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
2567cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2568cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else if (apnSetting != null && apnSetting.canHandleType(apnType)) {
2569ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    switch (curApnCtx.getState()) {
2570cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        case CONNECTED:
2571cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            if (DBG) {
2572ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                log("checkForCompatibleConnectedApnContext:"
2573ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        + " found canHandle conn=" + curDcac
2574ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        + " curApnCtx=" + curApnCtx);
2575cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            }
2576ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            return curDcac;
2577ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        case RETRYING:
2578cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        case CONNECTING:
2579ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            potentialDcac = curDcac;
2580ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            potentialApnCtx = curApnCtx;
2581cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        default:
2582cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            // Not connected, potential unchanged
2583cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            break;
2584cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2585cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2586ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            } else {
2587ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) {
2588ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    log("checkForCompatibleConnectedApnContext: not conn curApnCtx=" + curApnCtx);
2589ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                }
2590cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2591cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2592ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (potentialDcac != null) {
2593cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
2594ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                log("checkForCompatibleConnectedApnContext: found potential conn=" + potentialDcac
2595ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        + " curApnCtx=" + potentialApnCtx);
2596cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2597ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            return potentialDcac;
2598cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2599c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2600ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("checkForCompatibleConnectedApnContext: NO conn apnContext=" + apnContext);
2601cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
2602cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2603c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
260427b650c406018355a88a41528db7859e232728a0Jack Yu    public void setEnabled(int id, boolean enable) {
26051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_ENABLE_NEW_APN);
26061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = id;
26071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg2 = (enable ? DctConstants.ENABLED : DctConstants.DISABLED);
26081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
26091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
26101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
26111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onEnableApn(int apnId, int enabled) {
2612af5593594070f825032be46dced573cd195956e1Robert Greenwalt        ApnContext apnContext = mApnContextsById.get(apnId);
2613cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
2614cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onEnableApn(" + apnId + ", " + enabled + "): NO ApnContext");
2615cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
2616cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2617cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO change our retry manager to use the appropriate numbers for the new APN
2618cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onEnableApn: apnContext=" + apnContext + " call applyNewState");
2619cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        applyNewState(apnContext, enabled == DctConstants.ENABLED, apnContext.getDependencyMet());
2620cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2621c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2622cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // TODO: We shouldnt need this.
26231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean onTrySetupData(String reason) {
2624cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onTrySetupData: reason=" + reason);
2625ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(reason);
2626cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
2627cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2628c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
26291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean onTrySetupData(ApnContext apnContext) {
2630cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onTrySetupData: apnContext=" + apnContext);
2631cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return trySetupData(apnContext);
2632cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2633c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
26341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
26351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Return current {@link android.provider.Settings.Global#MOBILE_DATA} value.
26361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
26371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public boolean getDataEnabled() {
2638f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        final int device_provisioned =
2639f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                Settings.Global.getInt(mResolver, Settings.Global.DEVICE_PROVISIONED, 0);
2640f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
26411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        boolean retVal = "true".equalsIgnoreCase(SystemProperties.get(
26421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                "ro.com.android.mobiledata", "true"));
2643f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        if (TelephonyManager.getDefault().getSimCount() == 1) {
2644f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            retVal = Settings.Global.getInt(mResolver, Settings.Global.MOBILE_DATA,
2645f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                    retVal ? 1 : 0) != 0;
2646f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        } else {
2647f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            int phoneSubId = mPhone.getSubId();
2648f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            try {
2649f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                retVal = TelephonyManager.getIntWithSubId(mResolver,
2650f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                        Settings.Global.MOBILE_DATA, phoneSubId) != 0;
2651f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            } catch (SettingNotFoundException e) {
2652f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                // use existing retVal
2653f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            }
2654f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        }
2655f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        if (VDBG) log("getDataEnabled: retVal=" + retVal);
2656f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt        if (device_provisioned == 0) {
2657f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            // device is still getting provisioned - use whatever setting they
2658f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            // want during this process
2659f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            //
2660f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            // use the normal data_enabled setting (retVal, determined above)
2661f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            // as the default if nothing else is set
2662f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            final String prov_property = SystemProperties.get("ro.com.android.prov_mobiledata",
2663f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                  retVal ? "true" : "false");
2664f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            retVal = "true".equalsIgnoreCase(prov_property);
2665f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
2666f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            final int prov_mobile_data = Settings.Global.getInt(mResolver,
2667f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                    Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED,
2668f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                    retVal ? 1 : 0);
2669f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            retVal = prov_mobile_data != 0;
2670f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            log("getDataEnabled during provisioning retVal=" + retVal + " - (" + prov_property +
2671f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                    ", " + prov_mobile_data + ")");
26721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
2673f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
26741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return retVal;
26751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
26761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
26771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
26781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Modify {@link android.provider.Settings.Global#DATA_ROAMING} value.
26791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
26801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void setDataOnRoamingEnabled(boolean enabled) {
26811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        final int phoneSubId = mPhone.getSubId();
26821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (getDataOnRoamingEnabled() != enabled) {
26831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            int roaming = enabled ? 1 : 0;
26841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
26851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // For single SIM phones, this is a per phone property.
26861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (TelephonyManager.getDefault().getSimCount() == 1) {
26871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Settings.Global.putInt(mResolver, Settings.Global.DATA_ROAMING, roaming);
26881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
26891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Settings.Global.putInt(mResolver, Settings.Global.DATA_ROAMING +
26901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                         phoneSubId, roaming);
26911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
26921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
26931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSubscriptionManager.setDataRoaming(roaming, phoneSubId);
26941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // will trigger handleDataOnRoamingChange() through observer
26951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
26961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu               log("setDataOnRoamingEnabled: set phoneSubId=" + phoneSubId
26971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                       + " isRoaming=" + enabled);
26981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
26991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
27001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
27011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("setDataOnRoamingEnabled: unchanged phoneSubId=" + phoneSubId
27021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        + " isRoaming=" + enabled);
27031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu             }
27041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
27051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
27061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
27071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
27081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Return current {@link android.provider.Settings.Global#DATA_ROAMING} value.
27091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
27101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public boolean getDataOnRoamingEnabled() {
27111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        boolean isDataRoamingEnabled = "true".equalsIgnoreCase(SystemProperties.get(
27121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                "ro.com.android.dataroaming", "false"));
27131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        final int phoneSubId = mPhone.getSubId();
27141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
27151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        try {
27161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // For single SIM phones, this is a per phone property.
27171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (TelephonyManager.getDefault().getSimCount() == 1) {
27181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                isDataRoamingEnabled = Settings.Global.getInt(mResolver,
27191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.DATA_ROAMING, isDataRoamingEnabled ? 1 : 0) != 0;
27201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
27211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                isDataRoamingEnabled = TelephonyManager.getIntWithSubId(mResolver,
27221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.DATA_ROAMING, phoneSubId) != 0;
27231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
27241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } catch (SettingNotFoundException snfe) {
27251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("getDataOnRoamingEnabled: SettingNofFoundException snfe=" + snfe);
27261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
27271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) {
27281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("getDataOnRoamingEnabled: phoneSubId=" + phoneSubId +
27291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " isDataRoamingEnabled=" + isDataRoamingEnabled);
27301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
27311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return isDataRoamingEnabled;
27321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
27331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
27341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRoamingOff() {
2735cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onRoamingOff");
2736c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
27376bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        if (!mUserDataEnabled) return;
2738c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2739bda761320929f714951c328bfec6a51a1978db97Wink Saville        if (getDataOnRoamingEnabled() == false) {
2740cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_OFF);
2741bda761320929f714951c328bfec6a51a1978db97Wink Saville            setupDataOnConnectableApns(Phone.REASON_ROAMING_OFF);
2742cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2743cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_ROAMING_OFF);
2744cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2745cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2746cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
27471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRoamingOn() {
27486bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        if (DBG) log("onRoamingOn");
2749bda761320929f714951c328bfec6a51a1978db97Wink Saville
27506bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        if (!mUserDataEnabled) return;
2751cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2752bda761320929f714951c328bfec6a51a1978db97Wink Saville        if (getDataOnRoamingEnabled()) {
2753cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRoamingOn: setup data on roaming");
2754ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_ROAMING_ON);
2755cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_ROAMING_ON);
2756cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2757cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRoamingOn: Tear down data connection on roaming.");
2758cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpAllConnections(true, Phone.REASON_ROAMING_ON);
2759cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
2760cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2761cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2762cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
27631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRadioAvailable() {
2764cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onRadioAvailable");
2765cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
2766cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
2767cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
2768cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // setState(DctConstants.State.CONNECTED);
2769cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(null);
2770cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2771cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("onRadioAvailable: We're on the simulator; assuming data is connected");
2772cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2773cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2774cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
2775cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (r != null && r.getRecordsLoaded()) {
2776cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(null);
2777cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2778cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2779cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getOverallState() != DctConstants.State.IDLE) {
2780cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpConnection(true, null);
2781cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2782cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2783cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
27841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRadioOffOrNotAvailable() {
2785cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Make sure our reconnect delay starts at the initial value
2786cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // next time the radio comes on
2787cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2788cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mReregisterOnReconnectFailure = false;
2789cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2790cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
2791cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
2792cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
2793cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("We're on the simulator; assuming radio off is meaningless");
2794cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2795cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRadioOffOrNotAvailable: is off and clean up all connections");
2796cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpAllConnections(false, Phone.REASON_RADIO_TURNED_OFF);
2797cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2798cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyOffApnsOfAvailability(null);
2799cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2800cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
28011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void completeConnection(ApnContext apnContext) {
2802c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2803c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (DBG) log("completeConnection: successful, notify the world apnContext=" + apnContext);
2804c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2805c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (mIsProvisioning && !TextUtils.isEmpty(mProvisioningUrl)) {
2806c9b81a0c05128694c617fcdd67e73821895822feWink Saville            if (DBG) {
2807c9b81a0c05128694c617fcdd67e73821895822feWink Saville                log("completeConnection: MOBILE_PROVISIONING_ACTION url="
2808c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        + mProvisioningUrl);
2809c9b81a0c05128694c617fcdd67e73821895822feWink Saville            }
2810c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt            Intent newIntent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN,
2811c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt                    Intent.CATEGORY_APP_BROWSER);
2812c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt            newIntent.setData(Uri.parse(mProvisioningUrl));
2813c9b81a0c05128694c617fcdd67e73821895822feWink Saville            newIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
2814c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    Intent.FLAG_ACTIVITY_NEW_TASK);
2815c9b81a0c05128694c617fcdd67e73821895822feWink Saville            try {
2816c9b81a0c05128694c617fcdd67e73821895822feWink Saville                mPhone.getContext().startActivity(newIntent);
2817c9b81a0c05128694c617fcdd67e73821895822feWink Saville            } catch (ActivityNotFoundException e) {
2818c9b81a0c05128694c617fcdd67e73821895822feWink Saville                loge("completeConnection: startActivityAsUser failed" + e);
2819c9b81a0c05128694c617fcdd67e73821895822feWink Saville            }
2820c9b81a0c05128694c617fcdd67e73821895822feWink Saville        }
2821c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mIsProvisioning = false;
2822c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mProvisioningUrl = null;
28232b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        if (mProvisioningSpinner != null) {
28242b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            sendMessage(obtainMessage(DctConstants.CMD_CLEAR_PROVISIONING_SPINNER,
28252b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner));
28262b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        }
2827c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2828c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
2829c9b81a0c05128694c617fcdd67e73821895822feWink Saville        startNetStatPoll();
2830c9b81a0c05128694c617fcdd67e73821895822feWink Saville        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
2831c9b81a0c05128694c617fcdd67e73821895822feWink Saville    }
2832c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2833ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
2834ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * A SETUP (aka bringUp) has completed, possibly with an error. If
2835ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * there is an error this method will call {@link #onDataSetupCompleteError}.
2836ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
28371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataSetupComplete(AsyncResult ar) {
2838608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt
2839ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        DcFailCause cause = DcFailCause.UNKNOWN;
2840cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean handleError = false;
2841ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDataSetupComplete");
2842cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2843ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
2844cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2845cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (ar.exception == null) {
2846454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = apnContext.getDcAc();
2847cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2848cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (RADIO_TESTS) {
2849cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Note: To change radio.test.onDSC.null.dcac from command line you need to
2850cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // adb root and adb remount and from the command line you can only change the
2851cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // value to 1 once. To change it a second time you can reboot or execute
2852cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // adb shell stop and then adb shell start. The command line to set the value is:
2853ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink 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');"
2854cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ContentResolver cr = mPhone.getContext().getContentResolver();
2855cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                String radioTestProperty = "radio.test.onDSC.null.dcac";
2856cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (Settings.System.getInt(cr, radioTestProperty, 0) == 1) {
2857cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: " + radioTestProperty +
2858cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            " is true, set dcac to null and reset property to false");
2859cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    dcac = null;
2860cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    Settings.System.putInt(cr, radioTestProperty, 0);
2861cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: " + radioTestProperty + "=" +
2862cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            Settings.System.getInt(mPhone.getContext().getContentResolver(),
2863cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                    radioTestProperty, -1));
2864cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2865c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2866cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac == null) {
2867cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("onDataSetupComplete: no connection to DC, handle as error");
2868ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                cause = DcFailCause.CONNECTION_TO_DATACONNECTIONAC_BROKEN;
2869cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                handleError = true;
2870cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
2871cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ApnSetting apn = apnContext.getApnSetting();
2872cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
2873cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: success apn=" + (apn == null ? "unknown" : apn.apn));
2874cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2875cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn != null && apn.proxy != null && apn.proxy.length() != 0) {
2876cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    try {
2877cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        String port = apn.port;
2878cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (TextUtils.isEmpty(port)) port = "8080";
28799c180aedfc9f0d20525c0128487d3500e6c0a715Jason Monk                        ProxyInfo proxy = new ProxyInfo(apn.proxy,
2880cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                Integer.parseInt(port), null);
2881cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        dcac.setLinkPropertiesHttpProxySync(proxy);
2882cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    } catch (NumberFormatException e) {
2883cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        loge("onDataSetupComplete: NumberFormatException making ProxyProperties (" +
2884cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                apn.port + "): " + e);
2885cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2886cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2887cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2888cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // everything is setup
2889cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if(TextUtils.equals(apnContext.getApnType(),PhoneConstants.APN_TYPE_DEFAULT)) {
289027b650c406018355a88a41528db7859e232728a0Jack Yu                    try {
289127b650c406018355a88a41528db7859e232728a0Jack Yu                        SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "true");
289227b650c406018355a88a41528db7859e232728a0Jack Yu                    } catch (RuntimeException ex) {
289327b650c406018355a88a41528db7859e232728a0Jack Yu                        log("Failed to set PUPPET_MASTER_RADIO_STRESS_TEST to true");
289427b650c406018355a88a41528db7859e232728a0Jack Yu                    }
289522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mCanSetPreferApn && mPreferredApn == null) {
28960e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                        if (DBG) log("onDataSetupComplete: PREFERRED APN is null");
2897cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mPreferredApn = apn;
2898cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (mPreferredApn != null) {
2899cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            setPreferredApn(mPreferredApn.id);
2900cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
2901cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2902cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
290327b650c406018355a88a41528db7859e232728a0Jack Yu                    try {
290427b650c406018355a88a41528db7859e232728a0Jack Yu                        SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
290527b650c406018355a88a41528db7859e232728a0Jack Yu                    } catch (RuntimeException ex) {
290627b650c406018355a88a41528db7859e232728a0Jack Yu                        log("Failed to set PUPPET_MASTER_RADIO_STRESS_TEST to false");
290727b650c406018355a88a41528db7859e232728a0Jack Yu                    }
2908cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2909c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2910c9b81a0c05128694c617fcdd67e73821895822feWink Saville                // A connection is setup
2911c9b81a0c05128694c617fcdd67e73821895822feWink Saville                apnContext.setState(DctConstants.State.CONNECTED);
29120e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
2913c9b81a0c05128694c617fcdd67e73821895822feWink Saville                boolean isProvApn = apnContext.isProvisioningApn();
2914b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                final ConnectivityManager cm = ConnectivityManager.from(mPhone.getContext());
2915b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                if (mProvisionBroadcastReceiver != null) {
2916b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mPhone.getContext().unregisterReceiver(mProvisionBroadcastReceiver);
2917b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mProvisionBroadcastReceiver = null;
2918b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                }
2919c9b81a0c05128694c617fcdd67e73821895822feWink Saville                if ((!isProvApn) || mIsProvisioning) {
2920b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // Hide any provisioning notification.
2921b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    cm.setProvisioningNotificationVisible(false, ConnectivityManager.TYPE_MOBILE,
2922b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                            mProvisionActionName);
2923c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // Complete the connection normally notifying the world we're connected.
2924c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // We do this if this isn't a special provisioning apn or if we've been
2925c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // told its time to provision.
2926c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    completeConnection(apnContext);
2927c9b81a0c05128694c617fcdd67e73821895822feWink Saville                } else {
2928c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // This is a provisioning APN that we're reporting as connected. Later
2929c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // when the user desires to upgrade this to a "default" connection,
2930c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // mIsProvisioning == true, we'll go through the code path above.
2931c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // mIsProvisioning becomes true when CMD_ENABLE_MOBILE_PROVISIONING
2932c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // is sent to the DCT.
2933c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    if (DBG) {
2934c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        log("onDataSetupComplete: successful, BUT send connected to prov apn as"
2935c9b81a0c05128694c617fcdd67e73821895822feWink Saville                                + " mIsProvisioning:" + mIsProvisioning + " == false"
2936c9b81a0c05128694c617fcdd67e73821895822feWink Saville                                + " && (isProvisioningApn:" + isProvApn + " == true");
2937c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    }
2938c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2939b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // While radio is up, grab provisioning URL.  The URL contains ICCID which
2940b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // disappears when radio is off.
2941b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mProvisionBroadcastReceiver = new ProvisionNotificationBroadcastReceiver(
29422b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                            cm.getMobileProvisioningUrl(),
29432b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                            TelephonyManager.getDefault().getNetworkOperatorName());
2944b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mPhone.getContext().registerReceiver(mProvisionBroadcastReceiver,
2945b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                            new IntentFilter(mProvisionActionName));
2946b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // Put up user notification that sign-in is required.
2947b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    cm.setProvisioningNotificationVisible(true, ConnectivityManager.TYPE_MOBILE,
2948b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                            mProvisionActionName);
2949b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // Turn off radio to save battery and avoid wasting carrier resources.
2950b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // The network isn't usable and network validation will just fail anyhow.
2951b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    setRadio(false);
2952c9b81a0c05128694c617fcdd67e73821895822feWink Saville                }
2953c9b81a0c05128694c617fcdd67e73821895822feWink Saville                if (DBG) {
2954c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    log("onDataSetupComplete: SETUP complete type=" + apnContext.getApnType()
2955c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        + ", reason:" + apnContext.getReason());
2956c9b81a0c05128694c617fcdd67e73821895822feWink Saville                }
2957c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2958cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2959ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            cause = (DcFailCause) (ar.result);
2960cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
2961cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ApnSetting apn = apnContext.getApnSetting();
2962cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log(String.format("onDataSetupComplete: error apn=%s cause=%s",
2963cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        (apn == null ? "unknown" : apn.apn), cause));
2964c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2965cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cause.isEventLoggable()) {
2966cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Log this failure to the Event Logs.
2967cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                int cid = getCellLocationId();
2968cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                EventLog.writeEvent(EventLogTags.PDP_SETUP_FAIL,
2969cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        cause.ordinal(), cid, TelephonyManager.getDefault().getNetworkType());
2970c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
29710742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela            ApnSetting apn = apnContext.getApnSetting();
29720742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela            mPhone.notifyPreciseDataConnectionFailed(apnContext.getReason(),
29730742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela                    apnContext.getApnType(), apn != null ? apn.apn : "unknown", cause.toString());
2974cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2975a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            //compose broadcast intent send to the specific carrier apps
2976a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            Intent intent = new Intent(TelephonyIntents.ACTION_REQUEST_NETWORK_FAILED);
2977a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            intent.putExtra(ERROR_CODE_KEY, cause.getErrorCode());
2978a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            intent.putExtra(APN_TYPE_KEY, apnContext.getApnType());
2979a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            notifyCarrierAppWithIntent(intent);
2980a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
29810e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (cause.isRestartRadioFail() || apnContext.restartOnError(cause.getErrorCode())) {
29820e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                if (DBG) log("Modem restarted.");
29830e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                sendRestartRadio();
29840e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            }
2985cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
29860e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // If the data call failure cause is a permanent failure, we mark the APN as permanent
29870e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // failed.
29880e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (isPermanentFail(cause)) {
29890e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                log("cause = " + cause + ", mark apn as permanent failed. apn = " + apn);
29900e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                apnContext.markApnPermanentFailed(apn);
2991c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
29920e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
2993cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            handleError = true;
2994cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2995cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2996cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (handleError) {
2997ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            onDataSetupCompleteError(ar);
2998ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
2999a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3000a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        /* If flag is set to false after SETUP_DATA_CALL is invoked, we need
3001a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         * to clean data connections.
3002a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         */
3003a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (!mInternalDataEnabled) {
3004a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            cleanUpAllConnections(null);
3005a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
3006a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3007ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
3008cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3009ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
3010ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt     * check for obsolete messages.  Return ApnContext if valid, null if not
3011ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt     */
3012ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt    private ApnContext getValidApnContext(AsyncResult ar, String logString) {
3013ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (ar != null && ar.userObj instanceof Pair) {
3014ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            Pair<ApnContext, Integer>pair = (Pair<ApnContext, Integer>)ar.userObj;
3015ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            ApnContext apnContext = pair.first;
3016ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            if (apnContext != null) {
30171a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                final int generation = apnContext.getConnectionGeneration();
30181a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                if (DBG) {
30191a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                    log("getValidApnContext (" + logString + ") on " + apnContext + " got " +
30201a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                            generation + " vs " + pair.second);
30211a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                }
30221a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                if (generation == pair.second) {
3023ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                    return apnContext;
3024ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                } else {
3025ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                    log("ignoring obsolete " + logString);
3026ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                    return null;
3027ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                }
3028ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            }
3029ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        }
3030ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        throw new RuntimeException(logString + ": No apnContext");
3031ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt    }
3032ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt
3033ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt    /**
3034ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Error has occurred during the SETUP {aka bringUP} request and the DCT
3035ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * should either try the next waiting APN or start over from the
3036ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * beginning if the list is empty. Between each SETUP request there will
3037ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville     * be a delay defined by {@link #getApnDelay()}.
3038ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
30391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataSetupCompleteError(AsyncResult ar) {
30400e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
3041ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDataSetupCompleteError");
3042ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3043ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
3044ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
30450e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        long delay = apnContext.getDelayForNextApn(mFailFast);
3046ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
30470e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        // Check if we need to retry or not.
30480852a954be5937a1b0bca94df0c2007d7ee3c0c7Jack Yu        if (delay >= 0) {
30490e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (DBG) log("onDataSetupCompleteError: Try next APN. delay = " + delay);
3050ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext.setState(DctConstants.State.SCANNING);
3051ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // Wait a bit before trying the next APN, so that
3052ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // we're not tying up the RIL command channel
30530e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            startAlarmForReconnect(delay, apnContext);
30540e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        } else {
30550e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // If we are not going to retry any APN, set this APN context to failed state.
30560e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // This would be the final state of a data connection.
30570e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            apnContext.setState(DctConstants.State.FAILED);
30580e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType());
30590e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            apnContext.setDataConnectionAc(null);
30600e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            log("onDataSetupCompleteError: Stop retrying APNs.");
3061c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3062c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3063c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3064c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
3065a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu     * Read Carrier App name from CarrierConfig
3066a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu     * @return String[0] Package name, String[1] Activity name
3067a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu     */
3068a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    private String[] getActivationAppName() {
3069a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        CarrierConfigManager configManager = (CarrierConfigManager) mPhone.getContext()
3070a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                .getSystemService(Context.CARRIER_CONFIG_SERVICE);
3071a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        PersistableBundle b = null;
3072a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        String[] activationApp;
3073a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
3074a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu       if (configManager != null) {
3075a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            b = configManager.getConfig();
3076a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        }
3077a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        if (b != null) {
3078a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            activationApp = b.getStringArray(CarrierConfigManager
3079a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                    .KEY_SIM_PROVISIONING_STATUS_DETECTION_CARRIER_APP_STRING_ARRAY);
3080a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        } else {
3081a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            // Return static default defined in CarrierConfigManager.
3082a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            activationApp = CarrierConfigManager.getDefaultConfig().getStringArray
3083a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                    (CarrierConfigManager
3084a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                            .KEY_SIM_PROVISIONING_STATUS_DETECTION_CARRIER_APP_STRING_ARRAY);
3085a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        }
3086a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        return activationApp;
3087a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    }
3088a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
3089a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    /**
3090a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu     * Called when EVENT_REDIRECTION_DETECTED is received.
3091a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu     */
3092a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    private void onDataConnectionRedirected(String redirectUrl) {
3093a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        if (!TextUtils.isEmpty(redirectUrl)) {
3094a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            mRedirected = true;
3095a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_REDIRECTED);
3096a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            intent.putExtra(REDIRECTION_URL_KEY, redirectUrl);
3097a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            if(notifyCarrierAppWithIntent(intent)) {
3098a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                log("Starting Activation Carrier app with redirectUrl : " + redirectUrl);
3099a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            }
3100a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        }
3101a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    }
3102a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
3103a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    /**
3104cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Called when EVENT_DISCONNECT_DONE is received.
3105c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
31061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDisconnectDone(AsyncResult ar) {
3107ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDisconnectDone");
3108ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
3109c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3110cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE apnContext=" + apnContext);
3111cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setState(DctConstants.State.IDLE);
3112cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3113cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
3114cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3115cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // if all data connection are gone, check whether Airplane mode request was
3116cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // pending.
3117cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isDisconnected()) {
3118cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPhone.getServiceStateTracker().processPendingRadioPowerOffAfterDataOff()) {
3119a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                if (DBG) log("onDisconnectDone: radio will be turned off, no retries");
3120cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Radio will be turned off. No need to retry data setup
3121cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setApnSetting(null);
3122cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setDataConnectionAc(null);
3123a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3124a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // Need to notify disconnect as well, in the case of switching Airplane mode.
3125a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // Otherwise, it would cause 30s delayed to turn on Airplane mode.
31260e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                if (mDisconnectPendingCount > 0) {
3127a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mDisconnectPendingCount--;
31280e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                }
3129a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3130a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mDisconnectPendingCount == 0) {
3131a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    notifyDataDisconnectComplete();
3132a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    notifyAllDataDisconnected();
3133a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
3134cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return;
3135cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3136c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3137cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // If APN is still enabled, try to bring it back up automatically
31383fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (mAttached.get() && apnContext.isReady() && retryAfterDisconnected(apnContext)) {
313927b650c406018355a88a41528db7859e232728a0Jack Yu            try {
314027b650c406018355a88a41528db7859e232728a0Jack Yu                SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
314127b650c406018355a88a41528db7859e232728a0Jack Yu            } catch (RuntimeException ex) {
314227b650c406018355a88a41528db7859e232728a0Jack Yu                log("Failed to set PUPPET_MASTER_RADIO_STRESS_TEST to false");
314327b650c406018355a88a41528db7859e232728a0Jack Yu            }
3144cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Wait a bit before trying the next APN, so that
3145cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // we're not tying up the RIL command channel.
3146cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // This also helps in any external dependency to turn off the context.
31470e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (DBG) log("onDisconnectDone: attached, ready and retry after disconnect");
31480e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            long delay = apnContext.getInterApnDelay(mFailFast);
31490e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (delay > 0) {
31500e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                // Data connection is in IDLE state, so when we reconnect later, we'll rebuild
31510e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                // the waiting APN list, which will also reset/reconfigure the retry manager.
31520e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                startAlarmForReconnect(delay, apnContext);
31530e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            }
3154c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
3155449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            boolean restartRadioAfterProvisioning = mPhone.getContext().getResources().getBoolean(
3156449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                    com.android.internal.R.bool.config_restartRadioAfterProvisioning);
3157449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville
3158449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            if (apnContext.isProvisioningApn() && restartRadioAfterProvisioning) {
3159449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                log("onDisconnectDone: restartRadio after provisioning");
3160449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                restartRadio();
3161449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            }
3162cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setApnSetting(null);
3163cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setDataConnectionAc(null);
31643fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())) {
3165449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                if(DBG) log("onDisconnectDone: isOnlySigneDcAllowed true so setup single apn");
31663fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                setupDataOnConnectableApns(Phone.REASON_SINGLE_PDN_ARBITRATION);
3167449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            } else {
3168449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                if(DBG) log("onDisconnectDone: not retrying");
31693fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
3170c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3171a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3172a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mDisconnectPendingCount > 0)
3173a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mDisconnectPendingCount--;
3174a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3175a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mDisconnectPendingCount == 0) {
3176c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt            apnContext.setConcurrentVoiceAndDataAllowed(
3177c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed());
3178a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyDataDisconnectComplete();
3179a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
3180a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
3181a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3182c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3183c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3184ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
3185ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Called when EVENT_DISCONNECT_DC_RETRYING is received.
3186ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
31871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDisconnectDcRetrying(AsyncResult ar) {
3188ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // We could just do this in DC!!!
3189ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDisconnectDcRetrying");
3190ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
3191ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3192ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setState(DctConstants.State.RETRYING);
3193ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if(DBG) log("onDisconnectDcRetrying: apnContext=" + apnContext);
3194ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3195ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
3196ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
3197ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
31981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onVoiceCallStarted() {
3199cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onVoiceCallStarted");
3200ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        mInVoiceCall = true;
3201cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnected() && ! mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
3202cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onVoiceCallStarted stop polling");
3203cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            stopNetStatPoll();
3204cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            stopDataStallAlarm();
3205cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
3206c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3207c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3208c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onVoiceCallEnded() {
3210cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onVoiceCallEnded");
3211ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        mInVoiceCall = false;
3212cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnected()) {
3213cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
3214cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                startNetStatPoll();
3215cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
3216cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
3217cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
3218cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // clean slate after call end.
3219cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                resetPollStats();
3220c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3221c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3222bda761320929f714951c328bfec6a51a1978db97Wink Saville        // reset reconnect timer
3223bda761320929f714951c328bfec6a51a1978db97Wink Saville        setupDataOnConnectableApns(Phone.REASON_VOICE_CALL_ENDED);
3224c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3225c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onCleanUpConnection(boolean tearDown, int apnId, String reason) {
3227cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onCleanUpConnection");
3228af5593594070f825032be46dced573cd195956e1Robert Greenwalt        ApnContext apnContext = mApnContextsById.get(apnId);
3229cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
3230cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setReason(reason);
3231cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpConnection(tearDown, apnContext);
3232c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3233c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3234c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean isConnected() {
3236cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
3237ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getState() == DctConstants.State.CONNECTED) {
3238cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // At least one context is connected, return true
3239cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return true;
3240c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3241c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3242cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // There are not any contexts connected, return false
3243cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return false;
3244c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3245c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3246cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isDisconnected() {
3247cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
3248cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!apnContext.isDisconnected()) {
3249cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // At least one context was not disconnected return false
3250cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
3251cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3252c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3253cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // All contexts were disconnected so return true
3254cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
3255c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3256c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyDataConnection(String reason) {
3258cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("notifyDataConnection: reason=" + reason);
3259cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
3260187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (mAttached.get() && apnContext.isReady()) {
3261187a39f896f88eb6c5e4306d9595546654825976Wink Saville                if (DBG) log("notifyDataConnection: type:" + apnContext.getApnType());
3262cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
3263cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.getApnType());
3264cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3265c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3266cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyOffApnsOfAvailability(reason);
3267c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3268c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void setDataProfilesAsNeeded() {
32701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("setDataProfilesAsNeeded");
32711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mAllApnSettings != null && !mAllApnSettings.isEmpty()) {
32721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            ArrayList<DataProfile> dps = new ArrayList<DataProfile>();
32731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (ApnSetting apn : mAllApnSettings) {
32741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (apn.modemCognitive) {
32751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    DataProfile dp = new DataProfile(apn,
32761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            mPhone.getServiceState().getDataRoaming());
32771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    boolean isDup = false;
32781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    for(DataProfile dpIn : dps) {
32791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (dp.equals(dpIn)) {
32801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            isDup = true;
32811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            break;
32821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        }
32831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
32841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (!isDup) {
32851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        dps.add(dp);
32861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
32871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
32881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
32891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if(dps.size() > 0) {
32901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mPhone.mCi.setDataProfile(dps.toArray(new DataProfile[0]), null);
32911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
32921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
32931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
32941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3295c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
3296cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Based on the sim operator numeric, create a list for all possible
3297cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Data Connections and setup the preferredApn.
3298c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
3299cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void createAllApnList() {
33001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mMvnoMatched = false;
3301ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mAllApnSettings = new ArrayList<ApnSetting>();
3302cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
3303cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String operator = (r != null) ? r.getOperatorNumeric() : "";
3304cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (operator != null) {
3305cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            String selection = "numeric = '" + operator + "'";
330660bc489803a3557526e1f95e34c237e70f28bc50Sungmin Choi            String orderBy = "_id";
3307cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // query only enabled apn.
3308cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // carrier_enabled : 1 means enabled apn, 0 disabled apn.
33099d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan            // selection += " and carrier_enabled = 1";
3310cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: selection=" + selection);
3311cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3312cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            Cursor cursor = mPhone.getContext().getContentResolver().query(
331360bc489803a3557526e1f95e34c237e70f28bc50Sungmin Choi                    Telephony.Carriers.CONTENT_URI, null, selection, null, orderBy);
3314cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3315cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cursor != null) {
3316cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (cursor.getCount() > 0) {
3317ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    mAllApnSettings = createApnList(cursor);
3318cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3319cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cursor.close();
3320cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3321c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3322c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
332376f43316a5a6082d601bffd4b6898d0bd81e11fcram        addEmergencyApnSetting();
332476f43316a5a6082d601bffd4b6898d0bd81e11fcram
332529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        dedupeApnSettings();
332629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
3327ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings.isEmpty()) {
3328cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: No APN found for carrier: " + operator);
3329cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPreferredApn = null;
3330ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // TODO: What is the right behavior?
3331cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            //notifyNoData(DataConnection.FailCause.MISSING_UNKNOWN_APN);
3332c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
3333cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPreferredApn = getPreferredApn();
3334cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator)) {
3335cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn = null;
3336cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                setPreferredApn(-1);
3337cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3338cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: mPreferredApn=" + mPreferredApn);
3339c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3340ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("createAllApnList: X mAllApnSettings=" + mAllApnSettings);
33419d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan
33429d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        setDataProfilesAsNeeded();
3343c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3344c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
334529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    private void dedupeApnSettings() {
334629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        ArrayList<ApnSetting> resultApns = new ArrayList<ApnSetting>();
334729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
334829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        // coalesce APNs if they are similar enough to prevent
334929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        // us from bringing up two data calls with the same interface
335029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        int i = 0;
335129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        while (i < mAllApnSettings.size() - 1) {
335229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            ApnSetting first = mAllApnSettings.get(i);
335329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            ApnSetting second = null;
335429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            int j = i + 1;
335529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            while (j < mAllApnSettings.size()) {
335629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                second = mAllApnSettings.get(j);
335729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                if (apnsSimilar(first, second)) {
335829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    ApnSetting newApn = mergeApns(first, second);
335929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    mAllApnSettings.set(i, newApn);
336029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    first = newApn;
336129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    mAllApnSettings.remove(j);
336229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                } else {
336329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    j++;
336429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                }
336529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            }
336629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            i++;
336729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        }
336829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    }
336929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
3370d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe    //check whether the types of two APN same (even only one type of each APN is same)
3371d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe    private boolean apnTypeSameAny(ApnSetting first, ApnSetting second) {
3372d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe        if(VDBG) {
3373d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            StringBuilder apnType1 = new StringBuilder(first.apn + ": ");
3374d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            for(int index1 = 0; index1 < first.types.length; index1++) {
3375d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                apnType1.append(first.types[index1]);
3376d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                apnType1.append(",");
3377d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            }
3378d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe
3379d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            StringBuilder apnType2 = new StringBuilder(second.apn + ": ");
3380d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            for(int index1 = 0; index1 < second.types.length; index1++) {
3381d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                apnType2.append(second.types[index1]);
3382d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                apnType2.append(",");
3383d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            }
3384d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            log("APN1: is " + apnType1);
3385d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            log("APN2: is " + apnType2);
3386d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe        }
3387d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe
3388d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe        for(int index1 = 0; index1 < first.types.length; index1++) {
3389d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            for(int index2 = 0; index2 < second.types.length; index2++) {
3390d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                if(first.types[index1].equals(PhoneConstants.APN_TYPE_ALL) ||
3391d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                        second.types[index2].equals(PhoneConstants.APN_TYPE_ALL) ||
3392d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                        first.types[index1].equals(second.types[index2])) {
3393d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                    if(VDBG)log("apnTypeSameAny: return true");
3394d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                    return true;
3395d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                }
3396d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            }
3397d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe        }
3398d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe
3399d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe        if(VDBG)log("apnTypeSameAny: return false");
3400d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe        return false;
3401d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe    }
3402d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe
340329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    // Check if neither mention DUN and are substantially similar
340429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    private boolean apnsSimilar(ApnSetting first, ApnSetting second) {
340529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        return (first.canHandleType(PhoneConstants.APN_TYPE_DUN) == false &&
340629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                second.canHandleType(PhoneConstants.APN_TYPE_DUN) == false &&
340729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                Objects.equals(first.apn, second.apn) &&
3408d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                !apnTypeSameAny(first, second) &&
340961cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                xorEquals(first.proxy, second.proxy) &&
341061cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                xorEquals(first.port, second.port) &&
341129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                first.carrierEnabled == second.carrierEnabled &&
3412aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                first.bearerBitmask == second.bearerBitmask &&
341329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                first.profileId == second.profileId &&
341429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                Objects.equals(first.mvnoType, second.mvnoType) &&
341529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                Objects.equals(first.mvnoMatchData, second.mvnoMatchData) &&
341629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                xorEquals(first.mmsc, second.mmsc) &&
341729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                xorEquals(first.mmsProxy, second.mmsProxy) &&
341829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                xorEquals(first.mmsPort, second.mmsPort));
341929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    }
342029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
342129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    // equal or one is not specified
342229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    private boolean xorEquals(String first, String second) {
342329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        return (Objects.equals(first, second) ||
342429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                TextUtils.isEmpty(first) ||
342529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                TextUtils.isEmpty(second));
342629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    }
342729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
342829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    private ApnSetting mergeApns(ApnSetting dest, ApnSetting src) {
3429bca51fc3a191d3ca30df627b75374db0941571c5Sungmin Choi        int id = dest.id;
343029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        ArrayList<String> resultTypes = new ArrayList<String>();
343129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        resultTypes.addAll(Arrays.asList(dest.types));
343229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        for (String srcType : src.types) {
343329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            if (resultTypes.contains(srcType) == false) resultTypes.add(srcType);
3434bca51fc3a191d3ca30df627b75374db0941571c5Sungmin Choi            if (srcType.equals(PhoneConstants.APN_TYPE_DEFAULT)) id = src.id;
343529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        }
343629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        String mmsc = (TextUtils.isEmpty(dest.mmsc) ? src.mmsc : dest.mmsc);
343729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        String mmsProxy = (TextUtils.isEmpty(dest.mmsProxy) ? src.mmsProxy : dest.mmsProxy);
343829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        String mmsPort = (TextUtils.isEmpty(dest.mmsPort) ? src.mmsPort : dest.mmsPort);
343961cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String proxy = (TextUtils.isEmpty(dest.proxy) ? src.proxy : dest.proxy);
344061cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String port = (TextUtils.isEmpty(dest.port) ? src.port : dest.port);
344161cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String protocol = src.protocol.equals("IPV4V6") ? src.protocol : dest.protocol;
344261cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String roamingProtocol = src.roamingProtocol.equals("IPV4V6") ? src.roamingProtocol :
344361cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                dest.roamingProtocol;
3444aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan        int bearerBitmask = (dest.bearerBitmask == 0 || src.bearerBitmask == 0) ?
3445aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                0 : (dest.bearerBitmask | src.bearerBitmask);
344629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
3447bca51fc3a191d3ca30df627b75374db0941571c5Sungmin Choi        return new ApnSetting(id, dest.numeric, dest.carrier, dest.apn,
344861cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                proxy, port, mmsc, mmsProxy, mmsPort, dest.user, dest.password,
344961cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                dest.authType, resultTypes.toArray(new String[0]), protocol,
3450aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                roamingProtocol, dest.carrierEnabled, 0, bearerBitmask, dest.profileId,
345129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                (dest.modemCognitive || src.modemCognitive), dest.maxConns, dest.waitTime,
345229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                dest.maxConnsTime, dest.mtu, dest.mvnoType, dest.mvnoMatchData);
345329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    }
345429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
3455ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /** Return the DC AsyncChannel for the new data connection */
3456454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel createDataConnection() {
3457cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createDataConnection E");
3458cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3459cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int id = mUniqueIdGenerator.getAndIncrement();
3460ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        DataConnection conn = DataConnection.makeDataConnection(mPhone, id,
3461ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                                this, mDcTesterFailBringUpAll, mDcc);
3462cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mDataConnections.put(id, conn);
3463454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac = new DcAsyncChannel(conn, LOG_TAG);
3464cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int status = dcac.fullyConnectSync(mPhone.getContext(), this, conn.getHandler());
3465cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (status == AsyncChannel.STATUS_SUCCESSFUL) {
3466ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            mDataConnectionAcHashMap.put(dcac.getDataConnectionIdSync(), dcac);
3467c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
3468ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            loge("createDataConnection: Could not connect to dcac=" + dcac + " status=" + status);
3469c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3470cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3471cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createDataConnection() X id=" + id + " dc=" + conn);
3472ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        return dcac;
3473c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3474c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3475cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void destroyDataConnections() {
3476cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(mDataConnections != null) {
3477cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("destroyDataConnections: clear mDataConnectionList");
3478cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mDataConnections.clear();
3479cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
3480cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("destroyDataConnections: mDataConnecitonList is empty, ignore");
3481c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3482c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3483c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3484c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
3485cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Build a list of APNs to be used to create PDP's.
3486c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
3487cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param requestedApnType
3488cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return waitingApns list to be used to create PDP
3489cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *          error when waitingApns.isEmpty()
3490c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
3491203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    private ArrayList<ApnSetting> buildWaitingApns(String requestedApnType, int radioTech) {
3492cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("buildWaitingApns: E requestedApnType=" + requestedApnType);
3493cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ArrayList<ApnSetting> apnList = new ArrayList<ApnSetting>();
3494cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3495cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (requestedApnType.equals(PhoneConstants.APN_TYPE_DUN)) {
3496cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ApnSetting dun = fetchDunApn();
3497cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dun != null) {
3498cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnList.add(dun);
3499cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: X added APN_TYPE_DUN apnList=" + apnList);
3500cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return apnList;
3501c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3502c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3503c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3504cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
3505cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String operator = (r != null) ? r.getOperatorNumeric() : "";
3506c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3507cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // This is a workaround for a bug (7305641) where we don't failover to other
3508cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // suitable APNs if our preferred APN fails.  On prepaid ATT sims we need to
3509cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // failover to a provisioning APN, but once we've used their default data
3510cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // connection we are locked to it for life.  This change allows ATT devices
3511cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // to say they don't want to use preferred at all.
3512cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean usePreferred = true;
3513cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        try {
3514cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            usePreferred = ! mPhone.getContext().getResources().getBoolean(com.android.
3515cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    internal.R.bool.config_dontPreferApn);
3516cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } catch (Resources.NotFoundException e) {
3517cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("buildWaitingApns: usePreferred NotFoundException set to true");
3518cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            usePreferred = true;
3519cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3520bf660a4647db8151609cdfa0ecc4c96e1518947fSungmin Choi        if (usePreferred) {
3521bf660a4647db8151609cdfa0ecc4c96e1518947fSungmin Choi            mPreferredApn = getPreferredApn();
3522bf660a4647db8151609cdfa0ecc4c96e1518947fSungmin Choi        }
3523cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
3524cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("buildWaitingApns: usePreferred=" + usePreferred
352522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    + " canSetPreferApn=" + mCanSetPreferApn
3526cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " mPreferredApn=" + mPreferredApn
3527cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " operator=" + operator + " radioTech=" + radioTech
3528cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " IccRecords r=" + r);
3529cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3530c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
353122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (usePreferred && mCanSetPreferApn && mPreferredApn != null &&
3532cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn.canHandleType(requestedApnType)) {
3533cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
3534cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("buildWaitingApns: Preferred APN:" + operator + ":"
3535cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        + mPreferredApn.numeric + ":" + mPreferredApn);
3536cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3537cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPreferredApn.numeric.equals(operator)) {
3538aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                if (ServiceState.bitmaskHasTech(mPreferredApn.bearerBitmask, radioTech)) {
3539cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnList.add(mPreferredApn);
3540cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
3541cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return apnList;
3542cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
3543cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("buildWaitingApns: no preferred APN");
3544cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    setPreferredApn(-1);
3545cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mPreferredApn = null;
3546c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
3547cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
3548cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: no preferred APN");
3549cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                setPreferredApn(-1);
3550cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn = null;
3551c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3552c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3553ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings != null) {
3554ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (DBG) log("buildWaitingApns: mAllApnSettings=" + mAllApnSettings);
3555ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for (ApnSetting apn : mAllApnSettings) {
3556cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn.canHandleType(requestedApnType)) {
3557aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                    if (ServiceState.bitmaskHasTech(apn.bearerBitmask, radioTech)) {
35589232dafa7ea833fc0b3a6024d6c7e23fc8e961eaRobert Greenwalt                        if (DBG) log("buildWaitingApns: adding apn=" + apn);
3559cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnList.add(apn);
3560c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else {
3561cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (DBG) {
3562aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                            log("buildWaitingApns: bearerBitmask:" + apn.bearerBitmask + " does " +
3563aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                                    "not include radioTech:" + radioTech);
3564cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
3565c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
35669232dafa7ea833fc0b3a6024d6c7e23fc8e961eaRobert Greenwalt                } else if (DBG) {
356727b650c406018355a88a41528db7859e232728a0Jack Yu                    log("buildWaitingApns: couldn't handle requested ApnType="
3568cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            + requestedApnType);
3569c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
3570c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3571cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
35724bd0ae43eb0cb9969dee4f30cddc18a71da68190Jack Yu            loge("mAllApnSettings is null!");
3573c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
35740e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        if (DBG) log("buildWaitingApns: " + apnList.size() + " APNs in the list: " + apnList);
3575cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return apnList;
3576c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3577c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3578cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private String apnListToString (ArrayList<ApnSetting> apns) {
3579cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        StringBuilder result = new StringBuilder();
3580cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (int i = 0, size = apns.size(); i < size; i++) {
3581cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result.append('[')
3582cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                  .append(apns.get(i).toString())
3583cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                  .append(']');
3584c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3585cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result.toString();
3586c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3587c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3588cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void setPreferredApn(int pos) {
358922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (!mCanSetPreferApn) {
3590cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("setPreferredApn: X !canSEtPreferApn");
3591cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
3592cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3593cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
35946bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        String subId = Long.toString(mPhone.getSubId());
35956bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        Uri uri = Uri.withAppendedPath(PREFERAPN_NO_UPDATE_URI_USING_SUBID, subId);
3596cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("setPreferredApn: delete");
3597cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ContentResolver resolver = mPhone.getContext().getContentResolver();
35986bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        resolver.delete(uri, null, null);
3599cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3600cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (pos >= 0) {
3601cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("setPreferredApn: insert");
3602cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ContentValues values = new ContentValues();
3603cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            values.put(APN_ID, pos);
36046bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville            resolver.insert(uri, values);
3605cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3606cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
3607cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3608cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ApnSetting getPreferredApn() {
36094bd0ae43eb0cb9969dee4f30cddc18a71da68190Jack Yu        if (mAllApnSettings == null || mAllApnSettings.isEmpty()) {
36104bd0ae43eb0cb9969dee4f30cddc18a71da68190Jack Yu            log("getPreferredApn: mAllApnSettings is " + ((mAllApnSettings == null)?"null":"empty"));
3611cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return null;
3612cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3613cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
36146bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        String subId = Long.toString(mPhone.getSubId());
36156bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        Uri uri = Uri.withAppendedPath(PREFERAPN_NO_UPDATE_URI_USING_SUBID, subId);
3616cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Cursor cursor = mPhone.getContext().getContentResolver().query(
36176bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville                uri, new String[] { "_id", "name", "apn" },
3618cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
3619cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3620cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor != null) {
362122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCanSetPreferApn = true;
3622cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
362322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCanSetPreferApn = false;
3624cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3625cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("getPreferredApn: mRequestedApnType=" + mRequestedApnType + " cursor=" + cursor
3626cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                + " cursor.count=" + ((cursor != null) ? cursor.getCount() : 0));
3627cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
362822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mCanSetPreferApn && cursor.getCount() > 0) {
3629cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            int pos;
3630cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cursor.moveToFirst();
3631cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            pos = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID));
3632ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for(ApnSetting p : mAllApnSettings) {
3633cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("getPreferredApn: apnSetting=" + p);
3634cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (p.id == pos && p.canHandleType(mRequestedApnType)) {
3635cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("getPreferredApn: X found apnSetting" + p);
3636cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    cursor.close();
3637cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return p;
3638cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3639cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
3640cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3641cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3642cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor != null) {
3643cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cursor.close();
3644cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3645cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3646cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("getPreferredApn: X not found");
3647cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
3648cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
3649cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3650cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
3651cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void handleMessage (Message msg) {
36521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) log("handleMessage msg=" + msg);
3653cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3654cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        switch (msg.what) {
3655cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_RECORDS_LOADED:
36561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // If onRecordsLoadedOrSubIdChanged() is not called here, it should be called on
36571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // onSubscriptionsChanged() when a valid subId is available.
36581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                int subId = mPhone.getSubId();
36591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (SubscriptionManager.isValidSubscriptionId(subId)) {
36601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onRecordsLoadedOrSubIdChanged();
36611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
36621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("Ignoring EVENT_RECORDS_LOADED as subId is not valid: " + subId);
36631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
3664cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3665cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3666cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_CONNECTION_DETACHED:
3667cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onDataConnectionDetached();
3668cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3669cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3670cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_CONNECTION_ATTACHED:
3671bda761320929f714951c328bfec6a51a1978db97Wink Saville                onDataConnectionAttached();
3672cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3673cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3674cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DO_RECOVERY:
3675cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                doRecovery();
3676cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3677cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3678cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_APN_CHANGED:
3679cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onApnChanged();
3680cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3681cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3682cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_PS_RESTRICT_ENABLED:
3683cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                /**
3684cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * We don't need to explicitly to tear down the PDP context
3685cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * when PS restricted is enabled. The base band will deactive
3686cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * PDP context and notify us with PDP_CONTEXT_CHANGED.
3687cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * But we should stop the network polling and prevent reset PDP.
3688cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 */
3689cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
3690cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                stopNetStatPoll();
3691cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                stopDataStallAlarm();
3692cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsPsRestricted = true;
3693cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
3694cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3695cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_PS_RESTRICT_DISABLED:
3696cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                /**
3697cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * When PS restrict is removed, we need setup PDP connection if
3698cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * PDP connection is down.
3699cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 */
3700cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_PS_RESTRICT_DISABLED " + mIsPsRestricted);
3701cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsPsRestricted  = false;
3702cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (isConnected()) {
3703cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    startNetStatPoll();
3704cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
3705cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
3706cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // TODO: Should all PDN states be checked to fail?
3707ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    if (mState == DctConstants.State.FAILED) {
3708cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        cleanUpAllConnections(false, Phone.REASON_PS_RESTRICT_ENABLED);
3709cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mReregisterOnReconnectFailure = false;
3710cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
3711af5593594070f825032be46dced573cd195956e1Robert Greenwalt                    ApnContext apnContext = mApnContextsById.get(DctConstants.APN_DEFAULT_ID);
37123fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (apnContext != null) {
37133fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        apnContext.setReason(Phone.REASON_PS_RESTRICT_ENABLED);
37143fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        trySetupData(apnContext);
37153fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    } else {
37163fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        loge("**** Default ApnContext not found ****");
37173fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        if (Build.IS_DEBUGGABLE) {
37183fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                            throw new RuntimeException("Default ApnContext not found");
37193fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        }
37203fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    }
3721cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3722cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
3723ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3724cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_TRY_SETUP_DATA:
3725cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (msg.obj instanceof ApnContext) {
3726cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    onTrySetupData((ApnContext)msg.obj);
3727cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else if (msg.obj instanceof String) {
3728cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    onTrySetupData((String)msg.obj);
3729cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
3730cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    loge("EVENT_TRY_SETUP request w/o apnContext or String");
3731cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3732cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
3733cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3734cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_CLEAN_UP_CONNECTION:
3735cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                boolean tearDown = (msg.arg1 == 0) ? false : true;
3736cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_CLEAN_UP_CONNECTION tearDown=" + tearDown);
3737cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (msg.obj instanceof ApnContext) {
3738cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    cleanUpConnection(tearDown, (ApnContext)msg.obj);
3739cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
37401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onCleanUpConnection(tearDown, msg.arg2, (String) msg.obj);
3741cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3742cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
37431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE: {
37441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
3745a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                onSetInternalDataEnabled(enabled, (Message) msg.obj);
3746a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
37471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
3748a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS:
37491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if ((msg.obj != null) && (msg.obj instanceof String == false)) {
37501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    msg.obj = null;
3751a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
37521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onCleanUpAllConnections((String) msg.obj);
3753a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
3754ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3755220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville            case DctConstants.EVENT_DATA_RAT_CHANGED:
3756220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville                //May new Network allow setupData, so try it here
3757c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                setupDataOnConnectableApns(Phone.REASON_NW_TYPE_CHANGED,
3758c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                        RetryFailures.ONLY_ON_CHANGE);
3759220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville                break;
3760220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville
37612b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            case DctConstants.CMD_CLEAR_PROVISIONING_SPINNER:
37622b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                // Check message sender intended to clear the current spinner.
37632b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                if (mProvisioningSpinner == msg.obj) {
37642b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner.dismiss();
37652b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner = null;
37662b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                }
37672b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                break;
37681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
37691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("DISCONNECTED_CONNECTED: msg=" + msg);
37701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DcAsyncChannel dcac = (DcAsyncChannel) msg.obj;
37711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mDataConnectionAcHashMap.remove(dcac.getDataConnectionIdSync());
37721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                dcac.disconnected();
37731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
37751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ENABLE_NEW_APN:
37761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onEnableApn(msg.arg1, msg.arg2);
37771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_STALL_ALARM:
37801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDataStallAlarm(msg.arg1);
37811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ROAMING_OFF:
37841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onRoamingOff();
37851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
37871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ROAMING_ON:
37881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onRoamingOn();
37891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3791f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt            case DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE:
3792f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                onDeviceProvisionedChange();
3793f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt                break;
3794f299322eabb18e1234c81fe1e356b550b6687772Robert Greenwalt
3795a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            case DctConstants.EVENT_REDIRECTION_DETECTED:
3796a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                log("dataConnectionTracker.handleMessage: EVENT_REDIRECTION_DETECTED=" + msg);
3797a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                onDataConnectionRedirected((String) msg.obj);
3798a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
37991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RADIO_AVAILABLE:
38001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onRadioAvailable();
38011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
38031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
38041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onRadioOffOrNotAvailable();
38051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
38071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_SETUP_COMPLETE:
38081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDataSetupComplete((AsyncResult) msg.obj);
38091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
38111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_SETUP_COMPLETE_ERROR:
38121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDataSetupCompleteError((AsyncResult) msg.obj);
38131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
3814a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
38151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DISCONNECT_DONE:
38161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("DataConnectionTracker.handleMessage: EVENT_DISCONNECT_DONE msg=" + msg);
38171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDisconnectDone((AsyncResult) msg.obj);
38181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
38201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DISCONNECT_DC_RETRYING:
38211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("DataConnectionTracker.handleMessage: EVENT_DISCONNECT_DC_RETRYING msg=" + msg);
38221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDisconnectDcRetrying((AsyncResult) msg.obj);
38231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
38251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_VOICE_CALL_STARTED:
38261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onVoiceCallStarted();
38271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
38291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_VOICE_CALL_ENDED:
38301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onVoiceCallEnded();
38311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
38331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RESET_DONE: {
38341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("EVENT_RESET_DONE");
38351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onResetDone((AsyncResult) msg.obj);
38361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
38381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_USER_DATA_ENABLE: {
38391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
38401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_SET_USER_DATA_ENABLE enabled=" + enabled);
38411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onSetUserDataEnabled(enabled);
38421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
38441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // TODO - remove
38451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_DEPENDENCY_MET: {
38461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                boolean met = (msg.arg1 == DctConstants.ENABLED) ? true : false;
38471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_SET_DEPENDENCY_MET met=" + met);
38481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Bundle bundle = msg.getData();
38491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (bundle != null) {
38501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    String apnType = (String)bundle.get(DctConstants.APN_TYPE_KEY);
38511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (apnType != null) {
38521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onSetDependencyMet(apnType, met);
38531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
38541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
38571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_POLICY_DATA_ENABLE: {
38581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
38591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onSetPolicyDataEnabled(enabled);
38601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
38621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: {
38631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                sEnableFailFastRefCounter += (msg.arg1 == DctConstants.ENABLED) ? 1 : -1;
38641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
38651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: "
38661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + " sEnableFailFastRefCounter=" + sEnableFailFastRefCounter);
38671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (sEnableFailFastRefCounter < 0) {
38691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    final String s = "CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: "
38701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + "sEnableFailFastRefCounter:" + sEnableFailFastRefCounter + " < 0";
38711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge(s);
38721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    sEnableFailFastRefCounter = 0;
38731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = sEnableFailFastRefCounter > 0;
38751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
38761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: enabled=" + enabled
38771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + " sEnableFailFastRefCounter=" + sEnableFailFastRefCounter);
38781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (mFailFast != enabled) {
38801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mFailFast = enabled;
38810e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
38821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mDataStallDetectionEnabled = !enabled;
38831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mDataStallDetectionEnabled
38841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            && (getOverallState() == DctConstants.State.CONNECTED)
38851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            && (!mInVoiceCall ||
38861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    mPhone.getServiceStateTracker()
38871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                        .isConcurrentVoiceAndDataAllowed())) {
38881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: start data stall");
38891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        stopDataStallAlarm();
38901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
38911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
38921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: stop data stall");
38931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        stopDataStallAlarm();
38941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
38951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
38962b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen
38971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
38981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
38991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_ENABLE_MOBILE_PROVISIONING: {
39001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Bundle bundle = msg.getData();
39011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (bundle != null) {
39021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    try {
39031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mProvisioningUrl = (String)bundle.get(DctConstants.PROVISIONING_URL_KEY);
39041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } catch(ClassCastException e) {
39051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioning url not a string" + e);
39061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mProvisioningUrl = null;
39071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
39081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
39091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (TextUtils.isEmpty(mProvisioningUrl)) {
39101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioning url is empty, ignoring");
39111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mIsProvisioning = false;
39121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mProvisioningUrl = null;
39131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
39141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioningUrl=" + mProvisioningUrl);
39151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mIsProvisioning = true;
39161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    startProvisioningApnAlarm();
39171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
39181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_PROVISIONING_APN_ALARM: {
39211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("EVENT_PROVISIONING_APN_ALARM");
3922af5593594070f825032be46dced573cd195956e1Robert Greenwalt                ApnContext apnCtx = mApnContextsById.get(DctConstants.APN_DEFAULT_ID);
39231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (apnCtx.isProvisioningApn() && apnCtx.isConnectedOrConnecting()) {
39241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mProvisioningApnAlarmTag == msg.arg1) {
39251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) log("EVENT_PROVISIONING_APN_ALARM: Disconnecting");
39261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mIsProvisioning = false;
39271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mProvisioningUrl = null;
39281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        stopProvisioningApnAlarm();
39291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        sendCleanUpConnection(true, apnCtx);
39301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
39311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) {
39321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            log("EVENT_PROVISIONING_APN_ALARM: ignore stale tag,"
39331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    + " mProvisioningApnAlarmTag:" + mProvisioningApnAlarmTag
39341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    + " != arg1:" + msg.arg1);
39351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        }
39361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
39371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
39381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (DBG) log("EVENT_PROVISIONING_APN_ALARM: Not connected ignore");
39391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
39401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_IS_PROVISIONING_APN: {
39431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_IS_PROVISIONING_APN");
39441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                boolean isProvApn;
39451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                try {
39461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    String apnType = null;
39471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    Bundle bundle = msg.getData();
39481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (bundle != null) {
39491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        apnType = (String)bundle.get(DctConstants.APN_TYPE_KEY);
39501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
39511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (TextUtils.isEmpty(apnType)) {
39521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        loge("CMD_IS_PROVISIONING_APN: apnType is empty");
39531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        isProvApn = false;
39541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
39551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        isProvApn = isProvisioningApn(apnType);
39561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
39571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } catch (ClassCastException e) {
39581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge("CMD_IS_PROVISIONING_APN: NO provisioning url ignoring");
39591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    isProvApn = false;
39601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
39611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_IS_PROVISIONING_APN: ret=" + isProvApn);
39621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mReplyAc.replyToMessage(msg, DctConstants.CMD_IS_PROVISIONING_APN,
39631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        isProvApn ? DctConstants.ENABLED : DctConstants.DISABLED);
39641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ICC_CHANGED: {
39671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onUpdateIcc();
39681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RESTART_RADIO: {
39711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartRadio();
39721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_NET_STAT_POLL: {
39751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (msg.arg1 == DctConstants.ENABLED) {
39761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    handleStartNetStatPoll((DctConstants.Activity)msg.obj);
39771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else if (msg.arg1 == DctConstants.DISABLED) {
39781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    handleStopNetStatPoll((DctConstants.Activity)msg.obj);
39791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
39801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_STATE_CHANGED: {
39831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // no longer do anything, but still registered - clean up log
39841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // TODO - why are we still registering?
39851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
39861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
3987cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            default:
39881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Rlog.e("DcTracker", "Unhandled event=" + msg);
3989cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
39901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3991cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3992cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
3993cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
39941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int getApnProfileID(String apnType) {
3995cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IMS)) {
3996cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_IMS;
3997cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_FOTA)) {
3998cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_FOTA;
3999cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_CBS)) {
4000cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_CBS;
40011b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IA)) {
40021b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            return RILConstants.DATA_PROFILE_DEFAULT; // DEFAULT for now
400345df26444864daad60afdd4d121ab4043da3834bSungmin Choi        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_DUN)) {
400445df26444864daad60afdd4d121ab4043da3834bSungmin Choi            return RILConstants.DATA_PROFILE_TETHERED;
4005cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
4006cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_DEFAULT;
4007cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
4008cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
4009cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4010cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private int getCellLocationId() {
4011cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int cid = -1;
4012cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        CellLocation loc = mPhone.getCellLocation();
4013cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4014cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (loc != null) {
4015cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (loc instanceof GsmCellLocation) {
4016cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cid = ((GsmCellLocation)loc).getCid();
4017cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else if (loc instanceof CdmaCellLocation) {
4018cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cid = ((CdmaCellLocation)loc).getBaseStationId();
4019cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
4020cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
4021cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return cid;
4022cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
4023cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4024a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private IccRecords getUiccRecords(int appFamily) {
4025a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return mUiccController.getIccRecords(mPhone.getPhoneId(), appFamily);
4026a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4027a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4028a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
40291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onUpdateIcc() {
4030cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mUiccController == null ) {
4031cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            return;
4032cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
4033cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4034a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        IccRecords newIccRecords = getUiccRecords(UiccController.APP_FAM_3GPP);
4035cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4036cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
4037cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (r != newIccRecords) {
4038cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (r != null) {
4039cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("Removing stale icc objects.");
4040cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                r.unregisterForRecordsLoaded(this);
4041cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIccRecords.set(null);
40429aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan            }
4043cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (newIccRecords != null) {
40441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (SubscriptionManager.isValidSubscriptionId(mPhone.getSubId())) {
4045aa863054476b152fe9323defd197fa946a47033fSungmin Choi                    log("New records found.");
4046aa863054476b152fe9323defd197fa946a47033fSungmin Choi                    mIccRecords.set(newIccRecords);
4047aa863054476b152fe9323defd197fa946a47033fSungmin Choi                    newIccRecords.registerForRecordsLoaded(
4048aa863054476b152fe9323defd197fa946a47033fSungmin Choi                            this, DctConstants.EVENT_RECORDS_LOADED, null);
4049a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                    SubscriptionController.getInstance().setSimProvisioningStatus(
4050a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                            SubscriptionManager.SIM_PROVISIONED, mPhone.getSubId());
4051aa863054476b152fe9323defd197fa946a47033fSungmin Choi                }
40520469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal            } else {
40530469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal                onSimNotReady();
40549aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan            }
40559aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan        }
4056cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
4057cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4058a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void update() {
4059a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("update sub = " + mPhone.getSubId());
4060bda761320929f714951c328bfec6a51a1978db97Wink Saville        log("update(): Active DDS, register for all events now!");
4061bda761320929f714951c328bfec6a51a1978db97Wink Saville        onUpdateIcc();
4062a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
40632bb2331aa5c5285f70a7404d61ee71ede4831056Shishir Agrawal        mUserDataEnabled = getDataEnabled();
40640979b71e48405cab10bdf1d1b4170cfce72838a7Jack Yu        mAutoAttachOnCreation.set(false);
4065bda761320929f714951c328bfec6a51a1978db97Wink Saville
40661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ((GsmCdmaPhone)mPhone).updateCurrentCarrierInProvider();
4067a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4068a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4069a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void cleanUpAllConnections(String cause) {
4070a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cleanUpAllConnections(cause, null);
4071a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4072a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4073a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void updateRecords() {
4074bda761320929f714951c328bfec6a51a1978db97Wink Saville        onUpdateIcc();
4075a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4076a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4077a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void cleanUpAllConnections(String cause, Message disconnectAllCompleteMsg) {
4078a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("cleanUpAllConnections");
4079a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (disconnectAllCompleteMsg != null) {
4080a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mDisconnectAllCompleteMsgList.add(disconnectAllCompleteMsg);
4081a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4082a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4083a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Message msg = obtainMessage(DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS);
4084a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        msg.obj = cause;
4085a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sendMessage(msg);
4086a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4087a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4088a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    private boolean notifyCarrierAppWithIntent(Intent intent) {
4089a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        //read from carrier config manager
4090a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        String[] activationApp = getActivationAppName();
4091a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        if(activationApp == null || activationApp.length != 2) {
4092a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            return false;
4093a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        }
4094a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
4095a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        intent.setClassName(activationApp[0], activationApp[1]);
4096a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, mPhone.getSubId());
4097a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        //check if Activation App is available */
4098a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        final PackageManager packageManager = mPhone.getContext().getPackageManager();
4099a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        if (packageManager.queryBroadcastReceivers(intent,
4100a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
4101a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            loge("Activation Carrier app is configured, but not available: "
4102a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                    + activationApp[0] + "." + activationApp[1]);
4103a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            return false;
4104a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        }
4105a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
4106a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        try {
4107a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            mPhone.getContext().sendBroadcast(intent);
4108a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        } catch (ActivityNotFoundException e) {
4109a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            loge("sendBroadcast failed: " + e);
4110a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu            return false;
4111a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        }
4112a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
4113a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        if (DBG) log("send Intent to : " + activationApp[0] + "." + activationApp[1]
4114a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu                + " with action: " + intent.getAction());
4115a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu        return true;
4116a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu    }
4117a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
41181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyDataDisconnectComplete() {
4119a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("notifyDataDisconnectComplete");
4120a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        for (Message m: mDisconnectAllCompleteMsgList) {
4121a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            m.sendToTarget();
4122a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4123a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mDisconnectAllCompleteMsgList.clear();
4124a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4125a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4126a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
41271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyAllDataDisconnected() {
4128a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sEnableFailFastRefCounter = 0;
4129a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mFailFast = false;
4130a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.notifyRegistrants();
4131a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4132a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4133a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void registerForAllDataDisconnected(Handler h, int what, Object obj) {
4134a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.addUnique(h, what, obj);
4135a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4136a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (isDisconnected()) {
4137a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("notify All Data Disconnected");
4138a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
4139a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4140a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4141a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4142a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void unregisterForAllDataDisconnected(Handler h) {
4143a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.remove(h);
4144a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4145a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4146a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
41471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetInternalDataEnabled(boolean enabled, Message onCompleteMsg) {
41486bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        if (DBG) log("onSetInternalDataEnabled: enabled=" + enabled);
4149a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean sendOnComplete = true;
4150a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4151a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        synchronized (mDataEnabledLock) {
4152a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mInternalDataEnabled = enabled;
4153a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (enabled) {
4154a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("onSetInternalDataEnabled: changed to enabled, try to setup data call");
4155a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                onTrySetupData(Phone.REASON_DATA_ENABLED);
4156a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
4157a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                sendOnComplete = false;
4158a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("onSetInternalDataEnabled: changed to disabled, cleanUpAllConnections");
4159a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                cleanUpAllConnections(null, onCompleteMsg);
4160a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
4161a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4162a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4163a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (sendOnComplete) {
4164a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (onCompleteMsg != null) {
4165a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                onCompleteMsg.sendToTarget();
4166a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
4167a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4168a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4169a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4170a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean setInternalDataEnabledFlag(boolean enable) {
41716bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        if (DBG) log("setInternalDataEnabledFlag(" + enable + ")");
4172a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4173a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mInternalDataEnabled != enable) {
4174a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mInternalDataEnabled = enable;
4175a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4176a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return true;
4177a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4178a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4179a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean setInternalDataEnabled(boolean enable) {
4180a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return setInternalDataEnabled(enable, null);
4181a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4182a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4183a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean setInternalDataEnabled(boolean enable, Message onCompleteMsg) {
41846bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        if (DBG) log("setInternalDataEnabled(" + enable + ")");
4185a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4186a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Message msg = obtainMessage(DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE, onCompleteMsg);
4187a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        msg.arg1 = (enable ? DctConstants.ENABLED : DctConstants.DISABLED);
4188a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sendMessage(msg);
4189a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return true;
4190a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4191a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4192a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void setDataAllowed(boolean enable, Message response) {
41936bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville         if (DBG) log("setDataAllowed: enable=" + enable);
41941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu         isCleanupRequired.set(!enable);
4195a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         mPhone.mCi.setDataAllowed(enable, response);
4196a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         mInternalDataEnabled = enable;
4197a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4198a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
41991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void log(String s) {
4200a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Rlog.d(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s);
4201cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
4202cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
42031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void loge(String s) {
4204a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Rlog.e(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s);
4205cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
4206cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
4207c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
42081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println("DcTracker:");
42091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" RADIO_TESTS=" + RADIO_TESTS);
42101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mInternalDataEnabled=" + mInternalDataEnabled);
42111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mUserDataEnabled=" + mUserDataEnabled);
42121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" sPolicyDataEnabed=" + sPolicyDataEnabled);
42131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
42141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mRequestedApnType=" + mRequestedApnType);
42151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mPhone=" + mPhone.getPhoneName());
42161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mActivity=" + mActivity);
42171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mState=" + mState);
42181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mTxPkts=" + mTxPkts);
42191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mRxPkts=" + mRxPkts);
42201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mNetStatPollPeriod=" + mNetStatPollPeriod);
42211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mNetStatPollEnabled=" + mNetStatPollEnabled);
42221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mDataStallTxRxSum=" + mDataStallTxRxSum);
42231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mDataStallAlarmTag=" + mDataStallAlarmTag);
42241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mDataStallDetectionEanbled=" + mDataStallDetectionEnabled);
42251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mSentSinceLastRecv=" + mSentSinceLastRecv);
42261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mNoRecvPollCount=" + mNoRecvPollCount);
42271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mResolver=" + mResolver);
42281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsWifiConnected=" + mIsWifiConnected);
42291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mReconnectIntent=" + mReconnectIntent);
42301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mAutoAttachOnCreation=" + mAutoAttachOnCreation.get());
42311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsScreenOn=" + mIsScreenOn);
42321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mUniqueIdGenerator=" + mUniqueIdGenerator);
42331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
42341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
42351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        DcController dcc = mDcc;
42361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (dcc != null) {
42371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            dcc.dump(fd, pw, args);
42381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
42391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mDcc=null");
42401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
42411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
42421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        HashMap<Integer, DataConnection> dcs = mDataConnections;
42431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (dcs != null) {
42441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Set<Entry<Integer, DataConnection> > mDcSet = mDataConnections.entrySet();
42451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mDataConnections: count=" + mDcSet.size());
42461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (Entry<Integer, DataConnection> entry : mDcSet) {
42471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                pw.printf(" *** mDataConnection[%d] \n", entry.getKey());
42481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                entry.getValue().dump(fd, pw, args);
42491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
42501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
42511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println("mDataConnections=null");
42521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
42531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
42541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
42551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        HashMap<String, Integer> apnToDcId = mApnToDataConnectionId;
42561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (apnToDcId != null) {
42571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Set<Entry<String, Integer>> apnToDcIdSet = apnToDcId.entrySet();
42581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mApnToDataConnectonId size=" + apnToDcIdSet.size());
42591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (Entry<String, Integer> entry : apnToDcIdSet) {
42601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                pw.printf(" mApnToDataConnectonId[%s]=%d\n", entry.getKey(), entry.getValue());
42611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
42621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
42631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println("mApnToDataConnectionId=null");
42641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
42651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
42661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
42671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ConcurrentHashMap<String, ApnContext> apnCtxs = mApnContexts;
42681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (apnCtxs != null) {
42691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Set<Entry<String, ApnContext>> apnCtxsSet = apnCtxs.entrySet();
42701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mApnContexts size=" + apnCtxsSet.size());
42711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (Entry<String, ApnContext> entry : apnCtxsSet) {
42721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                entry.getValue().dump(fd, pw, args);
42731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
42741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" ***************************************");
42751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
42761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mApnContexts=null");
42771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
42781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
42791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ArrayList<ApnSetting> apnSettings = mAllApnSettings;
42801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (apnSettings != null) {
42811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mAllApnSettings size=" + apnSettings.size());
42821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (int i=0; i < apnSettings.size(); i++) {
42831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                pw.printf(" mAllApnSettings[%d]: %s\n", i, apnSettings.get(i));
42841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
42851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.flush();
42861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
42871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mAllApnSettings=null");
42881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
42891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mPreferredApn=" + mPreferredApn);
42901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsPsRestricted=" + mIsPsRestricted);
42911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsDisposed=" + mIsDisposed);
42921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIntentReceiver=" + mIntentReceiver);
4293cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mReregisterOnReconnectFailure=" + mReregisterOnReconnectFailure);
429422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" canSetPreferApn=" + mCanSetPreferApn);
4295cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mApnObserver=" + mApnObserver);
4296cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" getOverallState=" + getOverallState());
4297ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        pw.println(" mDataConnectionAsyncChannels=%s\n" + mDataConnectionAcHashMap);
4298187a39f896f88eb6c5e4306d9595546654825976Wink Saville        pw.println(" mAttached=" + mAttached.get());
42991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
4300c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
4301a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4302bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram    public String[] getPcscfAddress(String apnType) {
4303a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("getPcscfAddress()");
4304bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        ApnContext apnContext = null;
4305bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram
4306bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        if(apnType == null){
4307bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            log("apnType is null, return null");
4308bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            return null;
4309bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        }
4310a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4311bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_EMERGENCY)) {
4312af5593594070f825032be46dced573cd195956e1Robert Greenwalt            apnContext = mApnContextsById.get(DctConstants.APN_EMERGENCY_ID);
4313bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IMS)) {
4314af5593594070f825032be46dced573cd195956e1Robert Greenwalt            apnContext = mApnContextsById.get(DctConstants.APN_IMS_ID);
4315bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        } else {
4316bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            log("apnType is invalid, return null");
4317bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            return null;
4318bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        }
4319a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4320a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (apnContext == null) {
4321a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("apnContext is null, return null");
4322a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return null;
4323a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4324a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4325a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        DcAsyncChannel dcac = apnContext.getDcAc();
4326a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        String[] result = null;
4327a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4328a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (dcac != null) {
4329a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            result = dcac.getPcscfAddr();
4330a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4331a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            for (int i = 0; i < result.length; i++) {
4332a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("Pcscf[" + i + "]: " + result[i]);
4333a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
4334a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return result;
4335a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4336a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return null;
4337a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4338a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
433976f43316a5a6082d601bffd4b6898d0bd81e11fcram    /**
434076f43316a5a6082d601bffd4b6898d0bd81e11fcram     * Read APN configuration from Telephony.db for Emergency APN
434176f43316a5a6082d601bffd4b6898d0bd81e11fcram     * All opertors recognize the connection request for EPDN based on APN type
434276f43316a5a6082d601bffd4b6898d0bd81e11fcram     * PLMN name,APN name are not mandatory parameters
434376f43316a5a6082d601bffd4b6898d0bd81e11fcram     */
434476f43316a5a6082d601bffd4b6898d0bd81e11fcram    private void initEmergencyApnSetting() {
434576f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Operator Numeric is not available when sim records are not loaded.
434676f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Query Telephony.db with APN type as EPDN request does not
434776f43316a5a6082d601bffd4b6898d0bd81e11fcram        // require APN name, plmn and all operators support same APN config.
434876f43316a5a6082d601bffd4b6898d0bd81e11fcram        // DB will contain only one entry for Emergency APN
434976f43316a5a6082d601bffd4b6898d0bd81e11fcram        String selection = "type=\"emergency\"";
435076f43316a5a6082d601bffd4b6898d0bd81e11fcram        Cursor cursor = mPhone.getContext().getContentResolver().query(
435176f43316a5a6082d601bffd4b6898d0bd81e11fcram                Telephony.Carriers.CONTENT_URI, null, selection, null, null);
435276f43316a5a6082d601bffd4b6898d0bd81e11fcram
435376f43316a5a6082d601bffd4b6898d0bd81e11fcram        if (cursor != null) {
435476f43316a5a6082d601bffd4b6898d0bd81e11fcram            if (cursor.getCount() > 0) {
435576f43316a5a6082d601bffd4b6898d0bd81e11fcram                if (cursor.moveToFirst()) {
435676f43316a5a6082d601bffd4b6898d0bd81e11fcram                    mEmergencyApn = makeApnSetting(cursor);
435776f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
435876f43316a5a6082d601bffd4b6898d0bd81e11fcram            }
435976f43316a5a6082d601bffd4b6898d0bd81e11fcram            cursor.close();
436076f43316a5a6082d601bffd4b6898d0bd81e11fcram        }
436176f43316a5a6082d601bffd4b6898d0bd81e11fcram    }
436276f43316a5a6082d601bffd4b6898d0bd81e11fcram
436376f43316a5a6082d601bffd4b6898d0bd81e11fcram    /**
436476f43316a5a6082d601bffd4b6898d0bd81e11fcram     * Add the Emergency APN settings to APN settings list
436576f43316a5a6082d601bffd4b6898d0bd81e11fcram     */
436676f43316a5a6082d601bffd4b6898d0bd81e11fcram    private void addEmergencyApnSetting() {
436776f43316a5a6082d601bffd4b6898d0bd81e11fcram        if(mEmergencyApn != null) {
436876f43316a5a6082d601bffd4b6898d0bd81e11fcram            if(mAllApnSettings == null) {
436976f43316a5a6082d601bffd4b6898d0bd81e11fcram                mAllApnSettings = new ArrayList<ApnSetting>();
437076f43316a5a6082d601bffd4b6898d0bd81e11fcram            } else {
437176f43316a5a6082d601bffd4b6898d0bd81e11fcram                boolean hasEmergencyApn = false;
437276f43316a5a6082d601bffd4b6898d0bd81e11fcram                for (ApnSetting apn : mAllApnSettings) {
437376f43316a5a6082d601bffd4b6898d0bd81e11fcram                    if (ArrayUtils.contains(apn.types, PhoneConstants.APN_TYPE_EMERGENCY)) {
437476f43316a5a6082d601bffd4b6898d0bd81e11fcram                        hasEmergencyApn = true;
437576f43316a5a6082d601bffd4b6898d0bd81e11fcram                        break;
437676f43316a5a6082d601bffd4b6898d0bd81e11fcram                    }
437776f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
437876f43316a5a6082d601bffd4b6898d0bd81e11fcram
437976f43316a5a6082d601bffd4b6898d0bd81e11fcram                if(hasEmergencyApn == false) {
438076f43316a5a6082d601bffd4b6898d0bd81e11fcram                    mAllApnSettings.add(mEmergencyApn);
438176f43316a5a6082d601bffd4b6898d0bd81e11fcram                } else {
438276f43316a5a6082d601bffd4b6898d0bd81e11fcram                    log("addEmergencyApnSetting - E-APN setting is already present");
438376f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
438476f43316a5a6082d601bffd4b6898d0bd81e11fcram            }
438576f43316a5a6082d601bffd4b6898d0bd81e11fcram        }
438676f43316a5a6082d601bffd4b6898d0bd81e11fcram    }
43879a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
43889a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang    private void cleanUpConnectionsOnUpdatedApns(boolean tearDown) {
43899a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (DBG) log("cleanUpConnectionsOnUpdatedApns: tearDown=" + tearDown);
43909a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (mAllApnSettings.isEmpty()) {
43919a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            cleanUpAllConnections(tearDown, Phone.REASON_APN_CHANGED);
43929a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        } else {
43939a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            for (ApnContext apnContext : mApnContexts.values()) {
43949a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                if (VDBG) log("cleanUpConnectionsOnUpdatedApns for "+ apnContext);
43959a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
43969a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                boolean cleanUpApn = true;
43979a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                ArrayList<ApnSetting> currentWaitingApns = apnContext.getWaitingApns();
43989a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
43999a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                if ((currentWaitingApns != null) && (!apnContext.isDisconnected())) {
44009a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
44019a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    ArrayList<ApnSetting> waitingApns = buildWaitingApns(
44029a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                            apnContext.getApnType(), radioTech);
44039a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    if (VDBG) log("new waitingApns:" + waitingApns);
44049a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    if (waitingApns.size() == currentWaitingApns.size()) {
44059a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                        cleanUpApn = false;
44069a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                        for (int i = 0; i < waitingApns.size(); i++) {
44079a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                            if (!currentWaitingApns.get(i).equals(waitingApns.get(i))) {
44089a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                                if (VDBG) log("new waiting apn is different at " + i);
44099a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                                cleanUpApn = true;
44109a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                                apnContext.setWaitingApns(waitingApns);
44119a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                                break;
44129a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                            }
44139a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                        }
44149a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    }
44159a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                }
44169a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
44179a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                if (cleanUpApn) {
44189a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    apnContext.setReason(Phone.REASON_APN_CHANGED);
44199a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    cleanUpConnection(true, apnContext);
44209a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                }
44219a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            }
44229a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        }
44239a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
44249a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (!isConnected()) {
44259a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            stopNetStatPoll();
44269a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            stopDataStallAlarm();
44279a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        }
44289a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
44299a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
44309a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
44319a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (DBG) log("mDisconnectPendingCount = " + mDisconnectPendingCount);
44329a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (tearDown && mDisconnectPendingCount == 0) {
44339a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            notifyDataDisconnectComplete();
44349a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            notifyAllDataDisconnected();
44359a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        }
44369a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang    }
44371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
44391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Polling stuff
44401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
44411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void resetPollStats() {
44421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mTxPkts = -1;
44431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mRxPkts = -1;
44441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mNetStatPollPeriod = POLL_NETSTAT_MILLIS;
44451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void startNetStatPoll() {
44481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (getOverallState() == DctConstants.State.CONNECTED
44491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                && mNetStatPollEnabled == false) {
44501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
44511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("startNetStatPoll");
44521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
44531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            resetPollStats();
44541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mNetStatPollEnabled = true;
44551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPollNetStat.run();
44561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mPhone != null) {
44581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPhone.notifyDataActivity();
44591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void stopNetStatPoll() {
44631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mNetStatPollEnabled = false;
44641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        removeCallbacks(mPollNetStat);
44651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
44661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("stopNetStatPoll");
44671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // To sync data activity icon in the case of switching data connection to send MMS.
44701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mPhone != null) {
44711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPhone.notifyDataActivity();
44721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void sendStartNetStatPoll(DctConstants.Activity activity) {
44761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.CMD_NET_STAT_POLL);
44771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = DctConstants.ENABLED;
44781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.obj = activity;
44791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
44801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void handleStartNetStatPoll(DctConstants.Activity activity) {
44831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startNetStatPoll();
44841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
44851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        setActivity(activity);
44861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void sendStopNetStatPoll(DctConstants.Activity activity) {
44891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.CMD_NET_STAT_POLL);
44901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = DctConstants.DISABLED;
44911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.obj = activity;
44921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
44931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void handleStopNetStatPoll(DctConstants.Activity activity) {
44961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        stopNetStatPoll();
44971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        stopDataStallAlarm();
44981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        setActivity(activity);
44991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void updateDataActivity() {
45021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        long sent, received;
45031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        DctConstants.Activity newActivity;
45051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        TxRxSum preTxRxSum = new TxRxSum(mTxPkts, mRxPkts);
45071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        TxRxSum curTxRxSum = new TxRxSum();
45081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        curTxRxSum.updateTxRxSum();
45091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mTxPkts = curTxRxSum.txPkts;
45101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mRxPkts = curTxRxSum.rxPkts;
45111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) {
45131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("updateDataActivity: curTxRxSum=" + curTxRxSum + " preTxRxSum=" + preTxRxSum);
45141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
45151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mNetStatPollEnabled && (preTxRxSum.txPkts > 0 || preTxRxSum.rxPkts > 0)) {
45171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            sent = mTxPkts - preTxRxSum.txPkts;
45181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            received = mRxPkts - preTxRxSum.rxPkts;
45191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG)
45211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("updateDataActivity: sent=" + sent + " received=" + received);
45221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (sent > 0 && received > 0) {
45231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = DctConstants.Activity.DATAINANDOUT;
45241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (sent > 0 && received == 0) {
45251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = DctConstants.Activity.DATAOUT;
45261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (sent == 0 && received > 0) {
45271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = DctConstants.Activity.DATAIN;
45281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
45291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = (mActivity == DctConstants.Activity.DORMANT) ?
45301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mActivity : DctConstants.Activity.NONE;
45311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
45321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mActivity != newActivity && mIsScreenOn) {
45341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (VDBG)
45351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("updateDataActivity: newActivity=" + newActivity);
45361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mActivity = newActivity;
45371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mPhone.notifyDataActivity();
45381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
45391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
45401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
45431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Data-Stall
45441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
45451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Recovery action taken in case of data stall
45461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static class RecoveryAction {
45471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int GET_DATA_CALL_LIST      = 0;
45481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int CLEANUP                 = 1;
45491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int REREGISTER              = 2;
45501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int RADIO_RESTART           = 3;
45511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int RADIO_RESTART_WITH_PROP = 4;
45521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        private static boolean isAggressiveRecovery(int value) {
45541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return ((value == RecoveryAction.CLEANUP) ||
45551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    (value == RecoveryAction.REREGISTER) ||
45561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    (value == RecoveryAction.RADIO_RESTART) ||
45571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    (value == RecoveryAction.RADIO_RESTART_WITH_PROP));
45581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
45591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int getRecoveryAction() {
45621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int action = Settings.System.getInt(mResolver,
45631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                "radio.data.stall.recovery.action", RecoveryAction.GET_DATA_CALL_LIST);
45641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("getRecoveryAction: " + action);
45651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return action;
45661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void putRecoveryAction(int action) {
45691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Settings.System.putInt(mResolver, "radio.data.stall.recovery.action", action);
45701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("putRecoveryAction: " + action);
45711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void doRecovery() {
45741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (getOverallState() == DctConstants.State.CONNECTED) {
45751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Go through a series of recovery steps, each action transitions to the next action
45761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            int recoveryAction = getRecoveryAction();
45771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            switch (recoveryAction) {
45781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case RecoveryAction.GET_DATA_CALL_LIST:
45791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_GET_DATA_CALL_LIST,
45801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mSentSinceLastRecv);
45811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("doRecovery() get data call list");
45821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mPhone.mCi.getDataCallList(obtainMessage(DctConstants.EVENT_DATA_STATE_CHANGED));
45831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                putRecoveryAction(RecoveryAction.CLEANUP);
45841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
45851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case RecoveryAction.CLEANUP:
45861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_CLEANUP, mSentSinceLastRecv);
45871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("doRecovery() cleanup all connections");
45881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                cleanUpAllConnections(Phone.REASON_PDP_RESET);
45891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                putRecoveryAction(RecoveryAction.REREGISTER);
45901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
45911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case RecoveryAction.REREGISTER:
45921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_REREGISTER,
45931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mSentSinceLastRecv);
45941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("doRecovery() re-register");
45951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mPhone.getServiceStateTracker().reRegisterNetwork(null);
45961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                putRecoveryAction(RecoveryAction.RADIO_RESTART);
45971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
45981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case RecoveryAction.RADIO_RESTART:
45991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART,
46001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mSentSinceLastRecv);
46011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("restarting radio");
46021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                putRecoveryAction(RecoveryAction.RADIO_RESTART_WITH_PROP);
46031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartRadio();
46041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
46051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case RecoveryAction.RADIO_RESTART_WITH_PROP:
46061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // This is in case radio restart has not recovered the data.
46071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // It will set an additional "gsm.radioreset" property to tell
46081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // RIL or system to take further action.
46091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // The implementation of hard reset recovery action is up to OEM product.
46101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // Once RADIO_RESET property is consumed, it is expected to set back
46111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // to false by RIL.
46121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART_WITH_PROP, -1);
46131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("restarting radio with gsm.radioreset to true");
46141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                SystemProperties.set(RADIO_RESET_PROPERTY, "true");
46151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // give 1 sec so property change can be notified.
46161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                try {
46171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    Thread.sleep(1000);
46181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } catch (InterruptedException e) {}
46191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartRadio();
46201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
46211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
46221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            default:
46231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                throw new RuntimeException("doRecovery: Invalid recoveryAction=" +
46241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    recoveryAction);
46251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSentSinceLastRecv = 0;
46271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
46291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void updateDataStallInfo() {
46311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        long sent, received;
46321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        TxRxSum preTxRxSum = new TxRxSum(mDataStallTxRxSum);
46341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDataStallTxRxSum.updateTxRxSum();
46351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) {
46371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("updateDataStallInfo: mDataStallTxRxSum=" + mDataStallTxRxSum +
46381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " preTxRxSum=" + preTxRxSum);
46391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sent = mDataStallTxRxSum.txPkts - preTxRxSum.txPkts;
46421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        received = mDataStallTxRxSum.rxPkts - preTxRxSum.rxPkts;
46431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (RADIO_TESTS) {
46451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (SystemProperties.getBoolean("radio.test.data.stall", false)) {
46461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("updateDataStallInfo: radio.test.data.stall true received = 0;");
46471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                received = 0;
46481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if ( sent > 0 && received > 0 ) {
46511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) log("updateDataStallInfo: IN/OUT");
46521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSentSinceLastRecv = 0;
46531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
46541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (sent > 0 && received == 0) {
46551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mPhone.getState() == PhoneConstants.State.IDLE) {
46561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mSentSinceLastRecv += sent;
46571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
46581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mSentSinceLastRecv = 0;
46591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
46611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("updateDataStallInfo: OUT sent=" + sent +
46621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        " mSentSinceLastRecv=" + mSentSinceLastRecv);
46631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (sent == 0 && received > 0) {
46651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) log("updateDataStallInfo: IN");
46661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSentSinceLastRecv = 0;
46671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
46681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
46691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) log("updateDataStallInfo: NONE");
46701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
46721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataStallAlarm(int tag) {
46741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mDataStallAlarmTag != tag) {
46751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
46761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("onDataStallAlarm: ignore, tag=" + tag + " expecting " + mDataStallAlarmTag);
46771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return;
46791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        updateDataStallInfo();
46811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int hangWatchdogTrigger = Settings.Global.getInt(mResolver,
46831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Settings.Global.PDP_WATCHDOG_TRIGGER_PACKET_COUNT,
46841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                NUMBER_SENT_PACKETS_OF_HANG);
46851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
46861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        boolean suspectedStall = DATA_STALL_NOT_SUSPECTED;
46871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mSentSinceLastRecv >= hangWatchdogTrigger) {
46881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
46891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("onDataStallAlarm: tag=" + tag + " do recovery action=" + getRecoveryAction());
46901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            suspectedStall = DATA_STALL_SUSPECTED;
46921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            sendMessage(obtainMessage(DctConstants.EVENT_DO_RECOVERY));
46931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
46941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) {
46951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("onDataStallAlarm: tag=" + tag + " Sent " + String.valueOf(mSentSinceLastRecv) +
46961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " pkts since last received, < watchdogTrigger=" + hangWatchdogTrigger);
46971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
46981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
46991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startDataStallAlarm(suspectedStall);
47001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void startDataStallAlarm(boolean suspectedStall) {
47031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int nextAction = getRecoveryAction();
47041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int delayInMs;
47051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mDataStallDetectionEnabled && getOverallState() == DctConstants.State.CONNECTED) {
47071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // If screen is on or data stall is currently suspected, set the alarm
47080e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // with an aggressive timeout.
47091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mIsScreenOn || suspectedStall || RecoveryAction.isAggressiveRecovery(nextAction)) {
47101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                delayInMs = Settings.Global.getInt(mResolver,
47111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS,
47121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
47131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
47141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                delayInMs = Settings.Global.getInt(mResolver,
47151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS,
47161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
47171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mDataStallAlarmTag += 1;
47201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) {
47211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("startDataStallAlarm: tag=" + mDataStallAlarmTag +
47221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        " delay=" + (delayInMs / 1000) + "s");
47231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Intent intent = new Intent(INTENT_DATA_STALL_ALARM);
47251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            intent.putExtra(DATA_STALL_ALARM_TAG_EXTRA, mDataStallAlarmTag);
47261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mDataStallAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
47271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    PendingIntent.FLAG_UPDATE_CURRENT);
47281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
47291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    SystemClock.elapsedRealtime() + delayInMs, mDataStallAlarmIntent);
47301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
47311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) {
47321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("startDataStallAlarm: NOT started, no connection tag=" + mDataStallAlarmTag);
47331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void stopDataStallAlarm() {
47381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) {
47391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("stopDataStallAlarm: current tag=" + mDataStallAlarmTag +
47401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " mDataStallAlarmIntent=" + mDataStallAlarmIntent);
47411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDataStallAlarmTag += 1;
47431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mDataStallAlarmIntent != null) {
47441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mAlarmManager.cancel(mDataStallAlarmIntent);
47451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mDataStallAlarmIntent = null;
47461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void restartDataStallAlarm() {
47501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (isConnected() == false) return;
47511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // To be called on screen status change.
47521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // Do not cancel the alarm if it is set with aggressive timeout.
47531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int nextAction = getRecoveryAction();
47541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (RecoveryAction.isAggressiveRecovery(nextAction)) {
47561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("restartDataStallAlarm: action is pending. not resetting the alarm.");
47571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return;
47581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("restartDataStallAlarm: stop then start.");
47601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        stopDataStallAlarm();
47611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
47621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
47651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Provisioning APN
47661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
47671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onActionIntentProvisioningApnAlarm(Intent intent) {
47681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("onActionIntentProvisioningApnAlarm: action=" + intent.getAction());
47691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_PROVISIONING_APN_ALARM,
47701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                intent.getAction());
47711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = intent.getIntExtra(PROVISIONING_APN_ALARM_TAG_EXTRA, 0);
47721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
47731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
47741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
47751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void startProvisioningApnAlarm() {
47761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int delayInMs = Settings.Global.getInt(mResolver,
47771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                Settings.Global.PROVISIONING_APN_ALARM_DELAY_IN_MS,
47781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                PROVISIONING_APN_ALARM_DELAY_IN_MS_DEFAULT);
47791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (Build.IS_DEBUGGABLE) {
47801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Allow debug code to use a system property to provide another value
47811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            String delayInMsStrg = Integer.toString(delayInMs);
47821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            delayInMsStrg = System.getProperty(DEBUG_PROV_APN_ALARM, delayInMsStrg);
47831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            try {
47841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                delayInMs = Integer.parseInt(delayInMsStrg);
47851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } catch (NumberFormatException e) {
47861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                loge("startProvisioningApnAlarm: e=" + e);
47871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
47881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisioningApnAlarmTag += 1;
47901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
47911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("startProvisioningApnAlarm: tag=" + mProvisioningApnAlarmTag +
47921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " delay=" + (delayInMs / 1000) + "s");
47931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
47941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Intent intent = new Intent(INTENT_PROVISIONING_APN_ALARM);
47951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        intent.putExtra(PROVISIONING_APN_ALARM_TAG_EXTRA, mProvisioningApnAlarmTag);
47961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisioningApnAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
47971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                PendingIntent.FLAG_UPDATE_CURRENT);
47981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
47991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                SystemClock.elapsedRealtime() + delayInMs, mProvisioningApnAlarmIntent);
48001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
48011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
48021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void stopProvisioningApnAlarm() {
48031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
48041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("stopProvisioningApnAlarm: current tag=" + mProvisioningApnAlarmTag +
48051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " mProvsioningApnAlarmIntent=" + mProvisioningApnAlarmIntent);
48061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
48071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisioningApnAlarmTag += 1;
48081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mProvisioningApnAlarmIntent != null) {
48091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mAlarmManager.cancel(mProvisioningApnAlarmIntent);
48101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mProvisioningApnAlarmIntent = null;
48111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
48121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
48131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4814c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville}
4815